diff --git a/bsp/gd32350r-eval/.config b/bsp/gd32350r-eval/.config
new file mode 100644
index 0000000000000000000000000000000000000000..cba7e2b0bdc45d72b9ef8a045d31f8ded2efe669
--- /dev/null
+++ b/bsp/gd32350r-eval/.config
@@ -0,0 +1,555 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=8
+# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
+# CONFIG_RT_USING_SMP is not set
+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_USING_OVERFLOW_CHECK=y
+CONFIG_RT_USING_HOOK=y
+CONFIG_RT_USING_IDLE_HOOK=y
+CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
+CONFIG_IDLE_THREAD_STACK_SIZE=256
+CONFIG_RT_USING_TIMER_SOFT=y
+CONFIG_RT_TIMER_THREAD_PRIO=4
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=512
+
+#
+# kservice optimization
+#
+# CONFIG_RT_KSERVICE_USING_STDLIB is not set
+# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
+CONFIG_RT_DEBUG=y
+# CONFIG_RT_DEBUG_COLOR is not set
+# CONFIG_RT_DEBUG_INIT_CONFIG is not set
+# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
+# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
+# CONFIG_RT_DEBUG_IPC_CONFIG is not set
+# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
+# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
+# CONFIG_RT_DEBUG_MEM_CONFIG is not set
+# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
+# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
+# CONFIG_RT_DEBUG_MODULE_CONFIG 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_USERHEAP 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_DEVICE_OPS is not set
+# CONFIG_RT_USING_INTERRUPT_INFO is not set
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart"
+CONFIG_RT_VER_NUM=0x40004
+# CONFIG_RT_USING_CPU_FFS is not set
+# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD 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
+CONFIG_RT_MAIN_THREAD_PRIORITY=10
+
+#
+# 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
+CONFIG_FINSH_ARG_MAX=10
+
+#
+# Device virtual file system
+#
+# CONFIG_RT_USING_DFS is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_PIPE_BUFSZ=512
+# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
+CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_USING_SERIAL_V1=y
+# CONFIG_RT_USING_SERIAL_V2 is not set
+CONFIG_RT_SERIAL_USING_DMA=y
+CONFIG_RT_SERIAL_RB_BUFSZ=64
+# 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 is not set
+# CONFIG_RT_USING_PHY is not set
+CONFIG_RT_USING_PIN=y
+# CONFIG_RT_USING_ADC is not set
+# CONFIG_RT_USING_DAC is not set
+# CONFIG_RT_USING_PWM is not set
+# CONFIG_RT_USING_MTD_NOR is not set
+# CONFIG_RT_USING_MTD_NAND is not set
+# CONFIG_RT_USING_PM is not set
+# CONFIG_RT_USING_RTC is not set
+# CONFIG_RT_USING_SDIO is not set
+# CONFIG_RT_USING_SPI is not set
+# CONFIG_RT_USING_WDT is not set
+# CONFIG_RT_USING_AUDIO is not set
+# CONFIG_RT_USING_SENSOR is not set
+# CONFIG_RT_USING_TOUCH is not set
+# CONFIG_RT_USING_HWCRYPTO is not set
+# CONFIG_RT_USING_PULSE_ENCODER is not set
+# CONFIG_RT_USING_INPUT_CAPTURE 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 is not set
+# CONFIG_RT_USING_PTHREADS is not set
+# CONFIG_RT_LIBC_USING_TIME is not set
+
+#
+# Network
+#
+
+#
+# Socket abstraction layer
+#
+# CONFIG_RT_USING_SAL is not set
+
+#
+# Network interface device
+#
+# CONFIG_RT_USING_NETDEV is not set
+
+#
+# light weight TCP/IP stack
+#
+# CONFIG_RT_USING_LWIP is not set
+
+#
+# AT commands
+#
+# CONFIG_RT_USING_AT is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_RYM is not set
+# CONFIG_RT_USING_ULOG is not set
+# CONFIG_RT_USING_UTEST is not set
+# CONFIG_RT_USING_RT_LINK is not set
+
+#
+# RT-Thread Utestcases
+#
+# CONFIG_RT_USING_UTESTCASES is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_UMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_WEBNET is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_MYMQTT is not set
+# CONFIG_PKG_USING_KAWAII_MQTT is not set
+# CONFIG_PKG_USING_BC28_MQTT is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_JSMN is not set
+# CONFIG_PKG_USING_LIBMODBUS is not set
+# CONFIG_PKG_USING_FREEMODBUS is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_NANOPB 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_RW007 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_CMUX is not set
+# CONFIG_PKG_USING_PPP_DEVICE is not set
+# CONFIG_PKG_USING_AT_DEVICE is not set
+# CONFIG_PKG_USING_ATSRV_SOCKET is not set
+# CONFIG_PKG_USING_WIZNET is not set
+
+#
+# IoT Cloud
+#
+# CONFIG_PKG_USING_ONENET is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+# CONFIG_PKG_USING_ALI_IOTKIT is not set
+# CONFIG_PKG_USING_AZURE is not set
+# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
+# CONFIG_PKG_USING_JIOT-C-SDK is not set
+# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
+# CONFIG_PKG_USING_JOYLINK is not set
+# CONFIG_PKG_USING_NIMBLE is not set
+# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
+# CONFIG_PKG_USING_IPMSG is not set
+# CONFIG_PKG_USING_LSSDP is not set
+# CONFIG_PKG_USING_AIRKISS_OPEN is not set
+# CONFIG_PKG_USING_LIBRWS is not set
+# CONFIG_PKG_USING_TCPSERVER is not set
+# CONFIG_PKG_USING_PROTOBUF_C is not set
+# CONFIG_PKG_USING_DLT645 is not set
+# CONFIG_PKG_USING_QXWZ is not set
+# CONFIG_PKG_USING_SMTP_CLIENT is not set
+# CONFIG_PKG_USING_ABUP_FOTA is not set
+# CONFIG_PKG_USING_LIBCURL2RTT is not set
+# CONFIG_PKG_USING_CAPNP is not set
+# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
+# CONFIG_PKG_USING_AGILE_TELNET is not set
+# CONFIG_PKG_USING_NMEALIB is not set
+# CONFIG_PKG_USING_AGILE_JSMN is not set
+# CONFIG_PKG_USING_PDULIB is not set
+# CONFIG_PKG_USING_BTSTACK is not set
+# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
+# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
+# CONFIG_PKG_USING_MAVLINK is not set
+# CONFIG_PKG_USING_RAPIDJSON is not set
+# CONFIG_PKG_USING_BSAL is not set
+# CONFIG_PKG_USING_AGILE_MODBUS is not set
+# CONFIG_PKG_USING_AGILE_FTP is not set
+# CONFIG_PKG_USING_EMBEDDEDPROTO 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
+# CONFIG_PKG_USING_TFM is not set
+# CONFIG_PKG_USING_YD_CRYPTO is not set
+
+#
+# language packages
+#
+# CONFIG_PKG_USING_LUA is not set
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# CONFIG_PKG_USING_OPENMV is not set
+# CONFIG_PKG_USING_MUPDF is not set
+# CONFIG_PKG_USING_STEMWIN is not set
+# CONFIG_PKG_USING_WAVPLAYER is not set
+# CONFIG_PKG_USING_TJPGD is not set
+# CONFIG_PKG_USING_PDFGEN is not set
+# CONFIG_PKG_USING_HELIX is not set
+# CONFIG_PKG_USING_AZUREGUIX is not set
+# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
+# CONFIG_PKG_USING_NUEMWIN is not set
+# CONFIG_PKG_USING_MP3PLAYER is not set
+# CONFIG_PKG_USING_TINYJPEG 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_SEGGER_RTT is not set
+# CONFIG_PKG_USING_RDB is not set
+# CONFIG_PKG_USING_QRCODE is not set
+# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ULOG_FILE is not set
+# CONFIG_PKG_USING_LOGMGR is not set
+# CONFIG_PKG_USING_ADBD is not set
+# CONFIG_PKG_USING_COREMARK is not set
+# CONFIG_PKG_USING_DHRYSTONE is not set
+# CONFIG_PKG_USING_MEMORYPERF is not set
+# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
+# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
+# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
+# CONFIG_PKG_USING_BS8116A is not set
+# CONFIG_PKG_USING_GPS_RMC is not set
+# CONFIG_PKG_USING_URLENCODE is not set
+# CONFIG_PKG_USING_UMCN is not set
+# CONFIG_PKG_USING_LWRB2RTT is not set
+# CONFIG_PKG_USING_CPU_USAGE is not set
+# CONFIG_PKG_USING_GBK2UTF8 is not set
+# CONFIG_PKG_USING_VCONSOLE is not set
+# CONFIG_PKG_USING_KDB is not set
+# CONFIG_PKG_USING_WAMR is not set
+# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
+# CONFIG_PKG_USING_LWLOG is not set
+# CONFIG_PKG_USING_ANV_TRACE is not set
+# CONFIG_PKG_USING_ANV_MEMLEAK is not set
+# CONFIG_PKG_USING_ANV_TESTSUIT is not set
+# CONFIG_PKG_USING_ANV_BENCH is not set
+# CONFIG_PKG_USING_DEVMEM is not set
+# CONFIG_PKG_USING_REGEX is not set
+# CONFIG_PKG_USING_MEM_SANDBOX is not set
+# CONFIG_PKG_USING_SOLAR_TERMS is not set
+# CONFIG_PKG_USING_GAN_ZHI is not set
+
+#
+# system packages
+#
+
+#
+# acceleration: Assembly language or algorithmic acceleration packages
+#
+# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
+# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
+# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
+# CONFIG_PKG_USING_QFPLIB_M3 is not set
+
+#
+# Micrium: Micrium software products porting for RT-Thread
+#
+# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
+# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
+# CONFIG_PKG_USING_UC_CRC is not set
+# CONFIG_PKG_USING_UC_CLK is not set
+# CONFIG_PKG_USING_UC_COMMON is not set
+# CONFIG_PKG_USING_UC_MODBUS is not set
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_CAIRO is not set
+# CONFIG_PKG_USING_PIXMAN is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_FAL is not set
+# CONFIG_PKG_USING_FLASHDB is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+# CONFIG_PKG_USING_CMSIS is not set
+# CONFIG_PKG_USING_DFS_YAFFS is not set
+# CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_DFS_JFFS2 is not set
+# CONFIG_PKG_USING_DFS_UFFS is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_THREAD_POOL is not set
+# CONFIG_PKG_USING_ROBOTS is not set
+# CONFIG_PKG_USING_EV is not set
+# CONFIG_PKG_USING_SYSWATCH is not set
+# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
+# CONFIG_PKG_USING_PLCCORE is not set
+# CONFIG_PKG_USING_RAMDISK is not set
+# CONFIG_PKG_USING_MININI is not set
+# CONFIG_PKG_USING_QBOOT is not set
+# CONFIG_PKG_USING_PPOOL is not set
+# CONFIG_PKG_USING_OPENAMP is not set
+# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
+# CONFIG_PKG_USING_LPM is not set
+# CONFIG_PKG_USING_TLSF is not set
+# CONFIG_PKG_USING_EVENT_RECORDER is not set
+
+#
+# peripheral libraries and drivers
+#
+# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
+# CONFIG_PKG_USING_SHT2X is not set
+# CONFIG_PKG_USING_SHT3X is not set
+# CONFIG_PKG_USING_AS7341 is not set
+# CONFIG_PKG_USING_STM32_SDIO is not set
+# CONFIG_PKG_USING_ICM20608 is not set
+# CONFIG_PKG_USING_U8G2 is not set
+# CONFIG_PKG_USING_BUTTON is not set
+# CONFIG_PKG_USING_PCF8574 is not set
+# CONFIG_PKG_USING_SX12XX is not set
+# CONFIG_PKG_USING_SIGNAL_LED is not set
+# CONFIG_PKG_USING_LEDBLINK is not set
+# CONFIG_PKG_USING_LITTLED is not set
+# CONFIG_PKG_USING_LKDGUI is not set
+# CONFIG_PKG_USING_NRF5X_SDK is not set
+# CONFIG_PKG_USING_NRFX is not set
+# CONFIG_PKG_USING_WM_LIBRARIES is not set
+# CONFIG_PKG_USING_KENDRYTE_SDK is not set
+# CONFIG_PKG_USING_INFRARED is not set
+# CONFIG_PKG_USING_AGILE_BUTTON is not set
+# CONFIG_PKG_USING_AGILE_LED is not set
+# CONFIG_PKG_USING_AT24CXX is not set
+# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
+# CONFIG_PKG_USING_AD7746 is not set
+# CONFIG_PKG_USING_PCA9685 is not set
+# CONFIG_PKG_USING_I2C_TOOLS is not set
+# CONFIG_PKG_USING_NRF24L01 is not set
+# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
+# CONFIG_PKG_USING_MAX17048 is not set
+# CONFIG_PKG_USING_RPLIDAR is not set
+# CONFIG_PKG_USING_AS608 is not set
+# CONFIG_PKG_USING_RC522 is not set
+# CONFIG_PKG_USING_WS2812B is not set
+# CONFIG_PKG_USING_EMBARC_BSP is not set
+# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
+# CONFIG_PKG_USING_MULTI_RTIMER is not set
+# CONFIG_PKG_USING_MAX7219 is not set
+# CONFIG_PKG_USING_BEEP is not set
+# CONFIG_PKG_USING_EASYBLINK is not set
+# CONFIG_PKG_USING_PMS_SERIES is not set
+# CONFIG_PKG_USING_CAN_YMODEM is not set
+# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
+# CONFIG_PKG_USING_QLED is not set
+# CONFIG_PKG_USING_PAJ7620 is not set
+# CONFIG_PKG_USING_AGILE_CONSOLE is not set
+# CONFIG_PKG_USING_LD3320 is not set
+# CONFIG_PKG_USING_WK2124 is not set
+# CONFIG_PKG_USING_LY68L6400 is not set
+# CONFIG_PKG_USING_DM9051 is not set
+# CONFIG_PKG_USING_SSD1306 is not set
+# CONFIG_PKG_USING_QKEY is not set
+# CONFIG_PKG_USING_RS485 is not set
+# CONFIG_PKG_USING_NES is not set
+# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
+# CONFIG_PKG_USING_VDEVICE is not set
+# CONFIG_PKG_USING_SGM706 is not set
+# CONFIG_PKG_USING_STM32WB55_SDK is not set
+# CONFIG_PKG_USING_RDA58XX is not set
+# CONFIG_PKG_USING_LIBNFC is not set
+# CONFIG_PKG_USING_MFOC is not set
+# CONFIG_PKG_USING_TMC51XX is not set
+# CONFIG_PKG_USING_TCA9534 is not set
+# CONFIG_PKG_USING_KOBUKI is not set
+# CONFIG_PKG_USING_ROSSERIAL is not set
+# CONFIG_PKG_USING_MICRO_ROS is not set
+
+#
+# AI packages
+#
+# CONFIG_PKG_USING_LIBANN is not set
+# CONFIG_PKG_USING_NNOM is not set
+# CONFIG_PKG_USING_ONNX_BACKEND is not set
+# CONFIG_PKG_USING_ONNX_PARSER is not set
+# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
+# CONFIG_PKG_USING_ELAPACK is not set
+# CONFIG_PKG_USING_ULAPACK is not set
+# CONFIG_PKG_USING_QUEST is not set
+# CONFIG_PKG_USING_NAXOS is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_LIBCSV is not set
+# CONFIG_PKG_USING_OPTPARSE is not set
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+# CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_LZMA is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
+# CONFIG_PKG_USING_CANFESTIVAL is not set
+# CONFIG_PKG_USING_ZLIB is not set
+# CONFIG_PKG_USING_MINIZIP is not set
+# CONFIG_PKG_USING_DSTR is not set
+# CONFIG_PKG_USING_TINYFRAME is not set
+# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
+# CONFIG_PKG_USING_DIGITALCTRL is not set
+# CONFIG_PKG_USING_UPACKER is not set
+# CONFIG_PKG_USING_UPARAM is not set
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_KI is not set
+# CONFIG_PKG_USING_ARMv7M_DWT is not set
+# CONFIG_PKG_USING_VT100 is not set
+# CONFIG_PKG_USING_UKAL is not set
+# CONFIG_PKG_USING_CRCLIB is not set
+
+#
+# entertainment: terminal games and other interesting software packages
+#
+# CONFIG_PKG_USING_THREES is not set
+# CONFIG_PKG_USING_2048 is not set
+# CONFIG_PKG_USING_SNAKE is not set
+# CONFIG_PKG_USING_TETRIS is not set
+# CONFIG_PKG_USING_DONUT is not set
+# CONFIG_PKG_USING_ACLOCK is not set
+# CONFIG_PKG_USING_LWGPS is not set
+# CONFIG_PKG_USING_STATE_MACHINE is not set
+# CONFIG_PKG_USING_MCURSES is not set
+# CONFIG_PKG_USING_COWSAY is not set
+CONFIG_SOC_GD32350R=y
+CONFIG_BSP_USING_UART0=y
+# CONFIG_BSP_USING_UART1 is not set
diff --git a/bsp/gd32350r-eval/EventRecorderStub.scvd b/bsp/gd32350r-eval/EventRecorderStub.scvd
new file mode 100644
index 0000000000000000000000000000000000000000..2956b29683898915efa436cc948384a2c431dc31
--- /dev/null
+++ b/bsp/gd32350r-eval/EventRecorderStub.scvd
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/bsp/gd32350r-eval/Kconfig b/bsp/gd32350r-eval/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..907bfe3b877b8fe421b3519ab1ecb4c2b0a04d3d
--- /dev/null
+++ b/bsp/gd32350r-eval/Kconfig
@@ -0,0 +1,37 @@
+mainmenu "RT-Thread Configuration"
+
+config BSP_DIR
+ string
+ option env="BSP_ROOT"
+ default "."
+
+config RTT_DIR
+ string
+ option env="RTT_ROOT"
+ default "../.."
+
+# you can change the RTT_ROOT default: "rt-thread"
+# example : default "F:/git_repositories/rt-thread"
+
+config PKGS_DIR
+ string
+ option env="PKGS_ROOT"
+ default "packages"
+
+source "$RTT_DIR/Kconfig"
+source "$PKGS_DIR/Kconfig"
+
+config SOC_GD32350R
+ bool
+ select RT_USING_COMPONENTS_INIT
+ select RT_USING_USER_MAIN
+ default y
+
+config BSP_USING_UART0
+ bool "using uart0"
+ select RT_USING_SERIAL
+ default n
+config BSP_USING_UART1
+ bool "using uart1"
+ select RT_USING_SERIAL
+ default n
diff --git a/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Include/gd32f3x0.h b/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Include/gd32f3x0.h
new file mode 100644
index 0000000000000000000000000000000000000000..9121b966b6991514f59256b6d533138395bea211
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Include/gd32f3x0.h
@@ -0,0 +1,242 @@
+/*!
+ \file gd32f3x0.h
+ \brief general definitions for gd32f3x0
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_H
+#define GD32F3X0_H
+
+#ifdef cplusplus
+ extern "C" {
+#endif
+
+/* define GD32F3x0 */
+#if !defined (GD32F3x0)
+ #define GD32F3x0
+#endif /* define GD32F3x0 */
+#if !defined (GD32F3x0)
+ #error "Please select the target GD32F3x0 device used in your application (in gd32f3x0.h file)"
+#endif /* undefine GD32F3x0 tip */
+
+/* define GD32F3x0 device category */
+#if (!defined (GD32F330))&&(!defined (GD32F350))
+ #error "Please select GD32F3x0 device category( GD32F330 or GD32F350 )"
+#endif /* undefine GD32F330 or GD32F350 tip */
+#if (defined (GD32F330))&&(defined (GD32F350))
+ #error "Please select one GD32F3x0 device category( GD32F330 or GD32F350 )"
+#endif /* define GD32F330 and GD32F350 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 */
+
+/* GD32F3x0 firmware library version number V1.0 */
+#define __GD32F3x0_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */
+#define __GD32F3x0_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */
+#define __GD32F3x0_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
+#define __GD32F3x0_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */
+#define __GD32F3x0_STDPERIPH_VERSION ((__GD32F3x0_STDPERIPH_VERSION_MAIN << 24)\
+ |(__GD32F3x0_STDPERIPH_VERSION_SUB1 << 16)\
+ |(__GD32F3x0_STDPERIPH_VERSION_SUB2 << 8)\
+ |(__GD32F3x0_STDPERIPH_VERSION_RC))
+
+/* configuration of the Cortex-M4 processor and core peripherals */
+#define __CM4_REV 0x0001 /*!< Core revision r0p1 */
+#define __MPU_PRESENT 0U /*!< GD32F3x0 do not provide MPU */
+#define __NVIC_PRIO_BITS 4U /*!< GD32F3x0 uses 4 bits for the priority levels */
+#define __Vendor_SysTickConfig 0U /*!< set to 1 if different sysTick config is used */
+#define __FPU_PRESENT 1U /*!< FPU present */
+
+/* define interrupt number */
+typedef enum IRQn
+{
+ /* Cortex-M4 processor exceptions numbers */
+ NonMaskableInt_IRQn = -14, /*!< 2 non maskable interrupt */
+ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 memory management interrupt */
+ BusFault_IRQn = -11, /*!< 5 Cortex-M4 bus fault interrupt */
+ UsageFault_IRQn = -10, /*!< 6 Cortex-M4 usage fault interrupt */
+ SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV call interrupt */
+ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 debug monitor interrupt */
+ PendSV_IRQn = -2, /*!< 14 Cortex-M4 pend SV interrupt */
+ SysTick_IRQn = -1, /*!< 15 Cortex-M4 system tick interrupt */
+ /* interruput numbers */
+ WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */
+ LVD_IRQn = 1, /*!< LVD through EXTI line detect interrupt */
+ RCU_CTC_IRQn = 2, /*!< RTC and CTC 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 */
+ TSI_IRQn = 8, /*!< TSI Interrupt */
+ 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, CMP0 and CMP1 interrupts */
+ TIMER0_BRK_UP_TRG_COM_IRQn = 13, /*!< TIMER0 break, update, trigger and commutation interrupts */
+ TIMER0_Channel_IRQn = 14, /*!< TIMER0 channel capture compare interrupts */
+ TIMER1_IRQn = 15, /*!< TIMER1 interrupt */
+ TIMER2_IRQn = 16, /*!< TIMER2 interrupt */
+#ifdef GD32F350
+ TIMER5_DAC_IRQn = 17, /*!< TIMER5 and DAC interrupts */
+#endif /* GD32F350 */
+ 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 */
+#ifdef GD32F350
+ CEC_IRQn = 30, /*!< CEC interrupt */
+#endif /* GD32F350 */
+ I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */
+ I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */
+ DMA_Channel5_6_IRQn = 48, /*!< DMA channel 5 and channel 6 interrupts */
+#ifdef GD32F350
+ USBFS_WKUP_IRQn = 42, /*!< USBFS wakeup interrupt */
+ USBFS_IRQn = 67, /*!< USBFS global interrupt */
+#endif /* GD32F350 */
+} IRQn_Type;
+
+/* includes */
+#include "core_cm4.h"
+#include "system_gd32f3x0.h"
+#include
+
+/* enum definitions */
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus;
+typedef enum {FALSE = 0, TRUE = !FALSE} bool;
+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 */
+#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */
+#define CEC_BASE (APB1_BUS_BASE + 0x00007800U) /*!< CEC base address */
+#define CTC_BASE (APB1_BUS_BASE + 0x0000C800U) /*!< CTC 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 */
+#define TSI_BASE (AHB1_BUS_BASE + 0x00004000U) /*!< TSI base address */
+#define USBFS_BASE (AHB1_BUS_BASE + 0x0FFE0000U) /*!< USBFS 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)0xE0042000U) /*!< DBG base address */
+
+/* define marco USE_STDPERIPH_DRIVER */
+#if !defined USE_STDPERIPH_DRIVER
+#define USE_STDPERIPH_DRIVER
+#endif
+#ifdef USE_STDPERIPH_DRIVER
+#include "gd32f3x0_libopt.h"
+#endif /* USE_STDPERIPH_DRIVER */
+
+#ifdef cplusplus
+}
+#endif
+#endif
diff --git a/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Include/system_gd32f3x0.h b/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Include/system_gd32f3x0.h
new file mode 100644
index 0000000000000000000000000000000000000000..c2e466587a0ad3d2c74dd69f697a7038f4848520
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Include/system_gd32f3x0.h
@@ -0,0 +1,58 @@
+/*!
+ \file system_gd32f3x0.h
+ \brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File for
+ GD32F3x0 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_GD32F3X0_H
+#define SYSTEM_GD32F3X0_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+
+/* 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_GD32F3X0_H */
diff --git a/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Source/ARM/startup_gd32f3x0.s b/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Source/ARM/startup_gd32f3x0.s
new file mode 100644
index 0000000000000000000000000000000000000000..d9930d2455a3a5f1541fe7f437d16ff2f20ebfa5
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Source/ARM/startup_gd32f3x0.s
@@ -0,0 +1,318 @@
+;/*!
+; \file startup_gd32f3x0.s
+; \brief start up file
+;
+; \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+; \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+;*/
+;
+;/*
+; Copyright (c) 2019, GigaDevice Semiconductor Inc.
+;
+; 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.
+;*/
+
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+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 MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ 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_CTC_IRQHandler ; 20:RCU and CTC
+ 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 TSI_IRQHandler ; 24:TSI
+ 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 0-1
+ DCD TIMER0_BRK_UP_TRG_COM_IRQHandler ; 29:TIMER0 Break,Update,Trigger and Commutation
+ DCD TIMER0_Channel_IRQHandler ; 30:TIMER0 Channel Capture Compare
+ DCD TIMER1_IRQHandler ; 31:TIMER1
+ DCD TIMER2_IRQHandler ; 32:TIMER2
+ DCD TIMER5_DAC_IRQHandler ; 33:TIMER5 and DAC
+ 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 CEC_IRQHandler ; 46:CEC
+ DCD 0 ; Reserved
+ DCD I2C0_ER_IRQHandler ; 48:I2C0 Error
+ DCD 0 ; Reserved
+ DCD I2C1_ER_IRQHandler ; 50:I2C1 Error
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD USBFS_WKUP_IRQHandler ; 58:USBFS Wakeup
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD DMA_Channel5_6_IRQHandler ; 64:DMA Channel5 and Channel6
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD USBFS_IRQHandler ; 83:USBFS
+__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
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_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_CTC_IRQHandler [WEAK]
+ EXPORT EXTI0_1_IRQHandler [WEAK]
+ EXPORT EXTI2_3_IRQHandler [WEAK]
+ EXPORT EXTI4_15_IRQHandler [WEAK]
+ EXPORT TSI_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 TIMER1_IRQHandler [WEAK]
+ EXPORT TIMER2_IRQHandler [WEAK]
+ EXPORT TIMER5_DAC_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 CEC_IRQHandler [WEAK]
+ EXPORT I2C0_ER_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT USBFS_WKUP_IRQHandler [WEAK]
+ EXPORT DMA_Channel5_6_IRQHandler [WEAK]
+ EXPORT USBFS_IRQHandler [WEAK]
+
+;/* external interrupts handler */
+WWDGT_IRQHandler
+LVD_IRQHandler
+RTC_IRQHandler
+FMC_IRQHandler
+RCU_CTC_IRQHandler
+EXTI0_1_IRQHandler
+EXTI2_3_IRQHandler
+EXTI4_15_IRQHandler
+TSI_IRQHandler
+DMA_Channel0_IRQHandler
+DMA_Channel1_2_IRQHandler
+DMA_Channel3_4_IRQHandler
+ADC_CMP_IRQHandler
+TIMER0_BRK_UP_TRG_COM_IRQHandler
+TIMER0_Channel_IRQHandler
+TIMER1_IRQHandler
+TIMER2_IRQHandler
+TIMER5_DAC_IRQHandler
+TIMER13_IRQHandler
+TIMER14_IRQHandler
+TIMER15_IRQHandler
+TIMER16_IRQHandler
+I2C0_EV_IRQHandler
+I2C1_EV_IRQHandler
+SPI0_IRQHandler
+SPI1_IRQHandler
+USART0_IRQHandler
+USART1_IRQHandler
+CEC_IRQHandler
+I2C0_ER_IRQHandler
+I2C1_ER_IRQHandler
+USBFS_WKUP_IRQHandler
+DMA_Channel5_6_IRQHandler
+USBFS_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
diff --git a/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Source/IAR/startup_gd32f3x0.s b/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Source/IAR/startup_gd32f3x0.s
new file mode 100644
index 0000000000000000000000000000000000000000..2d7c70dc4a63bd3501877b8a9f47ce50fb86f29d
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Source/IAR/startup_gd32f3x0.s
@@ -0,0 +1,366 @@
+;/*!
+; \file startup_gd32f3x0.s
+; \brief start up file
+;
+; \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+; \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+;*/
+;
+;/*
+; Copyright (c) 2019, GigaDevice Semiconductor Inc.
+;
+; 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 ; Vector Number 16,Window watchdog timer
+ DCD LVD_IRQHandler ; Vector Number 17,LVD through EXTI Line detect
+ DCD RTC_IRQHandler ; Vector Number 18,RTC through EXTI Line
+ DCD FMC_IRQHandler ; Vector Number 19,FMC
+ DCD RCU_CTC_IRQHandler ; Vector Number 20,RCU and CTC
+ DCD EXTI0_1_IRQHandler ; Vector Number 21,EXTI Line 0 and EXTI Line 1
+ DCD EXTI2_3_IRQHandler ; Vector Number 22,EXTI Line 2 and EXTI Line 3
+ DCD EXTI4_15_IRQHandler ; Vector Number 23,EXTI Line 4 to EXTI Line 15
+ DCD TSI_IRQHandler ; Vector Number 24,TSI
+ DCD DMA_Channel0_IRQHandler ; Vector Number 25,DMA Channel 0
+ DCD DMA_Channel1_2_IRQHandler ; Vector Number 26,DMA Channel 1 and DMA Channel 2
+ DCD DMA_Channel3_4_IRQHandler ; Vector Number 27,DMA Channel 3 and DMA Channel 4
+ DCD ADC_CMP_IRQHandler ; Vector Number 28,ADC and Comparator 1-2
+ DCD TIMER0_BRK_UP_TRG_COM_IRQHandler ; Vector Number 29,TIMER0 Break, Update, Trigger and Commutation
+ DCD TIMER0_Channel_IRQHandler ; Vector Number 30,TIMER0 Channel Capture Compare
+ DCD TIMER1_IRQHandler ; Vector Number 31,TIMER1
+ DCD TIMER2_IRQHandler ; Vector Number 32,TIMER2
+ DCD TIMER5_DAC_IRQHandler ; Vector Number 33,TIMER5 and DAC
+ DCD 0 ; Reserved
+ DCD TIMER13_IRQHandler ; Vector Number 35,TIMER13
+ DCD TIMER14_IRQHandler ; Vector Number 36,TIMER14
+ DCD TIMER15_IRQHandler ; Vector Number 37,TIMER15
+ DCD TIMER16_IRQHandler ; Vector Number 38,TIMER16
+ DCD I2C0_EV_IRQHandler ; Vector Number 39,I2C0 Event
+ DCD I2C1_EV_IRQHandler ; Vector Number 40,I2C1 Event
+ DCD SPI0_IRQHandler ; Vector Number 41,SPI0
+ DCD SPI1_IRQHandler ; Vector Number 42,SPI1
+ DCD USART0_IRQHandler ; Vector Number 43,USART0
+ DCD USART1_IRQHandler ; Vector Number 44,USART1
+ DCD 0 ; Reserved
+ DCD CEC_IRQHandler ; Vector Number 46,CEC
+ DCD 0 ; Reserved
+ DCD I2C0_ER_IRQHandler ; Vector Number 48,I2C0 Error
+ DCD 0 ; Reserved
+ DCD I2C1_ER_IRQHandler ; Vector Number 50,I2C1 Error
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD USBFS_WKUP_IRQHandler ; Vector Number 58,USBFS Wakeup
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD DMA_Channel5_6_IRQHandler ; Vector Number 64,DMA Channel5 and Channel6
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD USBFS_IRQHandler ; Vector Number 83,USBFS
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; 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_CTC_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+RCU_CTC_IRQHandler
+ B RCU_CTC_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 TSI_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+TSI_IRQHandler
+ B TSI_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 TIMER1_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER1_IRQHandler
+ B TIMER1_IRQHandler
+
+ PUBWEAK TIMER2_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER2_IRQHandler
+ B TIMER2_IRQHandler
+
+ PUBWEAK TIMER5_DAC_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER5_DAC_IRQHandler
+ B TIMER5_DAC_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 CEC_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+CEC_IRQHandler
+ B CEC_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
+
+ PUBWEAK USBFS_WKUP_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+USBFS_WKUP_IRQHandler
+ B USBFS_WKUP_IRQHandler
+
+ PUBWEAK DMA_Channel5_6_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+DMA_Channel5_6_IRQHandler
+ B DMA_Channel5_6_IRQHandler
+
+ PUBWEAK USBFS_IRQHandler
+ SECTION .text:CODE:NOROOT:REORDER(1)
+USBFS_IRQHandler
+ B USBFS_IRQHandler
+
+ END
diff --git a/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Source/system_gd32f3x0.c b/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Source/system_gd32f3x0.c
new file mode 100644
index 0000000000000000000000000000000000000000..d8bb8bc7275fae5f06a9192b30f059418abea27d
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/CMSIS/GD/GD32F3x0/Source/system_gd32f3x0.c
@@ -0,0 +1,783 @@
+/*!
+ \file system_gd32f3x0.c
+ \brief CMSIS Cortex-M4 Device Peripheral Access Layer Source File for
+ GD32F3x0 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 "gd32f3x0.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 */
+#if defined (GD32F330)
+//#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 __SYSTEM_CLOCK_72M_PLL_IRC48M_DIV2 (uint32_t)(72000000)
+#define __SYSTEM_CLOCK_84M_PLL_HXTAL (uint32_t)(84000000)
+//#define __SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2 (uint32_t)(84000000)
+#endif /* GD32F330 */
+
+#if defined (GD32F350)
+//#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 __SYSTEM_CLOCK_84M_PLL_HXTAL (uint32_t)(84000000)
+//#define __SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2 (uint32_t)(84000000)
+//#define __SYSTEM_CLOCK_96M_PLL_HXTAL (uint32_t)(96000000)
+//#define __SYSTEM_CLOCK_96M_PLL_IRC8M_DIV2 (uint32_t)(96000000)
+//#define __SYSTEM_CLOCK_96M_PLL_IRC48M_DIV2 (uint32_t)(96000000)
+#define __SYSTEM_CLOCK_108M_PLL_HXTAL (uint32_t)(108000000)
+//#define __SYSTEM_CLOCK_108M_PLL_IRC8M_DIV2 (uint32_t)(108000000)
+#endif /* GD32F350 */
+
+#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);
+
+#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC48M_DIV2)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC48M_DIV2;
+static void system_clock_72m_irc48m(void);
+
+#elif defined (__SYSTEM_CLOCK_84M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_84M_PLL_HXTAL;
+static void system_clock_84m_hxtal(void);
+
+#elif defined (__SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2;
+static void system_clock_84m_irc8m(void);
+
+#elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_96M_PLL_HXTAL;
+static void system_clock_96m_hxtal(void);
+
+#elif defined (__SYSTEM_CLOCK_96M_PLL_IRC8M_DIV2)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_96M_PLL_IRC8M_DIV2;
+static void system_clock_96m_irc8m(void);
+
+#elif defined (__SYSTEM_CLOCK_96M_PLL_IRC48M_DIV2)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_96M_PLL_IRC48M_DIV2;
+static void system_clock_96m_irc48m(void);
+
+#elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_HXTAL;
+static void system_clock_108m_hxtal(void);
+
+#elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M_DIV2)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_IRC8M_DIV2;
+static void system_clock_108m_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)
+{
+#if (defined(GD32F350))
+ RCU_APB2EN = BIT(0);
+ CMP_CS |= (CMP_CS_CMP1MSEL | CMP_CS_CMP0MSEL);
+#endif /* GD32F350 */
+
+ /* FPU settings */
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
+#endif
+ /* 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);
+#if (defined(GD32F350))
+ RCU_CFG0 &= ~(RCU_CFG0_USBFSPSC);
+ RCU_CFG2 &= ~(RCU_CFG2_CECSEL | RCU_CFG2_USBFSPSC2);
+#endif /* GD32F350 */
+ RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS);
+ RCU_CFG1 &= ~(RCU_CFG1_PREDV | RCU_CFG1_PLLMF5 | RCU_CFG1_PLLPRESEL);
+ RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_ADCSEL);
+ RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV;
+ RCU_CFG2 &= ~RCU_CFG2_ADCPSC2;
+ RCU_CTL1 &= ~RCU_CTL1_IRC28MEN;
+ RCU_ADDCTL &= ~RCU_ADDCTL_IRC48MEN;
+ RCU_INT = 0x00000000U;
+ RCU_ADDINT = 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();
+#elif defined (__SYSTEM_CLOCK_84M_PLL_HXTAL)
+ system_clock_84m_hxtal();
+#elif defined (__SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2)
+ system_clock_84m_irc8m();
+#elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL)
+ system_clock_96m_hxtal();
+#elif defined (__SYSTEM_CLOCK_96M_PLL_IRC8M_DIV2)
+ system_clock_96m_irc8m();
+#elif defined (__SYSTEM_CLOCK_96M_PLL_IRC48M_DIV2)
+ system_clock_96m_irc48m();
+#elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
+ system_clock_108m_hxtal();
+#elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M_DIV2)
+ system_clock_108m_irc8m();
+#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)){
+ return;
+ }
+
+ /* 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)){
+ return;
+ }
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* PLL = HXTAL * 9 = 72 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV);
+ RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | 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)
+{
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+ /* 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)){
+ }
+}
+
+#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC48M_DIV2)
+/*!
+ \brief configure the system clock to 72M by PLL which selects IRC48M/2 as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_72m_irc48m(void)
+{
+ /* enable IRC48M */
+ RCU_ADDCTL |= RCU_ADDCTL_IRC48MEN;
+
+ /* wait until IRC48M is stable*/
+ while(0U == (RCU_ADDCTL & RCU_ADDCTL_IRC48MSTB)){
+ }
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+ /* PLL = (IRC48M/2) * 3 = 96 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV);
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PLLMF5);
+ RCU_CFG1 |= (RCU_PLL_PREDV2 |RCU_PLLPRESEL_IRC48M);
+ RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL3);
+
+ /* 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_84M_PLL_HXTAL)
+/*!
+ \brief configure the system clock to 84M by PLL which selects HXTAL as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_84m_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)){
+ return;
+ }
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* PLL = HXTAL /2 * 21 = 84 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV);
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PLLMF5);
+ RCU_CFG1 |= RCU_PLL_PREDV2;
+ RCU_CFG0 |= (RCU_CFG0_PLLSEL | RCU_PLL_MUL21);
+
+ /* 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_84M_PLL_IRC8M_DIV2)
+/*!
+ \brief configure the system clock to 84M by PLL which selects IRC8M/2 as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_84m_irc8m(void)
+{
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+ /* PLL = (IRC8M/2) * 21 = 84 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF);
+ RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL21);
+
+ /* 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_96M_PLL_HXTAL)
+/*!
+ \brief configure the system clock to 96M by PLL which selects HXTAL as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_96m_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)){
+ return;
+ }
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* PLL = HXTAL /2 * 24 = 96 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV);
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PLLMF5);
+ RCU_CFG1 |= RCU_PLL_PREDV2;
+ RCU_CFG0 |= (RCU_CFG0_PLLSEL | RCU_PLL_MUL24);
+
+ /* 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_96M_PLL_IRC8M_DIV2)
+/*!
+ \brief configure the system clock to 96M by PLL which selects IRC8M/2 as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_96m_irc8m(void)
+{
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+ /* PLL = (IRC8M/2) * 24 = 96 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF);
+ RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL24);
+
+ /* 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_96M_PLL_IRC48M_DIV2)
+/*!
+ \brief configure the system clock to 96M by PLL which selects IRC48M/2 as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_96m_irc48m(void)
+{
+ /* enable IRC48M */
+ RCU_ADDCTL |= RCU_ADDCTL_IRC48MEN;
+
+ /* wait until IRC48M is stable*/
+ while(0U == (RCU_ADDCTL & RCU_ADDCTL_IRC48MSTB)){
+ }
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+ /* PLL = (IRC48M/2) * 4 = 96 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV);
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PLLMF5);
+ RCU_CFG1 |= (RCU_PLL_PREDV2 |RCU_PLLPRESEL_IRC48M);
+ RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL4);
+
+ /* 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_108M_PLL_HXTAL)
+/*!
+ \brief configure the system clock to 84M by PLL which selects HXTAL as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_108m_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)){
+ return;
+ }
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* PLL = HXTAL /2 * 27 = 108 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV);
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PLLMF5);
+ RCU_CFG1 |= RCU_PLL_PREDV2;
+ RCU_CFG0 |= (RCU_CFG0_PLLSEL | RCU_PLL_MUL27);
+
+ /* 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_108M_PLL_IRC8M_DIV2)
+/*!
+ \brief configure the system clock to 108M by PLL which selects IRC8M/2 as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_108m_irc8m(void)
+{
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+ /* PLL = (IRC8M/2) * 27 = 108 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF);
+ RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL27);
+
+ /* 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, pllmf5 = 0U, pllsel = 0U, pllpresel = 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);
+ pllmf5 = GET_BITS(RCU_CFG1, 31, 31);
+ /* high 16 bits */
+ if(1U == pllmf4){
+ pllmf += 17U;
+ }else{
+ pllmf += 2U;
+ }
+ if(1U == pllmf5){
+ pllmf += 31U;
+ }
+ /* 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);
+ if(0U == pllpresel){
+ SystemCoreClock = (HXTAL_VALUE / prediv) * pllmf;
+ }else{
+ SystemCoreClock = (IRC48M_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;
+}
diff --git a/bsp/gd32350r-eval/Libraries/CMSIS/core_cm4.h b/bsp/gd32350r-eval/Libraries/CMSIS/core_cm4.h
new file mode 100644
index 0000000000000000000000000000000000000000..d82841442c5589baf40c252a6aea0d5f40b683e1
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/CMSIS/core_cm4.h
@@ -0,0 +1,1790 @@
+/**************************************************************************//**
+ * @file core_cm4.h
+ * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File
+ * @version V3.30
+ * @date 17. February 2014
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2014 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM4_H_GENERIC
+#define __CORE_CM4_H_GENERIC
+
+/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex_M4
+ @{
+ */
+
+/* CMSIS CM4 definitions */
+#define __CM4_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
+#define __CM4_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */
+#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \
+ __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x04) /*!< Cortex-M Core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ ) /* Cosmic */
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */
+ #define __STATIC_INLINE static inline
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1
+ #else
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0
+ #endif
+ #else
+ #define __FPU_USED 0
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1
+ #else
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0
+ #endif
+ #else
+ #define __FPU_USED 0
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1
+ #else
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0
+ #endif
+ #else
+ #define __FPU_USED 0
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1
+ #else
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0
+ #endif
+ #else
+ #define __FPU_USED 0
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0
+ #endif
+ #else
+ #define __FPU_USED 0
+ #endif
+
+#elif defined ( __CSMC__ ) /* Cosmic */
+ #if ( __CSMC__ & 0x400) // FPU present for parser
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0
+ #endif
+ #else
+ #define __FPU_USED 0
+ #endif
+#endif
+
+#include /* standard types definitions */
+#include /* Core Instruction Access */
+#include /* Core Function Access */
+#include /* Compiler specific SIMD Intrinsics */
+
+#endif /* __CORE_CM4_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM4_H_DEPENDANT
+#define __CORE_CM4_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM4_REV
+ #define __CM4_REV 0x0000
+ #warning "__CM4_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __FPU_PRESENT
+ #define __FPU_PRESENT 0
+ #warning "__FPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 4
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ IO Type Qualifiers are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/*@} end of group Cortex_M4 */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core Debug Register
+ - Core MPU Register
+ - Core FPU Register
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/** \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+#if (__CORTEX_M != 0x04)
+ uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
+#else
+ uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
+#endif
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+
+/** \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+
+/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+#if (__CORTEX_M != 0x04)
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+#else
+ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
+#endif
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+
+/** \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
+ uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[24];
+ __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24];
+ __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[24];
+ __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24];
+ __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
+ uint32_t RESERVED4[56];
+ __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
+ uint32_t RESERVED5[644];
+ __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
+} NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/** \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+ __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+ __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
+ __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */
+ __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
+ __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */
+ __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */
+ __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
+ __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
+ __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
+ __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
+ __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
+ __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */
+ uint32_t RESERVED0[5];
+ __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Registers Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Registers Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+ \brief Type definitions for the System Control and ID Register not in the SCB
+ @{
+ */
+
+/** \brief Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1];
+ __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */
+ __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */
+#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */
+
+#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */
+#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/** \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM)
+ \brief Type definitions for the Instrumentation Trace Macrocell (ITM)
+ @{
+ */
+
+/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+ __O union
+ {
+ __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */
+ __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */
+ __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */
+ } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864];
+ __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */
+ uint32_t RESERVED1[15];
+ __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */
+ uint32_t RESERVED2[15];
+ __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */
+ uint32_t RESERVED3[29];
+ __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */
+ __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */
+ __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */
+ uint32_t RESERVED4[43];
+ __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */
+ __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */
+ uint32_t RESERVED5[6];
+ __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */
+ __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */
+ __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */
+ __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */
+ __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */
+ __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */
+ __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */
+ __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */
+ __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */
+ __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */
+ __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */
+ __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT)
+ \brief Type definitions for the Data Watchpoint and Trace (DWT)
+ @{
+ */
+
+/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+ __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */
+ __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */
+ __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */
+ __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */
+ __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */
+ __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */
+ __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */
+ __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */
+ __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */
+ __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */
+ __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */
+ uint32_t RESERVED0[1];
+ __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */
+ __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */
+ __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */
+ uint32_t RESERVED1[1];
+ __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */
+ __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */
+ __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */
+ uint32_t RESERVED2[1];
+ __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */
+ __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */
+ __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_TPI Trace Port Interface (TPI)
+ \brief Type definitions for the Trace Port Interface (TPI)
+ @{
+ */
+
+/** \brief Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+ __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */
+ __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */
+ uint32_t RESERVED0[2];
+ __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */
+ uint32_t RESERVED1[55];
+ __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */
+ uint32_t RESERVED2[131];
+ __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */
+ __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */
+ __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */
+ uint32_t RESERVED3[759];
+ __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */
+ __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */
+ __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */
+ uint32_t RESERVED4[1];
+ __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */
+ __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */
+ __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */
+ uint32_t RESERVED5[39];
+ __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */
+ __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */
+ uint32_t RESERVED7[8];
+ __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */
+ __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */
+
+#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1)
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/** \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+ __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */
+ __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */
+ __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */
+ __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1)
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_FPU Floating Point Unit (FPU)
+ \brief Type definitions for the Floating Point Unit (FPU)
+ @{
+ */
+
+/** \brief Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1];
+ __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */
+ __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */
+ __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */
+ __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */
+ __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */
+} FPU_Type;
+
+/* Floating-Point Context Control Register */
+#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register */
+#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register */
+#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 */
+#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 */
+#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Type definitions for the Core Debug Registers
+ @{
+ */
+
+/** \brief Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+ __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
+ __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
+ __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
+ __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Cortex-M4 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
+#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
+#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
+#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */
+#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */
+#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+#if (__FPU_PRESENT == 1)
+ #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */
+ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Debug Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/** \brief Set Priority Grouping
+
+ The function sets the priority grouping field using the required unlock sequence.
+ The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+ Only values from 0..7 are used.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+
+ \param [in] PriorityGroup Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */
+ reg_value = (reg_value |
+ ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+ (PriorityGroupTmp << 8)); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+}
+
+
+/** \brief Get Priority Grouping
+
+ The function reads the priority grouping field from the NVIC Interrupt Controller.
+
+ \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+ return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */
+}
+
+
+/** \brief Enable External Interrupt
+
+ The function enables a device-specific interrupt in the NVIC interrupt controller.
+
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */
+ NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */
+}
+
+
+/** \brief Disable External Interrupt
+
+ The function disables a device-specific interrupt in the NVIC interrupt controller.
+
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+
+/** \brief Get Pending Interrupt
+
+ The function reads the pending register in the NVIC and returns the pending bit
+ for the specified interrupt.
+
+ \param [in] IRQn Interrupt number.
+
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+
+/** \brief Set Pending Interrupt
+
+ The function sets the pending bit of an external interrupt.
+
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+
+/** \brief Clear Pending Interrupt
+
+ The function clears the pending bit of an external interrupt.
+
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief Get Active Interrupt
+
+ The function reads the active register in NVIC and returns the active bit.
+
+ \param [in] IRQn Interrupt number.
+
+ \return 0 Interrupt status is not active.
+ \return 1 Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+ return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+
+/** \brief Set Interrupt Priority
+
+ The function sets the priority of an interrupt.
+
+ \note The priority cannot be set for every core interrupt.
+
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if(IRQn < 0) {
+ SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */
+ else {
+ NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
+}
+
+
+/** \brief Get Interrupt Priority
+
+ The function reads the priority of an interrupt. The interrupt
+ number can be positive to specify an external (device specific)
+ interrupt, or negative to specify an internal (core) interrupt.
+
+
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority. Value is aligned automatically to the implemented
+ priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if(IRQn < 0) {
+ return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */
+ else {
+ return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
+}
+
+
+/** \brief Encode Priority
+
+ The function encodes the priority for an interrupt with the given priority group,
+ preemptive priority value, and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set.
+
+ \param [in] PriorityGroup Used priority group.
+ \param [in] PreemptPriority Preemptive priority value (starting from 0).
+ \param [in] SubPriority Subpriority value (starting from 0).
+ \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ return (
+ ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+ ((SubPriority & ((1 << (SubPriorityBits )) - 1)))
+ );
+}
+
+
+/** \brief Decode Priority
+
+ The function decodes an interrupt priority value with a given priority group to
+ preemptive priority value and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+
+ \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+ \param [in] PriorityGroup Used priority group.
+ \param [out] pPreemptPriority Preemptive priority value (starting from 0).
+ \param [out] pSubPriority Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+ *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1);
+}
+
+
+/** \brief System Reset
+
+ The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+ (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+ SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+ while(1); /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief System Tick Configuration
+
+ The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+
+ \param [in] ticks Number of ticks between two interrupts.
+
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+
+ \note When the variable __Vendor_SysTickConfig is set to 1, then the
+ function SysTick_Config is not included. In this case, the file device.h
+ must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
+
+ SysTick->LOAD = ticks - 1; /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_core_DebugFunctions ITM Functions
+ \brief Functions that access the ITM debug interface.
+ @{
+ */
+
+extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */
+#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/** \brief ITM Send Character
+
+ The function transmits a character via the ITM channel 0, and
+ \li Just returns when no debugger is connected that has booked the output.
+ \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+
+ \param [in] ch Character to transmit.
+
+ \returns Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */
+ (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */
+ {
+ while (ITM->PORT[0].u32 == 0);
+ ITM->PORT[0].u8 = (uint8_t) ch;
+ }
+ return (ch);
+}
+
+
+/** \brief ITM Receive Character
+
+ The function inputs a character via the external variable \ref ITM_RxBuffer.
+
+ \return Received character.
+ \return -1 No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void) {
+ int32_t ch = -1; /* no character available */
+
+ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+ ch = ITM_RxBuffer;
+ ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
+ }
+
+ return (ch);
+}
+
+
+/** \brief ITM Check Character
+
+ The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+
+ \return 0 No character available.
+ \return 1 Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void) {
+
+ if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+ return (0); /* no character available */
+ } else {
+ return (1); /* character available */
+ }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+#endif /* __CORE_CM4_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/bsp/gd32350r-eval/Libraries/CMSIS/core_cm4_simd.h b/bsp/gd32350r-eval/Libraries/CMSIS/core_cm4_simd.h
new file mode 100644
index 0000000000000000000000000000000000000000..f9bceff1e514d9469fc4860410286013d8102c88
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/CMSIS/core_cm4_simd.h
@@ -0,0 +1,697 @@
+/**************************************************************************//**
+ * @file core_cm4_simd.h
+ * @brief CMSIS Cortex-M4 SIMD Header File
+ * @version V3.30
+ * @date 17. February 2014
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2014 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#endif
+
+#ifndef __CORE_CM4_SIMD_H
+#define __CORE_CM4_SIMD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ ******************************************************************************/
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+#define __SADD8 __sadd8
+#define __QADD8 __qadd8
+#define __SHADD8 __shadd8
+#define __UADD8 __uadd8
+#define __UQADD8 __uqadd8
+#define __UHADD8 __uhadd8
+#define __SSUB8 __ssub8
+#define __QSUB8 __qsub8
+#define __SHSUB8 __shsub8
+#define __USUB8 __usub8
+#define __UQSUB8 __uqsub8
+#define __UHSUB8 __uhsub8
+#define __SADD16 __sadd16
+#define __QADD16 __qadd16
+#define __SHADD16 __shadd16
+#define __UADD16 __uadd16
+#define __UQADD16 __uqadd16
+#define __UHADD16 __uhadd16
+#define __SSUB16 __ssub16
+#define __QSUB16 __qsub16
+#define __SHSUB16 __shsub16
+#define __USUB16 __usub16
+#define __UQSUB16 __uqsub16
+#define __UHSUB16 __uhsub16
+#define __SASX __sasx
+#define __QASX __qasx
+#define __SHASX __shasx
+#define __UASX __uasx
+#define __UQASX __uqasx
+#define __UHASX __uhasx
+#define __SSAX __ssax
+#define __QSAX __qsax
+#define __SHSAX __shsax
+#define __USAX __usax
+#define __UQSAX __uqsax
+#define __UHSAX __uhsax
+#define __USAD8 __usad8
+#define __USADA8 __usada8
+#define __SSAT16 __ssat16
+#define __USAT16 __usat16
+#define __UXTB16 __uxtb16
+#define __UXTAB16 __uxtab16
+#define __SXTB16 __sxtb16
+#define __SXTAB16 __sxtab16
+#define __SMUAD __smuad
+#define __SMUADX __smuadx
+#define __SMLAD __smlad
+#define __SMLADX __smladx
+#define __SMLALD __smlald
+#define __SMLALDX __smlaldx
+#define __SMUSD __smusd
+#define __SMUSDX __smusdx
+#define __SMLSD __smlsd
+#define __SMLSDX __smlsdx
+#define __SMLSLD __smlsld
+#define __SMLSLDX __smlsldx
+#define __SEL __sel
+#define __QADD __qadd
+#define __QSUB __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
+ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
+
+#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
+ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
+
+#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+ ((int64_t)(ARG3) << 32) ) >> 32))
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ // Little endian
+ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else // Big endian
+ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ // Little endian
+ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else // Big endian
+ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ // Little endian
+ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else // Big endian
+ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ // Little endian
+ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else // Big endian
+ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ if (ARG3 == 0) \
+ __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
+ else \
+ __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+#include
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+#include
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+/* not yet supported */
+
+
+#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
+/* Cosmic specific functions */
+#include
+
+#endif
+
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM4_SIMD_H */
diff --git a/bsp/gd32350r-eval/Libraries/CMSIS/core_cmFunc.h b/bsp/gd32350r-eval/Libraries/CMSIS/core_cmFunc.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c932e0d6e9dc47a0b5a06c4130ae4dccf4144c0
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/CMSIS/core_cmFunc.h
@@ -0,0 +1,616 @@
+/**************************************************************************//**
+ * @file core_cmFunc.h
+ * @brief CMSIS Cortex-M Core Function Access Header File
+ * @version V3.01
+ * @date 06. March 2012
+ *
+ * @note
+ * Copyright (C) 2009-2012 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+ #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* intrinsic void __enable_irq(); */
+/* intrinsic void __disable_irq(); */
+
+/** \brief Get Control Register
+
+ This function returns the content of the Control Register.
+
+ \return Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+ register uint32_t __regControl __ASM("control");
+ return(__regControl);
+}
+
+
+/** \brief Set Control Register
+
+ This function writes the given value to the Control Register.
+
+ \param [in] control Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+ register uint32_t __regControl __ASM("control");
+ __regControl = control;
+}
+
+
+/** \brief Get IPSR Register
+
+ This function returns the content of the IPSR Register.
+
+ \return IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+ register uint32_t __regIPSR __ASM("ipsr");
+ return(__regIPSR);
+}
+
+
+/** \brief Get APSR Register
+
+ This function returns the content of the APSR Register.
+
+ \return APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+ register uint32_t __regAPSR __ASM("apsr");
+ return(__regAPSR);
+}
+
+
+/** \brief Get xPSR Register
+
+ This function returns the content of the xPSR Register.
+
+ \return xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+ register uint32_t __regXPSR __ASM("xpsr");
+ return(__regXPSR);
+}
+
+
+/** \brief Get Process Stack Pointer
+
+ This function returns the current value of the Process Stack Pointer (PSP).
+
+ \return PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ return(__regProcessStackPointer);
+}
+
+
+/** \brief Set Process Stack Pointer
+
+ This function assigns the given value to the Process Stack Pointer (PSP).
+
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ __regProcessStackPointer = topOfProcStack;
+}
+
+
+/** \brief Get Main Stack Pointer
+
+ This function returns the current value of the Main Stack Pointer (MSP).
+
+ \return MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ return(__regMainStackPointer);
+}
+
+
+/** \brief Set Main Stack Pointer
+
+ This function assigns the given value to the Main Stack Pointer (MSP).
+
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ __regMainStackPointer = topOfMainStack;
+}
+
+
+/** \brief Get Priority Mask
+
+ This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+ \return Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ return(__regPriMask);
+}
+
+
+/** \brief Set Priority Mask
+
+ This function assigns the given value to the Priority Mask Register.
+
+ \param [in] priMask Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (priMask);
+}
+
+
+#if (__CORTEX_M >= 0x03)
+
+/** \brief Enable FIQ
+
+ This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq __enable_fiq
+
+
+/** \brief Disable FIQ
+
+ This function disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq __disable_fiq
+
+
+/** \brief Get Base Priority
+
+ This function returns the current value of the Base Priority register.
+
+ \return Base Priority register value
+ */
+__STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ return(__regBasePri);
+}
+
+
+/** \brief Set Base Priority
+
+ This function assigns the given value to the Base Priority register.
+
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ __regBasePri = (basePri & 0xff);
+}
+
+
+/** \brief Get Fault Mask
+
+ This function returns the current value of the Fault Mask register.
+
+ \return Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ return(__regFaultMask);
+}
+
+
+/** \brief Set Fault Mask
+
+ This function assigns the given value to the Fault Mask register.
+
+ \param [in] faultMask Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ __regFaultMask = (faultMask & (uint32_t)1);
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if (__CORTEX_M == 0x04)
+
+/** \brief Get FPSCR
+
+ This function returns the current value of the Floating Point Status/Control register.
+
+ \return Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ register uint32_t __regfpscr __ASM("fpscr");
+ return(__regfpscr);
+#else
+ return(0);
+#endif
+}
+
+
+/** \brief Set FPSCR
+
+ This function assigns the given value to the Floating Point Status/Control register.
+
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ register uint32_t __regfpscr __ASM("fpscr");
+ __regfpscr = (fpscr);
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) */
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+
+#include
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/** \brief Enable IRQ Interrupts
+
+ This function enables IRQ interrupts by clearing the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
+{
+ __ASM volatile ("cpsie i");
+}
+
+
+/** \brief Disable IRQ Interrupts
+
+ This function disables IRQ interrupts by setting the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
+{
+ __ASM volatile ("cpsid i");
+}
+
+
+/** \brief Get Control Register
+
+ This function returns the content of the Control Register.
+
+ \return Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, control" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Control Register
+
+ This function writes the given value to the Control Register.
+
+ \param [in] control Control Register value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+ __ASM volatile ("MSR control, %0" : : "r" (control) );
+}
+
+
+/** \brief Get IPSR Register
+
+ This function returns the content of the IPSR Register.
+
+ \return IPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Get APSR Register
+
+ This function returns the content of the APSR Register.
+
+ \return APSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Get xPSR Register
+
+ This function returns the content of the xPSR Register.
+
+ \return xPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Get Process Stack Pointer
+
+ This function returns the current value of the Process Stack Pointer (PSP).
+
+ \return PSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psp\n" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Process Stack Pointer
+
+ This function assigns the given value to the Process Stack Pointer (PSP).
+
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
+}
+
+
+/** \brief Get Main Stack Pointer
+
+ This function returns the current value of the Main Stack Pointer (MSP).
+
+ \return MSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Main Stack Pointer
+
+ This function assigns the given value to the Main Stack Pointer (MSP).
+
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
+}
+
+
+/** \brief Get Priority Mask
+
+ This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+ \return Priority Mask value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, primask" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Priority Mask
+
+ This function assigns the given value to the Priority Mask Register.
+
+ \param [in] priMask Priority Mask
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
+}
+
+
+#if (__CORTEX_M >= 0x03)
+
+/** \brief Enable FIQ
+
+ This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
+{
+ __ASM volatile ("cpsie f");
+}
+
+
+/** \brief Disable FIQ
+
+ This function disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
+{
+ __ASM volatile ("cpsid f");
+}
+
+
+/** \brief Get Base Priority
+
+ This function returns the current value of the Base Priority register.
+
+ \return Base Priority register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Base Priority
+
+ This function assigns the given value to the Base Priority register.
+
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+ __ASM volatile ("MSR basepri, %0" : : "r" (value) );
+}
+
+
+/** \brief Get Fault Mask
+
+ This function returns the current value of the Fault Mask register.
+
+ \return Fault Mask register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Fault Mask
+
+ This function assigns the given value to the Fault Mask register.
+
+ \param [in] faultMask Fault Mask value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if (__CORTEX_M == 0x04)
+
+/** \brief Get FPSCR
+
+ This function returns the current value of the Floating Point Status/Control register.
+
+ \return Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ uint32_t result;
+
+ __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+ return(result);
+#else
+ return(0);
+#endif
+}
+
+
+/** \brief Set FPSCR
+
+ This function assigns the given value to the Floating Point Status/Control register.
+
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) */
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+#endif /* __CORE_CMFUNC_H */
diff --git a/bsp/gd32350r-eval/Libraries/CMSIS/core_cmInstr.h b/bsp/gd32350r-eval/Libraries/CMSIS/core_cmInstr.h
new file mode 100644
index 0000000000000000000000000000000000000000..597e64df04408c0085d031977eaa574648f8cf9c
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/CMSIS/core_cmInstr.h
@@ -0,0 +1,618 @@
+/**************************************************************************//**
+ * @file core_cmInstr.h
+ * @brief CMSIS Cortex-M Core Instruction Access Header File
+ * @version V3.01
+ * @date 06. March 2012
+ *
+ * @note
+ * Copyright (C) 2009-2012 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+ #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+
+/** \brief No Operation
+
+ No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP __nop
+
+
+/** \brief Wait For Interrupt
+
+ Wait For Interrupt is a hint instruction that suspends execution
+ until one of a number of events occurs.
+ */
+#define __WFI __wfi
+
+
+/** \brief Wait For Event
+
+ Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+#define __WFE __wfe
+
+
+/** \brief Send Event
+
+ Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV __sev
+
+
+/** \brief Instruction Synchronization Barrier
+
+ Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or
+ memory, after the instruction has been completed.
+ */
+#define __ISB() __isb(0xF)
+
+
+/** \brief Data Synchronization Barrier
+
+ This function acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB() __dsb(0xF)
+
+
+/** \brief Data Memory Barrier
+
+ This function ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+#define __DMB() __dmb(0xF)
+
+
+/** \brief Reverse byte order (32 bit)
+
+ This function reverses the byte order in integer value.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REV __rev
+
+
+/** \brief Reverse byte order (16 bit)
+
+ This function reverses the byte order in two unsigned short values.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+ rev16 r0, r0
+ bx lr
+}
+
+
+/** \brief Reverse byte order in signed short value
+
+ This function reverses the byte order in a signed short value with sign extension to integer.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
+{
+ revsh r0, r0
+ bx lr
+}
+
+
+/** \brief Rotate Right in unsigned value (32 bit)
+
+ This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+
+ \param [in] value Value to rotate
+ \param [in] value Number of Bits to rotate
+ \return Rotated value
+ */
+#define __ROR __ror
+
+
+#if (__CORTEX_M >= 0x03)
+
+/** \brief Reverse bit order of value
+
+ This function reverses the bit order of the given value.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __RBIT __rbit
+
+
+/** \brief LDR Exclusive (8 bit)
+
+ This function performs a exclusive LDR command for 8 bit value.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
+
+
+/** \brief LDR Exclusive (16 bit)
+
+ This function performs a exclusive LDR command for 16 bit values.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
+
+
+/** \brief LDR Exclusive (32 bit)
+
+ This function performs a exclusive LDR command for 32 bit values.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
+
+
+/** \brief STR Exclusive (8 bit)
+
+ This function performs a exclusive STR command for 8 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXB(value, ptr) __strex(value, ptr)
+
+
+/** \brief STR Exclusive (16 bit)
+
+ This function performs a exclusive STR command for 16 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXH(value, ptr) __strex(value, ptr)
+
+
+/** \brief STR Exclusive (32 bit)
+
+ This function performs a exclusive STR command for 32 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXW(value, ptr) __strex(value, ptr)
+
+
+/** \brief Remove the exclusive lock
+
+ This function removes the exclusive lock which is created by LDREX.
+
+ */
+#define __CLREX __clrex
+
+
+/** \brief Signed Saturate
+
+ This function saturates a signed value.
+
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT __ssat
+
+
+/** \brief Unsigned Saturate
+
+ This function saturates an unsigned value.
+
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT __usat
+
+
+/** \brief Count leading zeros
+
+ This function counts the number of leading zeros of a data value.
+
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ __clz
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+
+#include
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/** \brief No Operation
+
+ No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
+{
+ __ASM volatile ("nop");
+}
+
+
+/** \brief Wait For Interrupt
+
+ Wait For Interrupt is a hint instruction that suspends execution
+ until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
+{
+ __ASM volatile ("wfi");
+}
+
+
+/** \brief Wait For Event
+
+ Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
+{
+ __ASM volatile ("wfe");
+}
+
+
+/** \brief Send Event
+
+ Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
+{
+ __ASM volatile ("sev");
+}
+
+
+/** \brief Instruction Synchronization Barrier
+
+ Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or
+ memory, after the instruction has been completed.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
+{
+ __ASM volatile ("isb");
+}
+
+
+/** \brief Data Synchronization Barrier
+
+ This function acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
+{
+ __ASM volatile ("dsb");
+}
+
+
+/** \brief Data Memory Barrier
+
+ This function ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
+{
+ __ASM volatile ("dmb");
+}
+
+
+/** \brief Reverse byte order (32 bit)
+
+ This function reverses the byte order in integer value.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+
+/** \brief Reverse byte order (16 bit)
+
+ This function reverses the byte order in two unsigned short values.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+
+/** \brief Reverse byte order in signed short value
+
+ This function reverses the byte order in a signed short value with sign extension to integer.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+
+/** \brief Rotate Right in unsigned value (32 bit)
+
+ This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+
+ \param [in] value Value to rotate
+ \param [in] value Number of Bits to rotate
+ \return Rotated value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+
+ __ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) );
+ return(op1);
+}
+
+
+#if (__CORTEX_M >= 0x03)
+
+/** \brief Reverse bit order of value
+
+ This function reverses the bit order of the given value.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+
+/** \brief LDR Exclusive (8 bit)
+
+ This function performs a exclusive LDR command for 8 bit value.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+ uint8_t result;
+
+ __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+
+/** \brief LDR Exclusive (16 bit)
+
+ This function performs a exclusive LDR command for 16 bit values.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+ uint16_t result;
+
+ __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+
+/** \brief LDR Exclusive (32 bit)
+
+ This function performs a exclusive LDR command for 32 bit values.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+
+/** \brief STR Exclusive (8 bit)
+
+ This function performs a exclusive STR command for 8 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+
+/** \brief STR Exclusive (16 bit)
+
+ This function performs a exclusive STR command for 16 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+
+/** \brief STR Exclusive (32 bit)
+
+ This function performs a exclusive STR command for 32 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+
+/** \brief Remove the exclusive lock
+
+ This function removes the exclusive lock which is created by LDREX.
+
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
+{
+ __ASM volatile ("clrex");
+}
+
+
+/** \brief Signed Saturate
+
+ This function saturates a signed value.
+
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/** \brief Unsigned Saturate
+
+ This function saturates an unsigned value.
+
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/** \brief Count leading zeros
+
+ This function counts the number of leading zeros of a data value.
+
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
+{
+ uint8_t result;
+
+ __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_adc.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_adc.h
new file mode 100644
index 0000000000000000000000000000000000000000..f18457857927ffae15a41fd6d931099d7da7025b
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_adc.h
@@ -0,0 +1,365 @@
+/*!
+ \file gd32f3x0_adc.h
+ \brief definitions for the ADC
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_ADC_H
+#define GD32F3X0_ADC_H
+
+#include "gd32f3x0.h"
+
+/* ADC definitions */
+#define ADC ADC_BASE
+
+/* registers definitions */
+#define ADC_STAT REG32(ADC + 0x00000000U) /*!< ADC status register */
+#define ADC_CTL0 REG32(ADC + 0x00000004U) /*!< ADC control register 0 */
+#define ADC_CTL1 REG32(ADC + 0x00000008U) /*!< ADC control register 1 */
+#define ADC_SAMPT0 REG32(ADC + 0x0000000CU) /*!< ADC sampling time register 0 */
+#define ADC_SAMPT1 REG32(ADC + 0x00000010U) /*!< ADC sampling time register 1 */
+#define ADC_IOFF0 REG32(ADC + 0x00000014U) /*!< ADC inserted channel data offset register 0 */
+#define ADC_IOFF1 REG32(ADC + 0x00000018U) /*!< ADC inserted channel data offset register 1 */
+#define ADC_IOFF2 REG32(ADC + 0x0000001CU) /*!< ADC inserted channel data offset register 2 */
+#define ADC_IOFF3 REG32(ADC + 0x00000020U) /*!< ADC inserted channel data offset register 3 */
+#define ADC_WDHT REG32(ADC + 0x00000024U) /*!< ADC watchdog high threshold register */
+#define ADC_WDLT REG32(ADC + 0x00000028U) /*!< ADC watchdog low threshold register */
+#define ADC_RSQ0 REG32(ADC + 0x0000002CU) /*!< ADC regular sequence register 0 */
+#define ADC_RSQ1 REG32(ADC + 0x00000030U) /*!< ADC regular sequence register 1 */
+#define ADC_RSQ2 REG32(ADC + 0x00000034U) /*!< ADC regular sequence register 2 */
+#define ADC_ISQ REG32(ADC + 0x00000038U) /*!< ADC inserted sequence register */
+#define ADC_IDATA0 REG32(ADC + 0x0000003CU) /*!< ADC inserted data register 0 */
+#define ADC_IDATA1 REG32(ADC + 0x00000040U) /*!< ADC inserted data register 1 */
+#define ADC_IDATA2 REG32(ADC + 0x00000044U) /*!< ADC inserted data register 2 */
+#define ADC_IDATA3 REG32(ADC + 0x00000048U) /*!< ADC inserted data register 3 */
+#define ADC_RDATA REG32(ADC + 0x0000004CU) /*!< ADC regular data register */
+#define ADC_OVSAMPCTL REG32(ADC + 0x00000080U) /*!< 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 */
+#define ADC_CTL1_VBETEN BIT(24) /*!< VBAT enable */
+
+/* ADC_SAMPTx x=0,1 */
+#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel n(n=0..18) 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_T1_CH1 CTL1_ETSRC(3) /*!< TIMER1 CH1 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_T1_TRGO CTL1_ETSIC(2) /*!< TIMER1 TRGO event select */
+#define ADC_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(3) /*!< TIMER1 CH0 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_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */
+#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */
+#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */
+#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */
+#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */
+#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */
+#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */
+#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */
+#define ADC_CHANNEL_18 ((uint8_t)0x12U) /*!< ADC channel 18 */
+
+/* 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);
+/* enable the vbat channel */
+void adc_vbat_enable(void);
+/* disable the vbat channel */
+void adc_vbat_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 /* GD32F3X0_ADC_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_cec.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_cec.h
new file mode 100644
index 0000000000000000000000000000000000000000..304c53437bb4248b691a6a773123571f48e81910
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_cec.h
@@ -0,0 +1,250 @@
+/*!
+ \file gd32f3x0_cec.h
+ \brief definitions for the CEC
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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.
+*/
+
+#ifdef GD32F350
+
+#ifndef GD32F3X0_CEC_H
+#define GD32F3X0_CEC_H
+
+#include "gd32f3x0.h"
+
+/* CEC definitions */
+#define CEC CEC_BASE /*!< CEC base address */
+
+/* registers definitions */
+#define CEC_CTL REG32(CEC + 0x00000000U) /*!< CEC control register */
+#define CEC_CFG REG32(CEC + 0x00000004U) /*!< CEC configuration register */
+#define CEC_TDATA REG32(CEC + 0x00000008U) /*!< CEC transmit data register */
+#define CEC_RDATA REG32(CEC + 0x0000000CU) /*!< CEC receive data register */
+#define CEC_INTF REG32(CEC + 0x00000010U) /*!< CEC interrupt flag Register */
+#define CEC_INTEN REG32(CEC + 0x00000014U) /*!< CEC interrupt enable register */
+
+/* bits definitions */
+/* CEC_CTL */
+#define CEC_CTL_CECEN BIT(0) /*!< enable or disable HDMI-CEC controller bit */
+#define CEC_CTL_STAOM BIT(1) /*!< start of sending a message. */
+#define CEC_CTL_ENDOM BIT(2) /*!< ENDOM bit value in the next frame in Tx mode */
+
+/* CEC_CFG */
+#define CEC_CFG_SFT BITS(0,2) /*!< signal free time */
+#define CEC_CFG_RTOL BIT(3) /*!< reception bit timing tolerance */
+#define CEC_CFG_BRES BIT(4) /*!< whether stop receive message when detected BRE */
+#define CEC_CFG_BREG BIT(5) /*!< generate Error-bit when detected BRE in singlecast */
+#define CEC_CFG_BPLEG BIT(6) /*!< generate Error-bit when detected BPLE in singlecast */
+#define CEC_CFG_BCNG BIT(7) /*!< do not generate Error-bit in broadcast message */
+#define CEC_CFG_SFTOPT BIT(8) /*!< the SFT start option bit */
+#define CEC_CFG_OWN_ADDRESS BITS(16,30) /*!< own address */
+#define CEC_CFG_LMEN BIT(31) /*!< listen mode enable bit */
+
+/* CEC_TDATA */
+#define CEC_TDATA_TDATA BITS(0,7) /*!< Tx data register */
+
+/* CEC_RDATA */
+#define CEC_RDATA_RDATA BITS(0,7) /*!< Rx data register */
+
+/* CEC_INTF */
+#define CEC_INTF_BR BIT(0) /*!< Rx-byte data received */
+#define CEC_INTF_REND BIT(1) /*!< end of reception */
+#define CEC_INTF_RO BIT(2) /*!< Rx overrun */
+#define CEC_INTF_BRE BIT(3) /*!< bit rising error */
+#define CEC_INTF_BPSE BIT(4) /*!< short bit period error */
+#define CEC_INTF_BPLE BIT(5) /*!< long bit period error */
+#define CEC_INTF_RAE BIT(6) /*!< Rx ACK error */
+#define CEC_INTF_ARBF BIT(7) /*!< arbitration fail */
+#define CEC_INTF_TBR BIT(8) /*!< Tx-byte data request */
+#define CEC_INTF_TEND BIT(9) /*!< transmission successfully end */
+#define CEC_INTF_TU BIT(10) /*!< Tx data buffer underrun */
+#define CEC_INTF_TERR BIT(11) /*!< Tx-error */
+#define CEC_INTF_TAERR BIT(12) /*!< Tx ACK error flag */
+
+/* CEC_INTEN */
+#define CEC_INTEN_BRIE BIT(0) /*!< BR interrupt enable */
+#define CEC_INTEN_RENDIE BIT(1) /*!< REND interrupt enable */
+#define CEC_INTEN_ROIE BIT(2) /*!< RO interrupt enable */
+#define CEC_INTEN_BREIE BIT(3) /*!< BRE interrupt enable. */
+#define CEC_INTEN_BPSEIE BIT(4) /*!< BPSE interrupt enable */
+#define CEC_INTEN_BPLEIE BIT(5) /*!< BPLE interrupt enable. */
+#define CEC_INTEN_RAEIE BIT(6) /*!< RAE interrupt enable */
+#define CEC_INTEN_ARBFIE BIT(7) /*!< ARBF interrupt enable */
+#define CEC_INTEN_TBRIE BIT(8) /*!< TBR interrupt enable */
+#define CEC_INTEN_TENDIE BIT(9) /*!< TEND interrupt enable */
+#define CEC_INTEN_TUIE BIT(10) /*!< TU interrupt enable */
+#define CEC_INTEN_TERRIE BIT(11) /*!< TE interrupt enable */
+#define CEC_INTEN_TAERRIE BIT(12) /*!< TAE interrupt enable */
+
+/* constants definitions */
+/* signal free time */
+#define CFG_SFT(regval) (BITS(0, 2) & ((regval) << 0U))
+#define CEC_SFT_PROTOCOL_PERIOD CFG_SFT(0) /*!< the signal free time will perform as HDMI-CEC protocol description */
+#define CEC_SFT_1POINT5_PERIOD CFG_SFT(1) /*!< 1.5 nominal data bit periods */
+#define CEC_SFT_2POINT5_PERIOD CFG_SFT(2) /*!< 2.5 nominal data bit periods */
+#define CEC_SFT_3POINT5_PERIOD CFG_SFT(3) /*!< 3.5 nominal data bit periods */
+#define CEC_SFT_4POINT5_PERIOD CFG_SFT(4) /*!< 4.5 nominal data bit periods */
+#define CEC_SFT_5POINT5_PERIOD CFG_SFT(5) /*!< 5.5 nominal data bit periods */
+#define CEC_SFT_6POINT5_PERIOD CFG_SFT(6) /*!< 6.5 nominal data bit periods */
+#define CEC_SFT_7POINT5_PERIOD CFG_SFT(7) /*!< 7.5 nominal data bit periods */
+
+/* signal free time start option */
+#define CEC_SFT_START_STAOM ((uint32_t)0x00000000U) /*!< signal free time counter starts counting when STAOM is asserted */
+#define CEC_SFT_START_LAST CEC_CFG_SFTOPT /*!< signal free time counter starts automatically after transmission/reception end */
+
+/* own address */
+#define CEC_OWN_ADDRESS_CLEAR ((uint32_t)0x00000000U) /*!< own address is cleared */
+#define CEC_OWN_ADDRESS0 BIT(16) /*!< own address is 0 */
+#define CEC_OWN_ADDRESS1 BIT(17) /*!< own address is 1 */
+#define CEC_OWN_ADDRESS2 BIT(18) /*!< own address is 2 */
+#define CEC_OWN_ADDRESS3 BIT(19) /*!< own address is 3 */
+#define CEC_OWN_ADDRESS4 BIT(20) /*!< own address is 4 */
+#define CEC_OWN_ADDRESS5 BIT(21) /*!< own address is 5 */
+#define CEC_OWN_ADDRESS6 BIT(22) /*!< own address is 6 */
+#define CEC_OWN_ADDRESS7 BIT(23) /*!< own address is 7 */
+#define CEC_OWN_ADDRESS8 BIT(24) /*!< own address is 8 */
+#define CEC_OWN_ADDRESS9 BIT(25) /*!< own address is 9 */
+#define CEC_OWN_ADDRESS10 BIT(26) /*!< own address is 10 */
+#define CEC_OWN_ADDRESS11 BIT(27) /*!< own address is 11 */
+#define CEC_OWN_ADDRESS12 BIT(28) /*!< own address is 12 */
+#define CEC_OWN_ADDRESS13 BIT(29) /*!< own address is 13 */
+#define CEC_OWN_ADDRESS14 BIT(30) /*!< own address is 14 */
+
+/* error-bit generate */
+#define CEC_BROADCAST_ERROR_BIT_ON ((uint32_t)0x00000000U) /*!< generate Error-bit in broadcast */
+#define CEC_BROADCAST_ERROR_BIT_OFF CEC_CFG_BCNG /*!< do not generate Error-bit in broadcast */
+#define CEC_LONG_PERIOD_ERROR_BIT_OFF ((uint32_t)0x00000000U) /*!< generate Error-bit on long bit period error */
+#define CEC_LONG_PERIOD_ERROR_BIT_ON CEC_CFG_BPLEG /*!< do not generate Error-bit on long bit period error */
+#define CEC_RISING_PERIOD_ERROR_BIT_OFF ((uint32_t)0x00000000U) /*!< generate Error-bit on bit rising error */
+#define CEC_RISING_PERIOD_ERROR_BIT_ON CEC_CFG_BREG /*!< do not generate Error-bit on bit rising error */
+
+/* whether stop receive message when detected bit rising error */
+#define CEC_STOP_RISING_ERROR_BIT_ON ((uint32_t)0x00000000U) /*!< stop reception when detected bit rising error */
+#define CEC_STOP_RISING_ERROR_BIT_OFF ((uint32_t)0x00000001U) /*!< do not stop reception when detected bit rising error */
+
+/* flag bits */
+#define CEC_FLAG_BR CEC_INTF_BR /*!< RX-byte data received */
+#define CEC_FLAG_REND CEC_INTF_REND /*!< end of reception */
+#define CEC_FLAG_RO CEC_INTF_RO /*!< RX overrun */
+#define CEC_FLAG_BRE CEC_INTF_BRE /*!< bit rising error */
+#define CEC_FLAG_BPSE CEC_INTF_BPSE /*!< short bit period error */
+#define CEC_FLAG_BPLE CEC_INTF_BPLE /*!< long bit period error */
+#define CEC_FLAG_RAE CEC_INTF_RAE /*!< RX ACK error */
+#define CEC_FLAG_ARBF CEC_INTF_ARBF /*!< arbitration lost */
+#define CEC_FLAG_TBR CEC_INTF_TBR /*!< TX-byte data request */
+#define CEC_FLAG_TEND CEC_INTF_TEND /*!< transmission successfully end */
+#define CEC_FLAG_TU CEC_INTF_TU /*!< TX data buffer underrun */
+#define CEC_FLAG_TERR CEC_INTF_TERR /*!< TX-error */
+#define CEC_FLAG_TAERR CEC_INTF_TAERR /*!< TX ACK error flag */
+
+/* interrupt flag bits */
+#define CEC_INT_FLAG_BR CEC_INTF_BR /*!< RX-byte data received */
+#define CEC_INT_FLAG_REND CEC_INTF_REND /*!< end of reception */
+#define CEC_INT_FLAG_RO CEC_INTF_RO /*!< RX overrun */
+#define CEC_INT_FLAG_BRE CEC_INTF_BRE /*!< bit rising error */
+#define CEC_INT_FLAG_BPSE CEC_INTF_BPSE /*!< short bit period error */
+#define CEC_INT_FLAG_BPLE CEC_INTF_BPLE /*!< long bit period error */
+#define CEC_INT_FLAG_RAE CEC_INTF_RAE /*!< RX ACK error */
+#define CEC_INT_FLAG_ARBF CEC_INTF_ARBF /*!< arbitration lost */
+#define CEC_INT_FLAG_TBR CEC_INTF_TBR /*!< TX-byte data request */
+#define CEC_INT_FLAG_TEND CEC_INTF_TEND /*!< transmission successfully end */
+#define CEC_INT_FLAG_TU CEC_INTF_TU /*!< TX data buffer underrun */
+#define CEC_INT_FLAG_TERR CEC_INTF_TERR /*!< TX-error */
+#define CEC_INT_FLAG_TAERR CEC_INTF_TAERR /*!< TX ACK error flag */
+
+/* interrupt enable bits */
+#define CEC_INT_BR CEC_INTEN_BRIE /*!< RBR interrupt enable */
+#define CEC_INT_REND CEC_INTEN_RENDIE /*!< REND interrupt enable */
+#define CEC_INT_RO CEC_INTEN_ROIE /*!< RO interrupt enable */
+#define CEC_INT_BRE CEC_INTEN_BREIE /*!< RBRE interrupt enable. */
+#define CEC_INT_BPSE CEC_INTEN_BPSEIE /*!< RSBPE interrupt enable */
+#define CEC_INT_BPLE CEC_INTEN_BPLEIE /*!< RLBPE interrupt enable. */
+#define CEC_INT_RAE CEC_INTEN_RAEIE /*!< RAE interrupt enable */
+#define CEC_INT_ARBF CEC_INTEN_ARBFIE /*!< ALRLST interrupt enable */
+#define CEC_INT_TBR CEC_INTEN_TBRIE /*!< TBR interrupt enable */
+#define CEC_INT_TEND CEC_INTEN_TENDIE /*!< TEND interrupt enable */
+#define CEC_INT_TU CEC_INTEN_TUIE /*!< TU interrupt enable */
+#define CEC_INT_TERR CEC_INTEN_TERRIE /*!< TE interrupt enable */
+#define CEC_INT_TAERR CEC_INTEN_TAERRIE /*!< TAE interrupt enable */
+
+/* function declarations */
+/* reset HDMI-CEC controller */
+void cec_deinit(void);
+/* configure signal free time,the signal free time counter start option,own address */
+void cec_init(uint32_t sftmopt, uint32_t sft, uint32_t address);
+/* configure generate Error-bit, whether stop receive message when detected bit rising error */
+void cec_error_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre, uint32_t rxbrestp);
+/* enable HDMI-CEC controller */
+void cec_enable(void);
+/* disable HDMI-CEC controller */
+void cec_disable(void);
+
+/* start CEC message transmission */
+void cec_transmission_start(void);
+/* end CEC message transmission */
+void cec_transmission_end(void);
+/* enable CEC listen mode */
+void cec_listen_mode_enable(void);
+/* disable CEC listen mode */
+void cec_listen_mode_disable(void);
+/* configure and clear own address */
+void cec_own_address_config(uint32_t address);
+/* configure signal free time and the signal free time counter start option */
+void cec_sft_config(uint32_t sftmopt,uint32_t sft);
+/* configure generate Error-bit when detected some abnormal situation or not */
+void cec_generate_errorbit_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre);
+/* whether stop receive message when detected bit rising error */
+void cec_stop_receive_bre_config(uint32_t rxbrestp);
+/* enable reception bit timing tolerance */
+void cec_reception_tolerance_enable(void);
+/* disable reception bit timing tolerance */
+void cec_reception_tolerance_disable(void);
+/* send a data by the CEC peripheral */
+void cec_data_send(uint8_t data);
+/* receive a data by the CEC peripheral */
+uint8_t cec_data_receive(void);
+
+/* enable interrupt */
+void cec_interrupt_enable(uint32_t flag);
+/* disable interrupt */
+void cec_interrupt_disable(uint32_t flag);
+/* get CEC status */
+FlagStatus cec_flag_get(uint32_t flag);
+/* clear CEC status */
+void cec_flag_clear(uint32_t flag);
+/* get CEC int flag and status */
+FlagStatus cec_interrupt_flag_get(uint32_t flag);
+/* clear CEC int flag and status */
+void cec_interrupt_flag_clear(uint32_t flag);
+
+#endif /* GD32F3X0_CEC_H */
+
+#endif /* GD32F350 */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_cmp.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_cmp.h
new file mode 100644
index 0000000000000000000000000000000000000000..19f64e03e7bffd340fb864d3f2dc82446e240e88
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_cmp.h
@@ -0,0 +1,219 @@
+/*!
+ \file gd32f3x0_cmp.h
+ \brief definitions for the CMP
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_CMP_H
+#define GD32F3X0_CMP_H
+
+#include "gd32f3x0.h"
+
+/* CMP definitions */
+#define CMP CMP_BASE /*!< CMP base address */
+
+/* registers definitions */
+#define CMP_CS REG32((CMP) + 0x00000000U) /*!< CMP control and status register */
+
+/* CMP_CS bits definitions */
+#define CMP_CS_CMP0EN BIT(0) /*!< CMP0 enable */
+#define CMP_CS_CMP0SW BIT(1) /*!< CMP0 switch */
+#define CMP_CS_CMP0M BITS(2,3) /*!< CMP0 mode */
+#define CMP_CS_CMP0MSEL BITS(4,6) /*!< COMP0_M input selection */
+#define CMP_CS_CMP0OSEL BITS(8,10) /*!< CMP0 output selection */
+#define CMP_CS_CMP0PL BIT(11) /*!< polarity of CMP0 output */
+#define CMP_CS_CMP0HST BITS(12,13) /*!< CMP0 hysteresis */
+#define CMP_CS_CMP0O BIT(14) /*!< CMP0 output */
+#define CMP_CS_CMP0LK BIT(15) /*!< CMP0 lock */
+#define CMP_CS_CMP1EN BIT(16) /*!< CMP1 enable */
+#define CMP_CS_CMP1M BITS(18,19) /*!< CMP1 mode */
+#define CMP_CS_CMP1MSEL BITS(20,22) /*!< CMP1_M input selection */
+#define CMP_CS_WNDEN BIT(23) /*!< window mode enable */
+#define CMP_CS_CMP1OSEL BITS(24,26) /*!< CMP1 output selection */
+#define CMP_CS_CMP1PL BIT(27) /*!< polarity of CMP1 output */
+#define CMP_CS_CMP1HST BITS(28,29) /*!< CMP1 hysteresis */
+#define CMP_CS_CMP1O BIT(30) /*!< CMP1 output */
+#define CMP_CS_CMP1LK BIT(31) /*!< CMP1 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_DAC, /*!< PA4 (DAC) input */
+ CMP_PA5, /*!< PA5 input */
+ CMP_PA_0_2 /*!< PA0 or 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 = 0, /*!< output no selection */
+ CMP_OUTPUT_TIMER0BKIN, /*!< TIMER 0 break input */
+ CMP_OUTPUT_TIMER0IC0, /*!< TIMER 0 channel0 input capture */
+ CMP_OUTPUT_TIMER0OCPRECLR, /*!< TIMER 0 OCPRE_CLR input */
+ CMP_OUTPUT_TIMER1IC3, /*!< TIMER 1 channel3 input capture */
+ CMP_OUTPUT_TIMER1OCPRECLR, /*!< TIMER 1 OCPRE_CLR input */
+ CMP_OUTPUT_TIMER2IC0, /*!< TIMER 2 channel0 input capture */
+ CMP_OUTPUT_TIMER2OCPRECLR /*!< TIMER 2 OCPRE_CLR input */
+}cmp_output_enum;
+
+/* CMP0 mode */
+#define CS_CMP0M(regval) (BITS(2,3) & ((uint32_t)(regval) << 2))
+#define CS_CMP0M_HIGHSPEED CS_CMP0M(0) /*!< CMP0 mode high speed */
+#define CS_CMP0M_MIDDLESPEED CS_CMP0M(1) /*!< CMP0 mode middle speed */
+#define CS_CMP0M_LOWSPEED CS_CMP0M(2) /*!< CMP0 mode low speed */
+#define CS_CMP0M_VERYLOWSPEED CS_CMP0M(3) /*!< CMP0 mode very low speed */
+
+/* comparator 0 inverting input */
+#define CS_CMP0MSEL(regval) (BITS(4,6) & ((uint32_t)(regval) << 4))
+#define CS_CMP0MSEL_1_4VREFINT CS_CMP0MSEL(0) /*!< CMP0 inverting input 1/4 Vrefint */
+#define CS_CMP0MSEL_1_2VREFINT CS_CMP0MSEL(1) /*!< CMP0 inverting input 1/2 Vrefint */
+#define CS_CMP0MSEL_3_4VREFINT CS_CMP0MSEL(2) /*!< CMP0 inverting input 3/4 Vrefint */
+#define CS_CMP0MSEL_VREFINT CS_CMP0MSEL(3) /*!< CMP0 inverting input Vrefint */
+#define CS_CMP0MSEL_DAC CS_CMP0MSEL(4) /*!< CMP0 inverting input DAC*/
+#define CS_CMP0MSEL_PA5 CS_CMP0MSEL(5) /*!< CMP0 inverting input PA5*/
+#define CS_CMP0MSEL_PA0 CS_CMP0MSEL(6) /*!< CMP0 inverting input PA0*/
+
+/* CMP0 output */
+#define CS_CMP0OSEL(regval) (BITS(8,10) & ((uint32_t)(regval) << 8))
+#define CS_CMP0OSEL_OUTPUT_NONE CS_CMP0OSEL(0) /*!< CMP0 output none */
+#define CS_CMP0OSEL_OUTPUT_TIMER0BKIN CS_CMP0OSEL(1) /*!< CMP0 output TIMER 0 break input */
+#define CS_CMP0OSEL_OUTPUT_TIMER0IC0 CS_CMP0OSEL(2) /*!< CMP0 output TIMER 0 channel 0 input capture */
+#define CS_CMP0OSEL_OUTPUT_TIMER0OCPRECLR CS_CMP0OSEL(3) /*!< CMP0 output TIMER 0 ocpreclear input */
+#define CS_CMP0OSEL_OUTPUT_TIMER1IC3 CS_CMP0OSEL(4) /*!< CMP0 output TIMER 1 channel 3 input capture */
+#define CS_CMP0OSEL_OUTPUT_TIMER1OCPRECLR CS_CMP0OSEL(5) /*!< CMP0 output TIMER 1 ocpreclear input */
+#define CS_CMP0OSEL_OUTPUT_TIMER2IC0 CS_CMP0OSEL(6) /*!< CMP0 output TIMER 2 channle 0 input capture */
+#define CS_CMP0OSEL_OUTPUT_TIMER2OCPRECLR CS_CMP0OSEL(7) /*!< CMP0 output TIMER 2 ocpreclear input */
+
+/* CMP0 hysteresis */
+#define CS_CMP0HST(regval) (BITS(12,13) & ((uint32_t)(regval) << 12))
+#define CS_CMP0HST_HYSTERESIS_NO CS_CMP0HST(0) /*!< CMP0 output no hysteresis */
+#define CS_CMP0HST_HYSTERESIS_LOW CS_CMP0HST(1) /*!< CMP0 output low hysteresis */
+#define CS_CMP0HST_HYSTERESIS_MIDDLE CS_CMP0HST(2) /*!< CMP0 output middle hysteresis */
+#define CS_CMP0HST_HYSTERESIS_HIGH CS_CMP0HST(3) /*!< CMP0 output high hysteresis */
+
+/* CMP1 mode */
+#define CS_CMP1M(regval) (BITS(18,19) & ((uint32_t)(regval) << 18))
+#define CS_CMP1M_HIGHSPEED CS_CMP1M(0) /*!< CMP1 mode high speed */
+#define CS_CMP1M_MIDDLESPEED CS_CMP1M(1) /*!< CMP1 mode middle speed */
+#define CS_CMP1M_LOWSPEED CS_CMP1M(2) /*!< CMP1 mode low speed */
+#define CS_CMP1M_VERYLOWSPEED CS_CMP1M(3) /*!< CMP1 mode very low speed */
+
+/* CMP1 inverting input */
+#define CS_CMP1MSEL(regval) (BITS(20,22) & ((uint32_t)(regval) << 20))
+#define CS_CMP1MSEL_1_4VREFINT CS_CMP1MSEL(0) /*!< CMP1 inverting input 1/4 Vrefint */
+#define CS_CMP1MSEL_1_2VREFINT CS_CMP1MSEL(1) /*!< CMP1 inverting input 1/2 Vrefint */
+#define CS_CMP1MSEL_3_4VREFINT CS_CMP1MSEL(2) /*!< CMP1 inverting input 3/4 Vrefint */
+#define CS_CMP1MSEL_VREFINT CS_CMP1MSEL(3) /*!< CMP1 inverting input Vrefint */
+#define CS_CMP1MSEL_DAC CS_CMP1MSEL(4) /*!< CMP1 inverting input DAC */
+#define CS_CMP1MSEL_PA5 CS_CMP1MSEL(5) /*!< CMP1 inverting input PA5 */
+#define CS_CMP1MSEL_PA2 CS_CMP1MSEL(6) /*!< CMP1 inverting input PA2 */
+
+/* CMP1 output */
+#define CS_CMP1OSEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24))
+#define CS_CMP1OSEL_OUTPUT_NONE CS_CMP1OSEL(0) /*!< CMP1 output none */
+#define CS_CMP1OSEL_OUTPUT_TIMER0BKIN CS_CMP1OSEL(1) /*!< CMP1 output TIMER 0 break input */
+#define CS_CMP1OSEL_OUTPUT_TIMER0IC0 CS_CMP1OSEL(2) /*!< CMP1 output TIMER 0 channel 0 input capture */
+#define CS_CMP1OSEL_OUTPUT_TIMER0OCPRECLR CS_CMP1OSEL(3) /*!< CMP1 output TIMER 0 ocpreclear input */
+#define CS_CMP1OSEL_OUTPUT_TIMER1IC3 CS_CMP1OSEL(4) /*!< CMP1 output TIMER 1 channel 3 input capture */
+#define CS_CMP1OSEL_OUTPUT_TIMER1OCPRECLR CS_CMP1OSEL(5) /*!< CMP1 output TIMER 1 ocpreclear input */
+#define CS_CMP1OSEL_OUTPUT_TIMER2IC0 CS_CMP1OSEL(6) /*!< CMP1 output TIMER 2 channle 0 input capture */
+#define CS_CMP1OSEL_OUTPUT_TIMER2OCPRECLR CS_CMP1OSEL(7) /*!< CMP1 output TIMER 2 ocpreclear input */
+
+/* CMP1 hysteresis */
+#define CS_CMP1HST(regval) (BITS(28,29) & ((uint32_t)(regval) << 28))
+#define CS_CMP1HST_HSTHYSTERESIS_NO CS_CMP1HST(0) /*!< CMP1 output no hysteresis */
+#define CS_CMP1HST_HYSTERESIS_LOW CS_CMP1HST(1) /*!< CMP1 output low hysteresis */
+#define CS_CMP1HST_HYSTERESIS_MIDDLE CS_CMP1HST(2) /*!< CMP1 output middle hysteresis */
+#define CS_CMP1HST_HYSTERESIS_HIGH CS_CMP1HST(3) /*!< CMP1 output high hysteresis */
+
+/* comparator x definitions */
+#define CMP0 ((uint32_t)0x00000000) /*!< comparator 0 */
+#define CMP1 ((uint32_t)0x00000010) /*!< comparator 1 */
+
+/* comparator 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(uint32_t cmp_periph, operating_mode_enum operating_mode, inverting_input_enum inverting_input, cmp_hysteresis_enum output_hysteresis);
+/* CMP output init */
+void cmp_output_init(uint32_t cmp_periph, cmp_output_enum output_slection, uint32_t output_polarity);
+
+/* enable functions */
+/* enable CMP */
+void cmp_enable(uint32_t cmp_periph);
+/* disable CMP */
+void cmp_disable(uint32_t cmp_periph);
+/* enable CMP switch */
+void cmp_switch_enable(void);
+/* disable CMP switch */
+void cmp_switch_disable(void);
+/* enable the window mode */
+void cmp_window_enable(void);
+/* disable the window mode */
+void cmp_window_disable(void);
+/* lock the CMP */
+void cmp_lock_enable(uint32_t cmp_periph);
+
+/* output functions */
+/* get output level */
+uint32_t cmp_output_level_get(uint32_t cmp_periph);
+
+#endif /* GD32F3X0_CMP_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_crc.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_crc.h
new file mode 100644
index 0000000000000000000000000000000000000000..398af8223861a7465fa685b678bc91c17a322132
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_crc.h
@@ -0,0 +1,119 @@
+/*!
+ \file gd32f3x0_crc.h
+ \brief definitions for the CRC
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_CRC_H
+#define GD32F3X0_CRC_H
+
+#include "gd32f3x0.h"
+
+/* CRC definitions */
+#define CRC CRC_BASE
+
+/* registers definitions */
+#define CRC_DATA REG32(CRC + 0x00000000U) /*!< CRC data register */
+#define CRC_FDATA REG32(CRC + 0x00000004U) /*!< CRC free data register */
+#define CRC_CTL REG32(CRC + 0x00000008U) /*!< CRC control register */
+#define CRC_IDATA REG32(CRC + 0x00000010U) /*!< CRC initialization data register */
+#define CRC_POLY REG32(CRC + 0x00000014U) /*!< 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 /* GD32F3X0_CRC_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_ctc.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_ctc.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c8ff14e08309722f3b470c30ca6b8d70195be1a
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_ctc.h
@@ -0,0 +1,191 @@
+/*!
+ \file gd32f3x0_ctc.h
+ \brief definitions for the CTC
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_CTC_H
+#define GD32F3X0_CTC_H
+
+#include "gd32f3x0.h"
+
+/* CTC definitions */
+#define CTC CTC_BASE
+
+/* registers definitions */
+#define CTC_CTL0 REG32(CTC + 0x00000000U) /*!< CTC control register 0 */
+#define CTC_CTL1 REG32(CTC + 0x00000004U) /*!< CTC control register 1 */
+#define CTC_STAT REG32(CTC + 0x00000008U) /*!< CTC status register */
+#define CTC_INTC REG32(CTC + 0x0000000CU) /*!< CTC interrupt clear register */
+
+/* bits definitions */
+/* CTC_CTL0 */
+#define CTC_CTL0_CKOKIE BIT(0) /*!< clock trim OK(CKOKIF) interrupt enable */
+#define CTC_CTL0_CKWARNIE BIT(1) /*!< clock trim warning(CKWARNIF) interrupt enable */
+#define CTC_CTL0_ERRIE BIT(2) /*!< error(ERRIF) interrupt enable */
+#define CTC_CTL0_EREFIE BIT(3) /*!< EREFIF interrupt enable */
+#define CTC_CTL0_CNTEN BIT(5) /*!< CTC counter enable */
+#define CTC_CTL0_AUTOTRIM BIT(6) /*!< hardware automatically trim mode */
+#define CTC_CTL0_SWREFPUL BIT(7) /*!< software reference source sync pulse */
+#define CTC_CTL0_TRIMVALUE BITS(8,13) /*!< IRC48M trim value */
+
+/* CTC_CTL1 */
+#define CTC_CTL1_RLVALUE BITS(0,15) /*!< CTC counter reload value */
+#define CTC_CTL1_CKLIM BITS(16,23) /*!< clock trim base limit value */
+#define CTC_CTL1_REFPSC BITS(24,26) /*!< reference signal source prescaler */
+#define CTC_CTL1_REFSEL BITS(28,29) /*!< reference signal source selection */
+#define CTC_CTL1_REFPOL BIT(31) /*!< reference signal source polarity */
+
+/* CTC_STAT */
+#define CTC_STAT_CKOKIF BIT(0) /*!< clock trim OK interrupt flag */
+#define CTC_STAT_CKWARNIF BIT(1) /*!< clock trim warning interrupt flag */
+#define CTC_STAT_ERRIF BIT(2) /*!< error interrupt flag */
+#define CTC_STAT_EREFIF BIT(3) /*!< expect reference interrupt flag */
+#define CTC_STAT_CKERR BIT(8) /*!< clock trim error bit */
+#define CTC_STAT_REFMISS BIT(9) /*!< reference sync pulse miss */
+#define CTC_STAT_TRIMERR BIT(10) /*!< trim value error bit */
+#define CTC_STAT_REFDIR BIT(15) /*!< CTC trim counter direction when reference sync pulse occurred */
+#define CTC_STAT_REFCAP BITS(16,31) /*!< CTC counter capture when reference sync pulse occurred */
+
+/* CTC_INTC */
+#define CTC_INTC_CKOKIC BIT(0) /*!< CKOKIF interrupt clear bit */
+#define CTC_INTC_CKWARNIC BIT(1) /*!< CKWARNIF interrupt clear bit */
+#define CTC_INTC_ERRIC BIT(2) /*!< ERRIF interrupt clear bit */
+#define CTC_INTC_EREFIC BIT(3) /*!< EREFIF interrupt clear bit */
+
+/* constants definitions */
+#define CTL0_TRIMVALUE(regval) (BITS(8,13) & ((uint32_t)(regval) << 8))
+#define CTL1_CKLIM(regval) (BITS(16,23) & ((uint32_t)(regval) << 16))
+#define GET_STAT_REFCAP(regval) GET_BITS((regval),16,31)
+#define GET_CTL0_TRIMVALUE(regval) GET_BITS((regval),8,13)
+
+/* hardware automatically trim mode definitions */
+#define CTC_HARDWARE_TRIM_MODE_ENABLE CTC_CTL0_AUTOTRIM /*!< hardware automatically trim mode enable*/
+#define CTC_HARDWARE_TRIM_MODE_DISABLE ((uint32_t)0x00000000U) /*!< hardware automatically trim mode disable*/
+
+/* reference signal source polarity definitions */
+#define CTC_REFSOURCE_POLARITY_FALLING CTC_CTL1_REFPOL /*!< reference signal source polarity is falling edge*/
+#define CTC_REFSOURCE_POLARITY_RISING ((uint32_t)0x00000000U) /*!< reference signal source polarity is rising edge*/
+
+/* reference signal source selection definitions */
+#define CTL1_REFSEL(regval) (BITS(28,29) & ((uint32_t)(regval) << 28))
+#define CTC_REFSOURCE_GPIO CTL1_REFSEL(0) /*!< GPIO is selected */
+#define CTC_REFSOURCE_LXTAL CTL1_REFSEL(1) /*!< LXTAL is clock selected */
+#define CTC_REFSOURCE_USBSOF CTL1_REFSEL(2) /*!< USBFSSOF selected */
+
+/* reference signal source prescaler definitions */
+#define CTL1_REFPSC(regval) (BITS(24,26) & ((uint32_t)(regval) << 24))
+#define CTC_REFSOURCE_PSC_OFF CTL1_REFPSC(0) /*!< reference signal not divided */
+#define CTC_REFSOURCE_PSC_DIV2 CTL1_REFPSC(1) /*!< reference signal divided by 2 */
+#define CTC_REFSOURCE_PSC_DIV4 CTL1_REFPSC(2) /*!< reference signal divided by 4 */
+#define CTC_REFSOURCE_PSC_DIV8 CTL1_REFPSC(3) /*!< reference signal divided by 8 */
+#define CTC_REFSOURCE_PSC_DIV16 CTL1_REFPSC(4) /*!< reference signal divided by 16 */
+#define CTC_REFSOURCE_PSC_DIV32 CTL1_REFPSC(5) /*!< reference signal divided by 32 */
+#define CTC_REFSOURCE_PSC_DIV64 CTL1_REFPSC(6) /*!< reference signal divided by 64 */
+#define CTC_REFSOURCE_PSC_DIV128 CTL1_REFPSC(7) /*!< reference signal divided by 128 */
+
+/* CTC interrupt enable definitions */
+#define CTC_INT_CKOK CTC_CTL0_CKOKIE /*!< clock trim OK interrupt enable */
+#define CTC_INT_CKWARN CTC_CTL0_CKWARNIE /*!< clock trim warning interrupt enable */
+#define CTC_INT_ERR CTC_CTL0_ERRIE /*!< error interrupt enable */
+#define CTC_INT_EREF CTC_CTL0_EREFIE /*!< expect reference interrupt enable */
+
+/* CTC interrupt source definitions */
+#define CTC_INT_FLAG_CKOK CTC_STAT_CKOKIF /*!< clock trim OK interrupt flag */
+#define CTC_INT_FLAG_CKWARN CTC_STAT_CKWARNIF /*!< clock trim warning interrupt flag */
+#define CTC_INT_FLAG_ERR CTC_STAT_ERRIF /*!< error interrupt flag */
+#define CTC_INT_FLAG_EREF CTC_STAT_EREFIF /*!< expect reference interrupt flag */
+#define CTC_INT_FLAG_CKERR CTC_STAT_CKERR /*!< clock trim error bit */
+#define CTC_INT_FLAG_REFMISS CTC_STAT_REFMISS /*!< reference sync pulse miss */
+#define CTC_INT_FLAG_TRIMERR CTC_STAT_TRIMERR /*!< trim value error */
+
+/* CTC flag definitions */
+#define CTC_FLAG_CKOK CTC_STAT_CKOKIF /*!< clock trim OK flag */
+#define CTC_FLAG_CKWARN CTC_STAT_CKWARNIF /*!< clock trim warning flag */
+#define CTC_FLAG_ERR CTC_STAT_ERRIF /*!< error flag */
+#define CTC_FLAG_EREF CTC_STAT_EREFIF /*!< expect reference flag */
+#define CTC_FLAG_CKERR CTC_STAT_CKERR /*!< clock trim error bit */
+#define CTC_FLAG_REFMISS CTC_STAT_REFMISS /*!< reference sync pulse miss */
+#define CTC_FLAG_TRIMERR CTC_STAT_TRIMERR /*!< trim value error bit */
+
+/* function declarations */
+/* initialization functions */
+/* reset ctc clock trim controller */
+void ctc_deinit(void);
+/* configure reference signal source polarity */
+void ctc_refsource_polarity_config(uint32_t polarity);
+/* select reference signal source */
+void ctc_refsource_signal_select(uint32_t refs);
+/* configure reference signal source prescaler */
+void ctc_refsource_prescaler_config(uint32_t prescaler);
+/* configure clock trim base limit value */
+void ctc_clock_limit_value_config(uint8_t limit_value);
+/* configure CTC counter reload value */
+void ctc_counter_reload_value_config(uint16_t reload_value);
+/* enable CTC trim counter */
+void ctc_counter_enable(void);
+/* disable CTC trim counter */
+void ctc_counter_disable(void);
+
+/* function configuration */
+/* configure the IRC48M trim value */
+void ctc_irc48m_trim_value_config(uint8_t trim_value);
+/* generate software reference source sync pulse */
+void ctc_software_refsource_pulse_generate(void);
+/* configure hardware automatically trim mode */
+void ctc_hardware_trim_mode_config(uint32_t hardmode);
+
+/* reading functions */
+/* read CTC counter capture value when reference sync pulse occurred */
+uint16_t ctc_counter_capture_value_read(void);
+/* read CTC trim counter direction when reference sync pulse occurred */
+FlagStatus ctc_counter_direction_read(void);
+/* read CTC counter reload value */
+uint16_t ctc_counter_reload_value_read(void);
+/* read the IRC48M trim value */
+uint8_t ctc_irc48m_trim_value_read(void);
+
+/* interrupt & flag functions */
+/* enable the CTC interrupt */
+void ctc_interrupt_enable(uint32_t interrupt);
+/* disable the CTC interrupt */
+void ctc_interrupt_disable(uint32_t interrupt);
+/* get CTC flag */
+FlagStatus ctc_flag_get(uint32_t flag);
+/* clear CTC flag */
+void ctc_flag_clear(uint32_t flag);
+/* get CTC interrupt flag */
+FlagStatus ctc_interrupt_flag_get(uint32_t interrupt);
+/* clear CTC interrupt flag */
+void ctc_interrupt_flag_clear(uint32_t interrupt);
+
+#endif /* GD32F3X0_CTC_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_dac.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_dac.h
new file mode 100644
index 0000000000000000000000000000000000000000..5975f7724c0b81fa2ea152357d6dced55bed20a6
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_dac.h
@@ -0,0 +1,204 @@
+/*!
+ \file gd32f3x0_dac.h
+ \brief definitions for the DAC
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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.
+*/
+
+#ifdef GD32F350
+#ifndef GD32F3X0_DAC_H
+#define GD32F3X0_DAC_H
+
+#include "gd32f3x0.h"
+
+/* DAC definitions */
+#define DAC DAC_BASE
+
+/* registers definitions */
+#define DAC_CTL REG32(DAC + (0x00000000U)) /*!< DAC control register */
+#define DAC_SWT REG32(DAC + (0x00000004U)) /*!< DAC software trigger register */
+#define DAC_R12DH REG32(DAC + (0x00000008U)) /*!< DAC 12-bit right-aligned data holding register */
+#define DAC_L12DH REG32(DAC + (0x0000000CU)) /*!< DAC 12-bit left-aligned data holding register */
+#define DAC_R8DH REG32(DAC + (0x00000010U)) /*!< DAC 8-bit right-aligned data holding register */
+#define DAC_DO REG32(DAC + (0x0000002CU)) /*!< DAC output data register */
+#define DAC_STAT REG32(DAC + (0x00000034U)) /*!< DAC status register */
+
+/* bits definitions */
+/* DAC_CTL */
+#define DAC_CTL_DEN BIT(0) /*!< DAC enable/disable bit */
+#define DAC_CTL_DBOFF BIT(1) /*!< DAC output buffer turn on/turn off bit */
+#define DAC_CTL_DTEN BIT(2) /*!< DAC trigger enable/disable bit */
+#define DAC_CTL_DTSEL BITS(3,5) /*!< DAC trigger source selection enable/disable bits */
+#define DAC_CTL_DWM BITS(6,7) /*!< DAC noise wave mode */
+#define DAC_CTL_DWBW BITS(8,11) /*!< DAC noise wave bit width */
+#define DAC_CTL_DDMAEN BIT(12) /*!< DAC DMA enable/disable bit */
+#define DAC_CTL_DDUDRIE BIT(13) /*!< DAC DMA underrun interrupt enable/disable bit */
+
+/* DAC_SWT */
+#define DAC_SWT_SWTR BIT(0) /*!< DAC software trigger bit,cleared by hardware */
+
+/* DAC_R12DH */
+#define DAC_R12DH_DAC_DH BITS(0,11) /*!< DAC 12-bit right-aligned data bits */
+
+/* DAC_L12DH */
+#define DAC_L12DH_DAC_DH BITS(4,15) /*!< DAC 12-bit left-aligned data bits */
+
+/* DAC_R8DH */
+#define DAC_R8DH_DAC_DH BITS(0,7) /*!< DAC 8-bit right-aligned data bits */
+
+/* DAC_DO */
+#define DAC_DO_DAC_DO BITS(0,11) /*!< DAC 12-bit output data bits */
+
+/* DAC_STAT */
+#define DAC_STAT_DDUDR BIT(13) /*!< DAC DMA underrun flag */
+
+/* constants definitions */
+/* DAC trigger source */
+#define CTL_DTSEL(regval) (BITS(3,5) & ((uint32_t)(regval) << 3))
+#define DAC_TRIGGER_T5_TRGO CTL_DTSEL(0) /*!< TIMER5 TRGO */
+#define DAC_TRIGGER_T2_TRGO CTL_DTSEL(1) /*!< TIMER2 TRGO */
+#define DAC_TRIGGER_T14_TRGO CTL_DTSEL(3) /*!< TIMER14 TRGO */
+#define DAC_TRIGGER_T1_TRGO CTL_DTSEL(4) /*!< TIMER1 TRGO */
+#define DAC_TRIGGER_EXTI_9 CTL_DTSEL(6) /*!< EXTI interrupt line9 event */
+#define DAC_TRIGGER_SOFTWARE CTL_DTSEL(7) /*!< software trigger */
+
+/* DAC noise wave mode */
+#define CTL_DWM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6))
+#define DAC_WAVE_DISABLE CTL_DWM(0) /*!< wave disable */
+#define DAC_WAVE_MODE_LFSR CTL_DWM(1) /*!< LFSR noise mode */
+#define DAC_WAVE_MODE_TRIANGLE CTL_DWM(2) /*!< triangle noise mode */
+
+/* DAC noise wave bit width */
+#define DWBW(regval) (BITS(8,11) & ((uint32_t)(regval) << 8))
+#define DAC_WAVE_BIT_WIDTH_1 DWBW(0) /*!< bit width of the wave signal is 1 */
+#define DAC_WAVE_BIT_WIDTH_2 DWBW(1) /*!< bit width of the wave signal is 2 */
+#define DAC_WAVE_BIT_WIDTH_3 DWBW(2) /*!< bit width of the wave signal is 3 */
+#define DAC_WAVE_BIT_WIDTH_4 DWBW(3) /*!< bit width of the wave signal is 4 */
+#define DAC_WAVE_BIT_WIDTH_5 DWBW(4) /*!< bit width of the wave signal is 5 */
+#define DAC_WAVE_BIT_WIDTH_6 DWBW(5) /*!< bit width of the wave signal is 6 */
+#define DAC_WAVE_BIT_WIDTH_7 DWBW(6) /*!< bit width of the wave signal is 7 */
+#define DAC_WAVE_BIT_WIDTH_8 DWBW(7) /*!< bit width of the wave signal is 8 */
+#define DAC_WAVE_BIT_WIDTH_9 DWBW(8) /*!< bit width of the wave signal is 9 */
+#define DAC_WAVE_BIT_WIDTH_10 DWBW(9) /*!< bit width of the wave signal is 10 */
+#define DAC_WAVE_BIT_WIDTH_11 DWBW(10) /*!< bit width of the wave signal is 11 */
+#define DAC_WAVE_BIT_WIDTH_12 DWBW(11) /*!< bit width of the wave signal is 12 */
+
+/* unmask LFSR bits in DAC LFSR noise mode */
+#define DAC_LFSR_BIT0 DAC_WAVE_BIT_WIDTH_1 /*!< unmask the LFSR bit0 */
+#define DAC_LFSR_BITS1_0 DAC_WAVE_BIT_WIDTH_2 /*!< unmask the LFSR bits[1:0] */
+#define DAC_LFSR_BITS2_0 DAC_WAVE_BIT_WIDTH_3 /*!< unmask the LFSR bits[2:0] */
+#define DAC_LFSR_BITS3_0 DAC_WAVE_BIT_WIDTH_4 /*!< unmask the LFSR bits[3:0] */
+#define DAC_LFSR_BITS4_0 DAC_WAVE_BIT_WIDTH_5 /*!< unmask the LFSR bits[4:0] */
+#define DAC_LFSR_BITS5_0 DAC_WAVE_BIT_WIDTH_6 /*!< unmask the LFSR bits[5:0] */
+#define DAC_LFSR_BITS6_0 DAC_WAVE_BIT_WIDTH_7 /*!< unmask the LFSR bits[6:0] */
+#define DAC_LFSR_BITS7_0 DAC_WAVE_BIT_WIDTH_8 /*!< unmask the LFSR bits[7:0] */
+#define DAC_LFSR_BITS8_0 DAC_WAVE_BIT_WIDTH_9 /*!< unmask the LFSR bits[8:0] */
+#define DAC_LFSR_BITS9_0 DAC_WAVE_BIT_WIDTH_10 /*!< unmask the LFSR bits[9:0] */
+#define DAC_LFSR_BITS10_0 DAC_WAVE_BIT_WIDTH_11 /*!< unmask the LFSR bits[10:0] */
+#define DAC_LFSR_BITS11_0 DAC_WAVE_BIT_WIDTH_12 /*!< unmask the LFSR bits[11:0] */
+
+/* triangle amplitude in DAC triangle noise mode */
+#define DAC_TRIANGLE_AMPLITUDE_1 DAC_WAVE_BIT_WIDTH_1 /*!< triangle amplitude is 1 */
+#define DAC_TRIANGLE_AMPLITUDE_3 DAC_WAVE_BIT_WIDTH_2 /*!< triangle amplitude is 3 */
+#define DAC_TRIANGLE_AMPLITUDE_7 DAC_WAVE_BIT_WIDTH_3 /*!< triangle amplitude is 7 */
+#define DAC_TRIANGLE_AMPLITUDE_15 DAC_WAVE_BIT_WIDTH_4 /*!< triangle amplitude is 15 */
+#define DAC_TRIANGLE_AMPLITUDE_31 DAC_WAVE_BIT_WIDTH_5 /*!< triangle amplitude is 31 */
+#define DAC_TRIANGLE_AMPLITUDE_63 DAC_WAVE_BIT_WIDTH_6 /*!< triangle amplitude is 63 */
+#define DAC_TRIANGLE_AMPLITUDE_127 DAC_WAVE_BIT_WIDTH_7 /*!< triangle amplitude is 127 */
+#define DAC_TRIANGLE_AMPLITUDE_255 DAC_WAVE_BIT_WIDTH_8 /*!< triangle amplitude is 255 */
+#define DAC_TRIANGLE_AMPLITUDE_511 DAC_WAVE_BIT_WIDTH_9 /*!< triangle amplitude is 511 */
+#define DAC_TRIANGLE_AMPLITUDE_1023 DAC_WAVE_BIT_WIDTH_10 /*!< triangle amplitude is 1023 */
+#define DAC_TRIANGLE_AMPLITUDE_2047 DAC_WAVE_BIT_WIDTH_11 /*!< triangle amplitude is 2047 */
+#define DAC_TRIANGLE_AMPLITUDE_4095 DAC_WAVE_BIT_WIDTH_12 /*!< triangle amplitude is 4095 */
+
+/* DAC data alignment */
+#define DATA_ALIGN(regval) (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define DAC_ALIGN_12B_R DATA_ALIGN(0) /*!< data right 12b alignment */
+#define DAC_ALIGN_12B_L DATA_ALIGN(1) /*!< data left 12b alignment */
+#define DAC_ALIGN_8B_R DATA_ALIGN(2) /*!< data right 8b alignment */
+
+/* function declarations */
+/* deinitialize DAC */
+void dac_deinit(void);
+
+/* enable DAC */
+void dac_enable(void);
+/* disable DAC */
+void dac_disable(void);
+/* enable DAC DMA */
+void dac_dma_enable(void);
+/* disable DAC DMA */
+void dac_dma_disable(void);
+/* enable DAC output buffer */
+void dac_output_buffer_enable(void);
+/* disable DAC output buffer */
+void dac_output_buffer_disable(void);
+/* enable DAC trigger */
+void dac_trigger_enable(void);
+/* disable DAC trigger */
+void dac_trigger_disable(void);
+/* enable DAC software trigger */
+void dac_software_trigger_enable(void);
+/* disable DAC software trigger */
+void dac_software_trigger_disable(void);
+/* enable DAC interrupt(DAC DMA underrun interrupt) */
+void dac_interrupt_enable(void);
+/* disable DAC interrupt(DAC DMA underrun interrupt) */
+void dac_interrupt_disable(void);
+
+/* configure DAC trigger source */
+void dac_trigger_source_config(uint32_t triggersource);
+/* configure DAC wave mode */
+void dac_wave_mode_config(uint32_t wave_mode);
+/* configure DAC wave bit width */
+void dac_wave_bit_width_config(uint32_t bit_width);
+/* configure DAC LFSR noise mode */
+void dac_lfsr_noise_config(uint32_t unmask_bits);
+/* configure DAC triangle noise mode */
+void dac_triangle_noise_config(uint32_t amplitude);
+/* get the last data output value */
+uint16_t dac_output_value_get(void);
+
+/* get the specified DAC flag(DAC DMA underrun flag) */
+FlagStatus dac_flag_get(void);
+/* clear the specified DAC flag(DAC DMA underrun flag) */
+void dac_flag_clear(void);
+/* get the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */
+FlagStatus dac_interrupt_flag_get(void);
+/* clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */
+void dac_interrupt_flag_clear(void);
+
+/* set DAC data holding register value */
+void dac_data_set(uint32_t dac_align, uint16_t data);
+
+#endif /* GD32F3X0_DAC_H */
+
+#endif /* GD32F350 */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_dbg.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_dbg.h
new file mode 100644
index 0000000000000000000000000000000000000000..9492753345671009353140130e8e40cb0d6c9b51
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_dbg.h
@@ -0,0 +1,128 @@
+/*!
+ \file gd32f3x0_dbg.h
+ \brief definitions for the DBG
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_DBG_H
+#define GD32F3X0_DBG_H
+
+#include "gd32f3x0.h"
+
+/* DBG definitions */
+#define DBG DBG_BASE
+
+/* registers definitions */
+#define DBG_ID REG32(DBG + 0x00000000U) /*!< DBG_ID code register */
+#define DBG_CTL0 REG32(DBG + 0x00000004U) /*!< DBG control register 0 */
+#define DBG_CTL1 REG32(DBG + 0x00000008U) /*!< 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) /*!< hold TIMER0 counter when core is halted */
+#define DBG_CTL0_TIMER1_HOLD BIT(11) /*!< hold TIMER1 counter when core is halted */
+#define DBG_CTL0_TIMER2_HOLD BIT(12) /*!< hold TIMER2 counter 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 */
+#ifdef GD32F350
+#define DBG_CTL0_TIMER5_HOLD BIT(19) /*!< hold TIMER5 counter when core is halted */
+#endif /* GD32F350 */
+#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) & 0x0000001FU)
+
+/* register index */
+typedef enum
+{
+ DBG_IDX_CTL0 = 0x04U, /*!< DBG control register 0 offset */
+ DBG_IDX_CTL1 = 0x08U, /*!< DBG control register 1 offset */
+}dbg_reg_idx;
+
+/* peripherals hold bit */
+typedef enum
+{
+ DBG_FWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 8U), /*!< debug FWDGT kept when core is halted */
+ DBG_WWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 9U), /*!< debug WWDGT kept when core is halted */
+ DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 10U), /*!< hold TIMER0 counter when core is halted */
+ DBG_TIMER1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 11U), /*!< hold TIMER1 counter when core is halted */
+ DBG_TIMER2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 12U), /*!< hold TIMER2 counter when core is halted */
+#ifdef GD32F350
+ DBG_TIMER5_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 19U), /*!< hold TIMER5 counter when core is halted */
+#endif /* GD32F350 */
+ DBG_TIMER13_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 27U), /*!< hold TIMER13 counter when core is halted */
+ DBG_TIMER14_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 16U), /*!< hold TIMER14 counter when core is halted */
+ DBG_TIMER15_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 17U), /*!< hold TIMER15 counter when core is halted */
+ DBG_TIMER16_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 18U), /*!< hold TIMER16 counter when core is halted */
+ DBG_I2C0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 15U), /*!< hold I2C0 smbus when core is halted */
+ DBG_I2C1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 16U), /*!< hold I2C1 smbus when core is halted */
+ DBG_RTC_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 10U), /*!< hold RTC calendar and wakeup counter when core is halted */
+}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 /* GD32F3X0_DBG_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_dma.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_dma.h
new file mode 100644
index 0000000000000000000000000000000000000000..9c24dca1ddb3623a7f23eb2bdab876957f3df4a5
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_dma.h
@@ -0,0 +1,273 @@
+/*!
+ \file gd32f3x0_dma.h
+ \brief definitions for the DMA
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_DMA_H
+#define GD32F3X0_DMA_H
+
+#include "gd32f3x0.h"
+
+/* DMA definitions */
+#define DMA DMA_BASE /*!< DMA base address */
+
+/* registers definitions */
+#define DMA_INTF REG32(DMA + 0x00000000U) /*!< DMA interrupt flag register */
+#define DMA_INTC REG32(DMA + 0x00000004U) /*!< DMA interrupt flag clear register */
+#define DMA_CH0CTL REG32(DMA + 0x00000008U) /*!< DMA channel 0 control register */
+#define DMA_CH0CNT REG32(DMA + 0x0000000CU) /*!< DMA channel 0 counter register */
+#define DMA_CH0PADDR REG32(DMA + 0x00000010U) /*!< DMA channel 0 peripheral base address register */
+#define DMA_CH0MADDR REG32(DMA + 0x00000014U) /*!< DMA channel 0 memory base address register */
+#define DMA_CH1CTL REG32(DMA + 0x0000001CU) /*!< DMA channel 1 control register */
+#define DMA_CH1CNT REG32(DMA + 0x00000020U) /*!< DMA channel 1 counter register */
+#define DMA_CH1PADDR REG32(DMA + 0x00000024U) /*!< DMA channel 1 peripheral base address register */
+#define DMA_CH1MADDR REG32(DMA + 0x00000028U) /*!< DMA channel 1 memory base address register */
+#define DMA_CH2CTL REG32(DMA + 0x00000030U) /*!< DMA channel 2 control register */
+#define DMA_CH2CNT REG32(DMA + 0x00000034U) /*!< DMA channel 2 counter register */
+#define DMA_CH2PADDR REG32(DMA + 0x00000038U) /*!< DMA channel 2 peripheral base address register */
+#define DMA_CH2MADDR REG32(DMA + 0x0000003CU) /*!< DMA channel 2 memory base address register */
+#define DMA_CH3CTL REG32(DMA + 0x00000044U) /*!< DMA channel 3 control register */
+#define DMA_CH3CNT REG32(DMA + 0x00000048U) /*!< DMA channel 3 counter register */
+#define DMA_CH3PADDR REG32(DMA + 0x0000004CU) /*!< DMA channel 3 peripheral base address register */
+#define DMA_CH3MADDR REG32(DMA + 0x00000050U) /*!< DMA channel 3 memory base address register */
+#define DMA_CH4CTL REG32(DMA + 0x00000058U) /*!< DMA channel 4 control register */
+#define DMA_CH4CNT REG32(DMA + 0x0000005CU) /*!< DMA channel 4 counter register */
+#define DMA_CH4PADDR REG32(DMA + 0x00000060U) /*!< DMA channel 4 peripheral base address register */
+#define DMA_CH4MADDR REG32(DMA + 0x00000064U) /*!< DMA channel 4 memory base address register */
+#define DMA_CH5CTL REG32(DMA + 0x0000006CU) /*!< DMA channel 5 control register */
+#define DMA_CH5CNT REG32(DMA + 0x00000070U) /*!< DMA channel 5 counter register */
+#define DMA_CH5PADDR REG32(DMA + 0x00000074U) /*!< DMA channel 5 peripheral base address register */
+#define DMA_CH5MADDR REG32(DMA + 0x00000078U) /*!< DMA channel 5 memory base address register */
+#define DMA_CH6CTL REG32(DMA + 0x00000080U) /*!< DMA channel 6 control register */
+#define DMA_CH6CNT REG32(DMA + 0x00000084U) /*!< DMA channel 6 counter register */
+#define DMA_CH6PADDR REG32(DMA + 0x00000088U) /*!< DMA channel 6 peripheral base address register */
+#define DMA_CH6MADDR REG32(DMA + 0x0000008CU) /*!< DMA channel 6 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..6 */
+#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..6 */
+#define DMA_CHXCNT_CNT BITS(0,15) /*!< transfer counter */
+
+/* DMA_CHxPADDR,x=0..6 */
+#define DMA_CHXPADDR_PADDR BITS(0,31) /*!< peripheral base address */
+
+/* DMA_CHxMADDR,x=0..6 */
+#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_CH5, /*!< DMA Channel5 */
+ DMA_CH6 /*!< DMA Channel6 */
+} dma_channel_enum;
+
+/* DMA initialize struct */
+typedef struct
+{
+ uint32_t periph_addr; /*!< peripheral base address */
+ uint32_t periph_width; /*!< transfer data size of peripheral */
+ uint8_t periph_inc; /*!< peripheral increasing mode */
+ uint32_t memory_addr; /*!< memory base address */
+ uint32_t memory_width; /*!< transfer data size of memory */
+ uint8_t memory_inc; /*!< memory increasing mode */
+ uint8_t direction; /*!< channel data transfer direction */
+ uint32_t number; /*!< channel transfer number */
+ uint32_t priority; /*!< channel priority level */
+} 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 + (uint32_t)0x00000008U) /*!< the base address of DMA channel CHXCTL register */
+#define DMA_CHXCNT_BASE (DMA + (uint32_t)0x0000000CU) /*!< the base address of DMA channel CHXCNT register */
+#define DMA_CHXPADDR_BASE (DMA + (uint32_t)0x00000010U) /*!< the base address of DMA channel CHXPADDR register */
+#define DMA_CHXMADDR_BASE (DMA + (uint32_t)0x00000014U) /*!< the base address of DMA channel CHXMADDR register */
+
+/* DMA channel shift bit */
+#define DMA_CHCTL(channel) REG32(DMA_CHXCTL_BASE + (uint32_t)0x0000014U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCTL register */
+#define DMA_CHCNT(channel) REG32(DMA_CHXCNT_BASE + (uint32_t)0x0000014U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCNT register */
+#define DMA_CHPADDR(channel) REG32(DMA_CHXPADDR_BASE + (uint32_t)0x0000014U * (uint32_t)(channel)) /*!< the address of DMA channel CHXPADDR register */
+#define DMA_CHMADDR(channel) REG32(DMA_CHXMADDR_BASE + (uint32_t)0x0000014U * (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(0) /*!< transfer data size of peripheral is 8-bit */
+#define DMA_PERIPHERAL_WIDTH_16BIT CHCTL_PWIDTH(1) /*!< transfer data size of peripheral is 16-bit */
+#define DMA_PERIPHERAL_WIDTH_32BIT CHCTL_PWIDTH(2) /*!< 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(0) /*!< transfer data size of memory is 8-bit */
+#define DMA_MEMORY_WIDTH_16BIT CHCTL_MWIDTH(1) /*!< transfer data size of memory is 16-bit */
+#define DMA_MEMORY_WIDTH_32BIT CHCTL_MWIDTH(2) /*!< transfer data size of memory is 32-bit */
+
+/* channel priority level */
+#define CHCTL_PRIO(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) /*!< DMA channel priority level */
+#define DMA_PRIORITY_LOW CHCTL_PRIO(0) /*!< low priority */
+#define DMA_PRIORITY_MEDIUM CHCTL_PRIO(1) /*!< medium priority */
+#define DMA_PRIORITY_HIGH CHCTL_PRIO(2) /*!< high priority */
+#define DMA_PRIORITY_ULTRA_HIGH CHCTL_PRIO(3) /*!< 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 /* GD32F3X0_DMA_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_exti.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_exti.h
new file mode 100644
index 0000000000000000000000000000000000000000..3e17ff3c577a325a24bf12da187c10f5890f2b1f
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_exti.h
@@ -0,0 +1,285 @@
+/*!
+ \file gd32f3x0_exti.h
+ \brief definitions for the EXTI
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_EXTI_H
+#define GD32F3X0_EXTI_H
+
+#include "gd32f3x0.h"
+
+/* EXTI definitions */
+#define EXTI EXTI_BASE
+
+/* registers definitions */
+#define EXTI_INTEN REG32(EXTI + 0x00000000U)/*!< interrupt enable register */
+#define EXTI_EVEN REG32(EXTI + 0x00000004U)/*!< event enable register */
+#define EXTI_RTEN REG32(EXTI + 0x00000008U)/*!< rising edge trigger enable register */
+#define EXTI_FTEN REG32(EXTI + 0x0000000CU)/*!< falling trigger enable register */
+#define EXTI_SWIEV REG32(EXTI + 0x00000010U)/*!< software interrupt event register */
+#define EXTI_PD REG32(EXTI + 0x00000014U)/*!< 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_RTEN18 BIT(18) /*!< rising edge from line 18 */
+#define EXTI_RTEN_RTEN19 BIT(19) /*!< rising edge from line 19 */
+#define EXTI_RTEN_RTEN21 BIT(21) /*!< rising edge from line 21 */
+#define EXTI_RTEN_RTEN22 BIT(22) /*!< rising edge from line 22 */
+
+/* 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_FTEN18 BIT(18) /*!< falling edge from line 18 */
+#define EXTI_FTEN_FTEN19 BIT(19) /*!< falling edge from line 19 */
+#define EXTI_FTEN_FTEN21 BIT(21) /*!< falling edge from line 21 */
+#define EXTI_FTEN_FTEN22 BIT(22) /*!< falling edge from line 22 */
+
+/* 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_SWIEV18 BIT(18) /*!< software interrupt/event request from line 18 */
+#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 */
+#define EXTI_SWIEV_SWIEV22 BIT(22) /*!< software interrupt/event request from line 22 */
+
+/* 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_PD18 BIT(18) /*!< interrupt/event pending status from line 18 */
+#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 */
+#define EXTI_PD_PD22 BIT(22) /*!< interrupt/event pending status from line 22 */
+
+/* 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);
+/* initialize the EXTI, 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);
+/* disable the interrupts from EXTI line x */
+void exti_interrupt_disable(exti_line_enum linex);
+/* enable the events from EXTI line x */
+void exti_event_enable(exti_line_enum linex);
+/* disable the events from EXTI line x */
+void exti_event_disable(exti_line_enum linex);
+
+/* enable EXTI software interrupt event */
+void exti_software_interrupt_enable(exti_line_enum linex);
+/* disable EXTI software interrupt event */
+void exti_software_interrupt_disable(exti_line_enum linex);
+/* get EXTI line x pending flag */
+FlagStatus exti_flag_get(exti_line_enum linex);
+/* clear EXTI line x pending flag */
+void exti_flag_clear(exti_line_enum linex);
+/* get EXTI line x flag when the interrupt flag is set */
+FlagStatus exti_interrupt_flag_get(exti_line_enum linex);
+/* clear EXTI line x pending flag */
+void exti_interrupt_flag_clear(exti_line_enum linex);
+
+#endif /* GD32F3X0_EXTI_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_fmc.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_fmc.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e49e73dc965805132b0678d4467482fba18a8da
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_fmc.h
@@ -0,0 +1,258 @@
+/*!
+ \file gd32f3x0_fmc.h
+ \brief definitions for the FMC
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_FMC_H
+#define GD32F3X0_FMC_H
+
+#include "gd32f3x0.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 + 0x00000000U) /*!< FMC wait state register */
+#define FMC_KEY REG32(FMC + 0x00000004U) /*!< FMC unlock key register */
+#define FMC_OBKEY REG32(FMC + 0x00000008U) /*!< FMC option bytes unlock key register */
+#define FMC_STAT REG32(FMC + 0x0000000CU) /*!< FMC status register */
+#define FMC_CTL REG32(FMC + 0x00000010U) /*!< FMC control register */
+#define FMC_ADDR REG32(FMC + 0x00000014U) /*!< FMC address register */
+#define FMC_OBSTAT REG32(FMC + 0x0000001CU) /*!< FMC option bytes status register */
+#define FMC_WP REG32(FMC + 0x00000020U) /*!< FMC write protection register */
+#define FMC_WSEN REG32(FMC + 0x000000FCU) /*!< FMC wait state enable register */
+#define FMC_PID REG32(FMC + 0x00000100U) /*!< FMC product ID register */
+
+#define OB_SPC REG16(OB + 0x00000000U) /*!< option byte security protection value */
+#define OB_USER REG16(OB + 0x00000002U) /*!< option byte user value*/
+#define OB_DATA0 REG16(OB + 0x00000004U) /*!< option byte data bit[7:0] value*/
+#define OB_DATA1 REG16(OB + 0x00000006U) /*!< option byte data bit[15:8] value*/
+#define OB_WP0 REG16(OB + 0x00000008U) /*!< option byte write protection 0 */
+#define OB_WP1 REG16(OB + 0x0000000AU) /*!< option byte write protection 1 */
+
+/* bits definitions */
+/* FMC_WS */
+#define FMC_WS_WSCNT BITS(0,2) /*!< wait state counter */
+
+/* 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_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_WSEN */
+#define FMC_WSEN_WSEN BIT(0) /*!< FMC wait state enable bit */
+#define FMC_WSEN_BPEN BIT(1) /*!< FMC bit program enable bit */
+
+/* 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_WPERR, /*!< erase/program protection error */
+ FMC_TOERR, /*!< timeout error */
+ FMC_OB_HSPC /*!< option byte security protection code high */
+}fmc_state_enum;
+
+/* option byte parameter */
+typedef struct
+{
+ uint8_t spc; /*!< option byte parameter spc */
+ uint8_t user; /*!< option byte parameter user */
+ uint8_t data0; /*!< option byte parameter data0 */
+ uint8_t data1; /*!< option byte parameter data1 */
+ uint8_t wp0; /*!< option byte parameter wp0 */
+ uint8_t wp1; /*!< option byte parameter wp1 */
+}ob_parm_struct;
+
+/* 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 ((uint8_t)0xA5U) /*!< no security protection */
+#define FMC_LSPC ((uint8_t)0xBBU) /*!< low security protection, any value except 0xA5 or 0xCC */
+#define FMC_HSPC ((uint8_t)0xCCU) /*!< high security 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 */
+
+#define OB_FWDGT_HW ((uint8_t)(~BIT(0))) /*!< hardware free watchdog timer */
+#define OB_DEEPSLEEP_RST ((uint8_t)(~BIT(1))) /*!< generate a reset instead of entering deepsleep mode */
+#define OB_STDBY_RST ((uint8_t)(~BIT(2))) /*!< generate a reset instead of entering standby mode */
+#define OB_BOOT1_SET_1 ((uint8_t)(~BIT(4))) /*!< BOOT1 bit is 1 */
+#define OB_VDDA_DISABLE ((uint8_t)(~BIT(5))) /*!< disable VDDA monitor */
+#define OB_SRAM_PARITY_ENABLE ((uint8_t)(~BIT(6))) /*!< enable SRAM parity check */
+
+/* option byte security protection level in FMC_OBSTAT register */
+#define OB_OBSTAT_PLEVEL_NO ((uint32_t)0x00000000U) /*!< no security protection */
+#define OB_OBSTAT_PLEVEL_LOW ((uint32_t)0x00000002U) /*!< low security protection */
+#define OB_OBSTAT_PLEVEL_HIGH ((uint32_t)0x00000006U) /*!< high security protection */
+
+#define OB_USER_DEFAULT ((uint8_t)0xDFU) /*!< OB_USER default value */
+
+/* option byte parameter address */
+#define OB_SPC_ADDR (uint32_t)(OB + 0x00000000U)/*!< option byte spc address */
+#define OB_USER_ADDR (uint32_t)(OB + 0x00000002U)/*!< option byte user address */
+#define OB_DATA_ADDR0 (uint32_t)(OB + 0x00000004U)/*!< option byte data address 0 */
+#define OB_DATA_ADDR1 (uint32_t)(OB + 0x00000006U)/*!< option byte data address 1 */
+#define OB_WP_ADDR0 (uint32_t)(OB + 0x00000008U)/*!< option byte wp address 0 */
+#define OB_WP_ADDR1 (uint32_t)(OB + 0x0000000AU)/*!< option byte wp 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_WPERR FMC_STAT_WPERR /*!< FMC write protection error flag */
+#define FMC_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);
+/* fmc wait state enable */
+void fmc_wait_state_enable(void);
+/* fmc wait state disable */
+void fmc_wait_state_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 word at the corresponding address */
+fmc_state_enum fmc_word_program(uint32_t address, uint32_t data);
+/* FMC program a half word at the corresponding address */
+fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data);
+/* FMC program a word at the corresponding address without erasing */
+fmc_state_enum fmc_word_reprogram(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);
+/* 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(uint8_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(uint32_t address, uint8_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 interrupt flag set or reset */
+FlagStatus fmc_interrupt_flag_get(uint32_t flag);
+/* clear the FMC interrupt pending flag */
+void fmc_interrupt_flag_clear(uint32_t 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);
+/* get current option byte value */
+void ob_parm_get(ob_parm_struct *ob_parm);
+/* modify the target option byte depending on the original value */
+void ob_value_modify(uint32_t address, uint16_t value,ob_parm_struct *ob_parm);
+
+#endif /* GD32F3X0_FMC_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_fwdgt.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_fwdgt.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b2d9db64fc449d721eeb19546f633f79dd11aef
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_fwdgt.h
@@ -0,0 +1,124 @@
+/*!
+ \file gd32f3x0_fwdgt.h
+ \brief definitions for the FWDGT
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_FWDGT_H
+#define GD32F3X0_FWDGT_H
+
+#include "gd32f3x0.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_CTL register value */
+#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_CTL_CMD bit field */
+
+/* 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 */
+
+/* FWDGT_RLD register value */
+#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_RLD_RLD bit field */
+
+/* FWDGT_WND register value */
+#define WND_WND(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_WND_WND bit field */
+
+/* control value */
+#define FWDGT_WRITEACCESS_ENABLE ((uint16_t)0x5555U) /*!< FWDGT_CTL bits write access enable value */
+#define FWDGT_WRITEACCESS_DISABLE ((uint16_t)0x0000U) /*!< FWDGT_CTL bits write access disable value */
+#define FWDGT_KEY_RELOAD ((uint16_t)0xAAAAU) /*!< FWDGT_CTL bits fwdgt counter reload value */
+#define FWDGT_KEY_ENABLE ((uint16_t)0xCCCCU) /*!< 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 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 /* GD32F3X0_FWDGT_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_gpio.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_gpio.h
new file mode 100644
index 0000000000000000000000000000000000000000..045accbd021f8a048149db7665815b76e7b8aa7a
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_gpio.h
@@ -0,0 +1,408 @@
+/*!
+ \file gd32f3x0_gpio.h
+ \brief definitions for the GPIO
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_GPIO_H
+#define GD32F3X0_GPIO_H
+
+#include "gd32f3x0.h"
+
+/* GPIOx(x=A,B,C,D,F) definitions */
+#define GPIOA (GPIO_BASE + 0x00000000U)
+#define GPIOB (GPIO_BASE + 0x00000400U)
+#define GPIOC (GPIO_BASE + 0x00000800U)
+#define GPIOD (GPIO_BASE + 0x00000C00U)
+#define GPIOF (GPIO_BASE + 0x00001400U)
+
+/* registers definitions */
+#define GPIO_CTL(gpiox) REG32((gpiox) + 0x00000000U) /*!< GPIO port control register */
+#define GPIO_OMODE(gpiox) REG32((gpiox) + 0x00000004U) /*!< GPIO port output mode register */
+#define GPIO_OSPD0(gpiox) REG32((gpiox) + 0x00000008U) /*!< GPIO port output speed register 0 */
+#define GPIO_PUD(gpiox) REG32((gpiox) + 0x0000000CU) /*!< GPIO port pull-up/pull-down register */
+#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x00000010U) /*!< GPIO port input status register */
+#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x00000014U) /*!< GPIO port output control register */
+#define GPIO_BOP(gpiox) REG32((gpiox) + 0x00000018U) /*!< GPIO port bit operation register */
+#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x0000001CU) /*!< GPIO port configuration lock register */
+#define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x00000020U) /*!< GPIO alternate function selected register 0 */
+#define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x00000024U) /*!< GPIO alternate function selected register 1 */
+#define GPIO_BC(gpiox) REG32((gpiox) + 0x00000028U) /*!< GPIO bit clear register */
+#define GPIO_TG(gpiox) REG32((gpiox) + 0x0000002CU) /*!< GPIO port bit toggle register */
+#define GPIO_OSPD1(gpiox) REG32((gpiox) + 0x0000003CU) /*!< GPIO port output speed register 1 */
+
+/* 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_OSPD0 */
+#define GPIO_OSPD0_OSPD0 BITS(0,1) /*!< pin 0 output max speed bits */
+#define GPIO_OSPD0_OSPD1 BITS(2,3) /*!< pin 1 output max speed bits */
+#define GPIO_OSPD0_OSPD2 BITS(4,5) /*!< pin 2 output max speed bits */
+#define GPIO_OSPD0_OSPD3 BITS(6,7) /*!< pin 3 output max speed bits */
+#define GPIO_OSPD0_OSPD4 BITS(8,9) /*!< pin 4 output max speed bits */
+#define GPIO_OSPD0_OSPD5 BITS(10,11) /*!< pin 5 output max speed bits */
+#define GPIO_OSPD0_OSPD6 BITS(12,13) /*!< pin 6 output max speed bits */
+#define GPIO_OSPD0_OSPD7 BITS(14,15) /*!< pin 7 output max speed bits */
+#define GPIO_OSPD0_OSPD8 BITS(16,17) /*!< pin 8 output max speed bits */
+#define GPIO_OSPD0_OSPD9 BITS(18,19) /*!< pin 9 output max speed bits */
+#define GPIO_OSPD0_OSPD10 BITS(20,21) /*!< pin 10 output max speed bits */
+#define GPIO_OSPD0_OSPD11 BITS(22,23) /*!< pin 11 output max speed bits */
+#define GPIO_OSPD0_OSPD12 BITS(24,25) /*!< pin 12 output max speed bits */
+#define GPIO_OSPD0_OSPD13 BITS(26,27) /*!< pin 13 output max speed bits */
+#define GPIO_OSPD0_OSPD14 BITS(28,29) /*!< pin 14 output max speed bits */
+#define GPIO_OSPD0_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 */
+
+/* GPIO_OSPD1 */
+#define GPIO_OSPD1_SPD0 BIT(0) /*!< set pin 0 very high output speed when OSPD0 is "11" */
+#define GPIO_OSPD1_SPD1 BIT(1) /*!< set pin 1 very high output speed when OSPD1 is "11" */
+#define GPIO_OSPD1_SPD2 BIT(2) /*!< set pin 2 very high output speed when OSPD2 is "11" */
+#define GPIO_OSPD1_SPD3 BIT(3) /*!< set pin 3 very high output speed when OSPD3 is "11" */
+#define GPIO_OSPD1_SPD4 BIT(4) /*!< set pin 4 very high output speed when OSPD4 is "11" */
+#define GPIO_OSPD1_SPD5 BIT(5) /*!< set pin 5 very high output speed when OSPD5 is "11" */
+#define GPIO_OSPD1_SPD6 BIT(6) /*!< set pin 6 very high output speed when OSPD6 is "11" */
+#define GPIO_OSPD1_SPD7 BIT(7) /*!< set pin 7 very high output speed when OSPD7 is "11" */
+#define GPIO_OSPD1_SPD8 BIT(8) /*!< set pin 8 very high output speed when OSPD8 is "11" */
+#define GPIO_OSPD1_SPD9 BIT(9) /*!< set pin 9 very high output speed when OSPD9 is "11" */
+#define GPIO_OSPD1_SPD10 BIT(10) /*!< set pin 10 very high output speed when OSPD10 is "11" */
+#define GPIO_OSPD1_SPD11 BIT(11) /*!< set pin 11 very high output speed when OSPD11 is "11" */
+#define GPIO_OSPD1_SPD12 BIT(12) /*!< set pin 12 very high output speed when OSPD12 is "11" */
+#define GPIO_OSPD1_SPD13 BIT(13) /*!< set pin 13 very high output speed when OSPD13 is "11" */
+#define GPIO_OSPD1_SPD14 BIT(14) /*!< set pin 14 very high output speed when OSPD14 is "11" */
+#define GPIO_OSPD1_SPD15 BIT(15) /*!< set pin 15 very high output speed when OSPD15 is "11" */
+
+/* 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) ((uint32_t)((uint32_t)0x00000003U << (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) ((uint32_t)((uint32_t)0x00000003U << (2U * (n))))
+
+/* GPIO output speed values */
+#define GPIO_OSPEED_SET(n, speed) ((uint32_t)((uint32_t)(speed) << (2U * (n))))
+#define GPIO_OSPEED_MASK(n) ((uint32_t)((uint32_t)0x00000003U << (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 */
+#define GPIO_OSPEED_MAX ((uint32_t)0x0000FFFFU) /*!< GPIO very high output speed, max speed more than 50MHz */
+
+/* GPIO alternate function values */
+#define GPIO_AFR_SET(n, af) ((uint32_t)((uint32_t)(af) << (4U * (n))))
+#define GPIO_AFR_MASK(n) ((uint32_t)((uint32_t)0x0000000FU << (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 /* GD32F3X0_GPIO_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_i2c.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_i2c.h
new file mode 100644
index 0000000000000000000000000000000000000000..d37cc1cf3860715978b4121aa51a4a24e249c4ad
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_i2c.h
@@ -0,0 +1,347 @@
+/*!
+ \file gd32f3x0_i2c.h
+ \brief definitions for the I2C
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_I2C_H
+#define GD32F3X0_I2C_H
+
+#include "gd32f3x0.h"
+
+/* I2Cx(x=0,1) definitions */
+#define I2C0 I2C_BASE /*!< I2C0 base address */
+#define I2C1 (I2C_BASE+0x00000400U) /*!< I2C1 base address */
+
+/* registers definitions */
+#define I2C_CTL0(i2cx) REG32((i2cx) + 0x00000000U) /*!< I2C control register 0 */
+#define I2C_CTL1(i2cx) REG32((i2cx) + 0x00000004U) /*!< I2C control register 1 */
+#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x00000008U) /*!< I2C slave address register 0*/
+#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0000000CU) /*!< I2C slave address register */
+#define I2C_DATA(i2cx) REG32((i2cx) + 0x00000010U) /*!< I2C transfer buffer register */
+#define I2C_STAT0(i2cx) REG32((i2cx) + 0x00000014U) /*!< I2C transfer status register 0 */
+#define I2C_STAT1(i2cx) REG32((i2cx) + 0x00000018U) /*!< I2C transfer status register */
+#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x0000001CU) /*!< I2C clock configure register */
+#define I2C_RT(i2cx) REG32((i2cx) + 0x00000020U) /*!< I2C rise time register */
+#define I2C_FMPCFG(i2cx) REG32((i2cx) + 0x00000090U) /*!< 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_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) & 0x0000FFFFU) >> 6)))
+#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU)
+#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) & 0x001F0000U) >> 16)
+
+/* register offset */
+#define I2C_CTL1_REG_OFFSET (0x00000004U) /*!< CTL1 register offset */
+#define I2C_STAT0_REG_OFFSET (0x00000014U) /*!< STAT0 register offset */
+#define I2C_STAT1_REG_OFFSET (0x00000018U) /*!< STAT1 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 */
+}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 */
+}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 */
+}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_DISABLE I2C_CTL0_SS /*!< SCL stretching is enabled */
+#define I2C_SCLSTRETCH_ENABLE ((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 position of ACK and PEC when receiving */
+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);
+
+/* whether to enable I2C PEC calculation or not */
+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);
+/* whether ARP is enabled under SMBus */
+void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate);
+
+/* 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 /* GD32F3X0_I2C_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_misc.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_misc.h
new file mode 100644
index 0000000000000000000000000000000000000000..08586feda5c8a4feb4f446bb54da664f4e7e9b4a
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_misc.h
@@ -0,0 +1,92 @@
+/*!
+ \file gd32f3x0_misc.h
+ \brief definitions for the MISC
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_MISC_H
+#define GD32F3X0_MISC_H
+
+#include "gd32f3x0.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 */
+
+/* priority group - define the pre-emption priority and the subpriority */
+#define NVIC_PRIGROUP_PRE0_SUB4 ((uint32_t)0x00000700) /*!< 0 bits for pre-emption priority 4 bits for subpriority */
+#define NVIC_PRIGROUP_PRE1_SUB3 ((uint32_t)0x00000600) /*!< 1 bits for pre-emption priority 3 bits for subpriority */
+#define NVIC_PRIGROUP_PRE2_SUB2 ((uint32_t)0x00000500) /*!< 2 bits for pre-emption priority 2 bits for subpriority */
+#define NVIC_PRIGROUP_PRE3_SUB1 ((uint32_t)0x00000400) /*!< 3 bits for pre-emption priority 1 bits for subpriority */
+#define NVIC_PRIGROUP_PRE4_SUB0 ((uint32_t)0x00000300) /*!< 4 bits for pre-emption priority 0 bits for subpriority */
+
+/* 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 */
+/* set the priority group */
+void nvic_priority_group_set(uint32_t nvic_prigroup);
+
+/* enable NVIC request */
+void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority);
+/* disable NVIC request */
+void nvic_irq_disable(uint8_t nvic_irq);
+
+/* 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 /* GD32F3X0_MISC_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_pmu.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_pmu.h
new file mode 100644
index 0000000000000000000000000000000000000000..230180bf9c5020f29de8579a484abbcd8fc2f3b8
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_pmu.h
@@ -0,0 +1,197 @@
+/*!
+ \file gd32f3x0_pmu.h
+ \brief definitions for the PMU
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_PMU_H
+#define GD32F3X0_PMU_H
+
+#include "gd32f3x0.h"
+
+/* PMU definitions */
+#define PMU PMU_BASE /*!< PMU base address */
+
+/* registers definitions */
+#define PMU_CTL REG32(PMU + 0x00000000U) /*!< PMU control register */
+#define PMU_CS REG32(PMU + 0x00000004U) /*!< 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_LDLP BIT(10) /*!< low-driver mode when use low power LDO */
+#define PMU_CTL_LDNP BIT(11) /*!< low-driver mode when use normal power LDO */
+#define PMU_CTL_LDOVS BITS(14,15) /*!< LDO output voltage select */
+#define PMU_CTL_HDEN BIT(16) /*!< high-driver mode enable */
+#define PMU_CTL_HDS BIT(17) /*!< high-driver mode switch */
+#define PMU_CTL_LDEN BITS(18,19) /*!< low-driver mode enable in deep-sleep mode */
+
+/* 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_WUPEN4 BIT(12) /*!< wakeup pin enable */
+#define PMU_CS_WUPEN5 BIT(13) /*!< wakeup pin enable */
+#define PMU_CS_WUPEN6 BIT(14) /*!< wakeup pin enable */
+#define PMU_CS_LDOVSRF BIT(15) /*!< LDO voltage select ready flag */
+#define PMU_CS_HDRF BIT(16) /*!< high-driver ready flag */
+#define PMU_CS_HDSRF BIT(17) /*!< high-driver switch ready flag */
+#define PMU_CS_LDRF BITS(18,19) /*!< low-driver mode ready flag */
+
+/* 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_LOW CTL_LDOVS(1) /*!< LDO output voltage low mode */
+#define PMU_LDOVS_MID CTL_LDOVS(2) /*!< LDO output voltage mid mode */
+#define PMU_LDOVS_HIGH CTL_LDOVS(3) /*!< LDO output voltage high mode */
+
+/* PMU low-driver mode enable in deep-sleep mode */
+#define CTL_LDEN(regval) (BITS(18,19)&((uint32_t)(regval)<<18))
+#define PMU_LOWDRIVER_DISABLE CTL_LDEN(0) /*!< low-driver mode disable in deep-sleep mode */
+#define PMU_LOWDRIVER_ENABLE CTL_LDEN(3) /*!< low-driver mode enable in deep-sleep mode */
+
+/* PMU high-driver mode switch */
+#define PMU_HIGHDR_SWITCH_NONE ((uint32_t)0x00000000U) /*!< no high-driver mode switch */
+#define PMU_HIGHDR_SWITCH_EN PMU_CTL_HDS /*!< high-driver mode switch */
+
+/* PMU low-driver mode when use normal power LDO */
+#define PMU_NORMALDR_NORMALPWR ((uint32_t)0x00000000U) /*!< normal-driver when use normal power LDO */
+#define PMU_LOWDR_NORMALPWR PMU_CTL_LDNP /*!< low-driver mode enabled when LDEN is 11 and use normal power LDO */
+
+/* PMU low-driver mode when use low power LDO */
+#define PMU_NORMALDR_LOWPWR ((uint32_t)0x00000000U) /*!< normal-driver when use low power LDO */
+#define PMU_LOWDR_LOWPWR PMU_CTL_LDLP /*!< low-driver mode enabled when LDEN is 11 and use low power LDO */
+
+/* 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 low power mode ready flag definitions */
+#define CS_LDRF(regval) (BITS(18,19)&((uint32_t)(regval)<<18))
+#define PMU_LDRF_NORMAL CS_LDRF(0) /*!< normal-driver in deep-sleep mode */
+#define PMU_LDRF_LOWDRIVER CS_LDRF(3) /*!< low-driver mode in deep-sleep 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 */
+#define PMU_FLAG_LDOVSR PMU_CS_LDOVSRF /*!< LDO voltage select ready flag */
+#define PMU_FLAG_HDR PMU_CS_HDRF /*!< high-driver ready flag */
+#define PMU_FLAG_HDSR PMU_CS_HDSRF /*!< high-driver switch ready flag */
+#define PMU_FLAG_LDR PMU_CS_LDRF /*!< low-driver mode ready flag */
+
+/* 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_PIN4 PMU_CS_WUPEN4 /*!< WKUP Pin 4 (PC5) 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 */
+/* function configuration */
+/* 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);
+
+/* functions of low-driver mode and high-driver mode in deep-sleep mode */
+/* enable low-driver mode in deep-sleep mode */
+void pmu_lowdriver_mode_enable(void);
+/* disable low-driver mode in deep-sleep mode */
+void pmu_lowdriver_mode_disable(void);
+/* enable high-driver mode */
+void pmu_highdriver_mode_enable(void);
+/* disable high-driver mode */
+void pmu_highdriver_mode_disable(void);
+/* switch high-driver mode */
+void pmu_highdriver_switch_select(uint32_t highdr_switch);
+/* in deep-sleep mode, low-driver mode when use low power LDO */
+void pmu_lowpower_driver_config(uint32_t mode);
+/* in deep-sleep mode, low-driver mode when use normal power LDO */
+void pmu_normalpower_driver_config(uint32_t mode);
+
+/* 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 /* GD32F3X0_PMU_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_rcu.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_rcu.h
new file mode 100644
index 0000000000000000000000000000000000000000..b870b69db173fd1b4da343977a88d7a3da5cdfe3
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_rcu.h
@@ -0,0 +1,797 @@
+/*!
+ \file gd32f3x0_rcu.h
+ \brief definitions for the RCU
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_RCU_H
+#define GD32F3X0_RCU_H
+
+#include "gd32f3x0.h"
+
+/* RCU definitions */
+#define RCU RCU_BASE
+
+/* registers definitions */
+#define RCU_CTL0 REG32(RCU + 0x00000000U) /*!< control register 0 */
+#define RCU_CFG0 REG32(RCU + 0x00000004U) /*!< configuration register 0 */
+#define RCU_INT REG32(RCU + 0x00000008U) /*!< interrupt register */
+#define RCU_APB2RST REG32(RCU + 0x0000000CU) /*!< APB2 reset register */
+#define RCU_APB1RST REG32(RCU + 0x00000010U) /*!< APB1 reset register */
+#define RCU_AHBEN REG32(RCU + 0x00000014U) /*!< AHB enable register */
+#define RCU_APB2EN REG32(RCU + 0x00000018U) /*!< APB2 enable register */
+#define RCU_APB1EN REG32(RCU + 0x0000001CU) /*!< APB1 enable register */
+#define RCU_BDCTL REG32(RCU + 0x00000020U) /*!< backup domain control register */
+#define RCU_RSTSCK REG32(RCU + 0x00000024U) /*!< reset source /clock register */
+#define RCU_AHBRST REG32(RCU + 0x00000028U) /*!< AHB reset register */
+#define RCU_CFG1 REG32(RCU + 0x0000002CU) /*!< configuration register 1 */
+#define RCU_CFG2 REG32(RCU + 0x00000030U) /*!< configuration register 2 */
+#define RCU_CTL1 REG32(RCU + 0x00000034U) /*!< control register 1 */
+#define RCU_ADDCTL REG32(RCU + 0x000000C0U) /*!< additional clock control register */
+#define RCU_ADDINT REG32(RCU + 0x000000CCU) /*!< additional clock interrupt register */
+#define RCU_ADDAPB1EN REG32(RCU + 0x000000F8U) /*!< APB1 additional enable register */
+#define RCU_ADDAPB1RST REG32(RCU + 0x000000FCU) /*!< APB1 additional reset register */
+#define RCU_VKEY REG32(RCU + 0x00000100U) /*!< voltage key register */
+#define RCU_DSV REG32(RCU + 0x00000134U) /*!< 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_USBFSPSC BITS(22,23) /*!< USBFS clock prescaler selection */
+#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_TIMER1RST BIT(0) /*!< TIMER1 timer reset */
+#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 */
+#define RCU_APB1RST_DACRST BIT(29) /*!< DAC reset */
+#define RCU_APB1RST_CECRST BIT(30) /*!< HDMI CEC 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_USBFS BIT(12) /*!< USBFS 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_PDEN BIT(20) /*!< GPIO port D clock enable */
+#define RCU_AHBEN_PFEN BIT(22) /*!< GPIO port F clock enable */
+#define RCU_AHBEN_TSIEN BIT(24) /*!< TSI 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 */
+
+/* RCU_APB1EN */
+#define RCU_APB1EN_TIMER1EN BIT(0) /*!< TIMER1 timer clock enable */
+#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 */
+#define RCU_APB1EN_DACEN BIT(29) /*!< DAC interface clock enable */
+#define RCU_APB1EN_CECEN BIT(30) /*!< HDMI CEC 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_USBFSRST BIT(12) /*!< USBFS reset */
+#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_PDRST BIT(20) /*!< GPIO port D reset */
+#define RCU_AHBRST_PFRST BIT(22) /*!< GPIO port F reset */
+#define RCU_AHBRST_TSIRST BIT(24) /*!< TSI unit reset */
+
+/* RCU_CFG1 */
+#define RCU_CFG1_PREDV BITS(0,3) /*!< CK_HXTAL divider previous PLL */
+#define RCU_CFG1_PLLPRESEL BIT(30) /*!< PLL clock source preselection */
+#define RCU_CFG1_PLLMF5 BIT(31) /*!< bit 5 of PLLMF */
+
+/* RCU_CFG2 */
+#define RCU_CFG2_USART0SEL BITS(0,1) /*!< CK_USART0 clock source selection */
+#define RCU_CFG2_CECSEL BIT(6) /*!< CK_CEC 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_USBFSPSC2 BIT(30) /*!< bit 2 of USBFSPSC */
+#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_ADDCTL */
+#define RCU_ADDCTL_CK48MSEL BIT(0) /*!< 48M clock selection */
+#define RCU_ADDCTL_IRC48MEN BIT(16) /*!< IRC48M internal 48M RC oscillator enable */
+#define RCU_ADDCTL_IRC48MSTB BIT(17) /*!< internal 48M RC oscillator stabilization flag */
+#define RCU_ADDCTL_IRC48MCALIB BITS(24,31) /*!< internal 48M RC oscillator calibration value register */
+
+/* RCU_ADDINT */
+#define RCU_ADDINT_IRC48MSTBIF BIT(6) /*!< IRC48M stabilization interrupt flag */
+#define RCU_ADDINT_IRC48MSTBIE BIT(14) /*!< IRC48M stabilization interrupt enable */
+#define RCU_ADDINT_IRC48MSTBIC BIT(22) /*!< IRC48M stabilization interrupt clear */
+
+/* RCU_ADDAPB1EN */
+#define RCU_ADDAPB1EN_CTCEN BIT(27) /*!< CTC unit clock enable */
+
+/* RCU_ADDAPB1RST */
+#define RCU_ADDAPB1RST_CTCRST BIT(27) /*!< CTC unit reset */
+
+/* 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) & (uint32_t)0x0000001FU)
+/* define the voltage key unlock value */
+#define RCU_VKEY_UNLOCK ((uint32_t)0x1A2B3C4DU)
+
+/* register index */
+typedef enum
+{
+ /* peripherals enable */
+ IDX_AHBEN = ((uint32_t)0x00000014U),
+ IDX_APB2EN = ((uint32_t)0x00000018U),
+ IDX_APB1EN = ((uint32_t)0x0000001CU),
+ IDX_ADDAPB1EN = ((uint32_t)0x000000F8U),
+ /* peripherals reset */
+ IDX_AHBRST = ((uint32_t)0x00000028U),
+ IDX_APB2RST = ((uint32_t)0x0000000CU),
+ IDX_APB1RST = ((uint32_t)0x00000010U),
+ IDX_ADDAPB1RST = ((uint32_t)0x000000FCU),
+ /* clock stabilization */
+ IDX_CTL0 = ((uint32_t)0x00000000U),
+ IDX_BDCTL = ((uint32_t)0x00000020U),
+ IDX_CTL1 = ((uint32_t)0x00000034U),
+ IDX_ADDCTL = ((uint32_t)0x000000C0U),
+ /* peripheral reset */
+ IDX_RSTSCK = ((uint32_t)0x00000024U),
+ /* clock stabilization and stuck interrupt */
+ IDX_INT = ((uint32_t)0x00000008U),
+ IDX_ADDINT = ((uint32_t)0x000000CCU),
+ /* configuration register */
+ IDX_CFG0 = ((uint32_t)0x00000004U),
+ IDX_CFG2 = ((uint32_t)0x00000030U)
+}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_GPIOD = RCU_REGIDX_BIT(IDX_AHBEN, 20U), /*!< GPIOD clock */
+ RCU_GPIOF = RCU_REGIDX_BIT(IDX_AHBEN, 22U), /*!< GPIOF clock */
+ RCU_TSI = RCU_REGIDX_BIT(IDX_AHBEN, 24U), /*!< TSI 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 */
+
+ /* APB1 peripherals */
+ RCU_TIMER1 = RCU_REGIDX_BIT(IDX_APB1EN, 0U), /*!< TIMER1 clock */
+ RCU_TIMER2 = RCU_REGIDX_BIT(IDX_APB1EN, 1U), /*!< TIMER2 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 */
+#if defined(GD32F350)
+ RCU_DAC = RCU_REGIDX_BIT(IDX_APB1EN, 29U), /*!< DAC clock */
+ RCU_CEC = RCU_REGIDX_BIT(IDX_APB1EN, 30U), /*!< CEC clock */
+ RCU_TIMER5 = RCU_REGIDX_BIT(IDX_APB1EN, 4U), /*!< TIMER5 clock */
+ RCU_USBFS = RCU_REGIDX_BIT(IDX_AHBEN, 12U), /*!< USBFS clock */
+#endif /* GD32F350 */
+ RCU_RTC = RCU_REGIDX_BIT(IDX_BDCTL, 15U), /*!< RTC clock */
+
+ /* RCU_ADDAPB1EN */
+ RCU_CTC = RCU_REGIDX_BIT(IDX_ADDAPB1EN, 27U) /*!< CTC 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_GPIODRST = RCU_REGIDX_BIT(IDX_AHBRST, 20U), /*!< GPIOD reset */
+ RCU_GPIOFRST = RCU_REGIDX_BIT(IDX_AHBRST, 22U), /*!< GPIOF reset */
+ RCU_TSIRST = RCU_REGIDX_BIT(IDX_AHBRST, 24U), /*!< TSI 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_TIMER1RST = RCU_REGIDX_BIT(IDX_APB1RST, 0U), /*!< TIMER1 reset */
+ RCU_TIMER2RST = RCU_REGIDX_BIT(IDX_APB1RST, 1U), /*!< TIMER2 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 */
+#if defined(GD32F350)
+ RCU_DACRST = RCU_REGIDX_BIT(IDX_APB1RST, 29U), /*!< DAC reset */
+ RCU_CECRST = RCU_REGIDX_BIT(IDX_APB1RST, 30U), /*!< CEC reset */
+ RCU_TIMER5RST = RCU_REGIDX_BIT(IDX_APB1RST, 4U), /*!< TIMER5 reset */
+ RCU_USBFSRST = RCU_REGIDX_BIT(IDX_AHBRST, 12U), /*!< USBFS reset */
+#endif /* GD32F350 */
+ /* RCU_ADDAPB1RST */
+ RCU_CTCRST = RCU_REGIDX_BIT(IDX_ADDAPB1RST, 27U), /*!< CTC 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_IRC48MSTB = RCU_REGIDX_BIT(IDX_ADDCTL, 17U), /*!< IRC48M 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_IRC48MSTB = RCU_REGIDX_BIT(IDX_ADDCTL, 6U) /*!< IRC48M stabilization 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_IRC48MSTB_CLR = RCU_REGIDX_BIT(IDX_ADDCTL, 22U) /*!< IRC48M stabilization interrupt flag 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_IRC48MSTB = RCU_REGIDX_BIT(IDX_ADDINT, 14U) /*!< IRC48M 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_IRC48M = RCU_REGIDX_BIT(IDX_ADDCTL, 16U), /*!< IRC48M */
+ 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_CEC, /*!< CEC 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_IRC48M RCU_CFG0_PLLSEL /*!< PLL clock source select HXTAL or IRC48M*/
+
+/* PLL clock source preselection */
+#define RCU_PLLPRESEL_HXTAL ((uint32_t)0x00000000U) /*!< PLL clock source preselection HXTAL */
+#define RCU_PLLPRESEL_IRC48M RCU_CFG1_PLLPRESEL /*!< PLL clock source preselection IRC48M */
+
+/* HXTAL or IRC48M divider for PLL source clock selection */
+#define RCU_PLLPREDV ((uint32_t)0x00000000U) /*!< HXTAL or IRC48M clock selected */
+#define RCU_PLLPREDV_DIV2 RCU_CFG0_PLLPREDV /*!< (HXTAL or IRC48M) /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 */
+#define RCU_PLL_MUL33 (CFG0_PLLMF(0) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 33 */
+#define RCU_PLL_MUL34 (CFG0_PLLMF(1) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 34 */
+#define RCU_PLL_MUL35 (CFG0_PLLMF(2) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 35 */
+#define RCU_PLL_MUL36 (CFG0_PLLMF(3) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 36 */
+#define RCU_PLL_MUL37 (CFG0_PLLMF(4) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 37 */
+#define RCU_PLL_MUL38 (CFG0_PLLMF(5) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 38 */
+#define RCU_PLL_MUL39 (CFG0_PLLMF(6) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 39 */
+#define RCU_PLL_MUL40 (CFG0_PLLMF(7) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 40 */
+#define RCU_PLL_MUL41 (CFG0_PLLMF(8) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 41 */
+#define RCU_PLL_MUL42 (CFG0_PLLMF(9) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 42 */
+#define RCU_PLL_MUL43 (CFG0_PLLMF(10) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 43 */
+#define RCU_PLL_MUL44 (CFG0_PLLMF(11) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 44 */
+#define RCU_PLL_MUL45 (CFG0_PLLMF(12) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 45 */
+#define RCU_PLL_MUL46 (CFG0_PLLMF(13) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 46 */
+#define RCU_PLL_MUL47 (CFG0_PLLMF(14) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 47 */
+#define RCU_PLL_MUL48 (CFG0_PLLMF(15) | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 48 */
+#define RCU_PLL_MUL49 (RCU_CFG0_PLLMF4 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 49 */
+#define RCU_PLL_MUL50 (RCU_PLL_MUL18 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 50 */
+#define RCU_PLL_MUL51 (RCU_PLL_MUL19 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 51 */
+#define RCU_PLL_MUL52 (RCU_PLL_MUL20 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 52 */
+#define RCU_PLL_MUL53 (RCU_PLL_MUL21 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 53 */
+#define RCU_PLL_MUL54 (RCU_PLL_MUL22 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 54 */
+#define RCU_PLL_MUL55 (RCU_PLL_MUL23 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 55 */
+#define RCU_PLL_MUL56 (RCU_PLL_MUL24 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 56 */
+#define RCU_PLL_MUL57 (RCU_PLL_MUL25 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 57 */
+#define RCU_PLL_MUL58 (RCU_PLL_MUL26 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 58 */
+#define RCU_PLL_MUL59 (RCU_PLL_MUL27 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 59 */
+#define RCU_PLL_MUL60 (RCU_PLL_MUL28 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 60 */
+#define RCU_PLL_MUL61 (RCU_PLL_MUL29 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 61 */
+#define RCU_PLL_MUL62 (RCU_PLL_MUL30 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 62 */
+#define RCU_PLL_MUL63 (RCU_PLL_MUL31 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 63 */
+#define RCU_PLL_MUL64 (RCU_PLL_MUL32 | RCU_CFG1_PLLMF5) /*!< PLL source clock multiply by 64 */
+
+/* USBFS clock prescaler selection */
+#define CFG0_USBFSPSC(regval) (BITS(22,23) & ((uint32_t)(regval) << 22))
+#define RCU_USBFS_CKPLL_DIV1_5 CFG0_USBFSPSC(0) /*!< USBFS clock prescaler select CK_PLL/1.5 */
+#define RCU_USBFS_CKPLL_DIV1 CFG0_USBFSPSC(1) /*!< USBFS clock prescaler select CK_PLL */
+#define RCU_USBFS_CKPLL_DIV2_5 CFG0_USBFSPSC(2) /*!< USBFS clock prescaler select CK_PLL/2.5 */
+#define RCU_USBFS_CKPLL_DIV2 CFG0_USBFSPSC(3) /*!< USBFS clock prescaler select CK_PLL/2 */
+#define RCU_USBFS_CKPLL_DIV3 RCU_CFG2_USBFSPSC2 /*!< USBFS clock prescaler select CK_PLL/3 */
+#define RCU_USBFS_CKPLL_DIV3_5 (CFG0_USBFSPSC(1)|RCU_CFG2_USBFSPSC2) /*!< USBFS clock prescaler select CK_PLL/3.5 */
+
+/* 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 */
+
+/* CEC clock source selection */
+#define RCU_CECSRC_IRC8M_DIV244 ((uint32_t)0x00000000U) /*!< CK_CEC clock source select IRC8M/244 */
+#define RCU_CECSRC_LXTAL RCU_CFG2_CECSEL /*!< CK_CEC clock source select LXTAL */
+
+/* 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 */
+
+/* CK48M clock source selection */
+#define RCU_CK48MSRC_PLL48M ((uint32_t)0x00000000U) /*!< CK48M source clock select PLL48M */
+#define RCU_CK48MSRC_IRC48M RCU_ADDCTL_CK48MSEL /*!< CK48M source clock select IRC48M */
+
+/* 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_0_7 DSV_DSLPVS(3) /*!< core voltage is 0.7V 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 USBFS prescaler selection */
+void rcu_usbfs_clock_config(uint32_t ck_usbfs);
+/* 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 preselection */
+void rcu_pll_preselection_config(uint32_t pll_presel);
+/* 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 CEC clock source selection */
+void rcu_cec_clock_config(uint32_t ck_cec);
+/* configure the RTC clock source selection */
+void rcu_rtc_clock_config(uint32_t rtc_clock_source);
+/* configure the CK48M clock selection */
+void rcu_ck48m_clock_config(uint32_t ck48m_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 /* GD32F3X0_RCU_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_rtc.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_rtc.h
new file mode 100644
index 0000000000000000000000000000000000000000..767d90992d17fb126e4621102ba8521f9738550a
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_rtc.h
@@ -0,0 +1,560 @@
+/*!
+ \file gd32f3x0_rtc.h
+ \brief definitions for the RTC
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_RTC_H
+#define GD32F3X0_RTC_H
+
+#include "gd32f3x0.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 /*!< enable alarm flag output with high level */
+#define RTC_ALARM_LOW RTC_CTL_OS_ENABLE | 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 /* GD32F3X0_RTC_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_spi.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_spi.h
new file mode 100644
index 0000000000000000000000000000000000000000..c24aad66a4461e2974034cffc7fd4e13a00f91ac
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_spi.h
@@ -0,0 +1,368 @@
+/*!
+ \file gd32f3x0_spi.h
+ \brief definitions for the SPI
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_SPI_H
+#define GD32F3X0_SPI_H
+
+#include "gd32f3x0.h"
+
+/* SPIx(x=0,1) definitions */
+#define SPI0 (SPI_BASE + 0x0000F800U)
+#define SPI1 SPI_BASE
+
+/* SPI registers definitions */
+#define SPI_CTL0(spix) REG32((spix) + 0x00000000U) /*!< SPI control register 0 */
+#define SPI_CTL1(spix) REG32((spix) + 0x00000004U) /*!< SPI control register 1*/
+#define SPI_STAT(spix) REG32((spix) + 0x00000008U) /*!< SPI status register */
+#define SPI_DATA(spix) REG32((spix) + 0x0000000CU) /*!< SPI data register */
+#define SPI_CRCPOLY(spix) REG32((spix) + 0x00000010U) /*!< SPI CRC polynomial register */
+#define SPI_RCRC(spix) REG32((spix) + 0x00000014U) /*!< SPI receive CRC register */
+#define SPI_TCRC(spix) REG32((spix) + 0x00000018U) /*!< SPI transmit CRC register */
+#define SPI_I2SCTL(spix) REG32((spix) + 0x0000001CU) /*!< SPI I2S control register */
+#define SPI_I2SPSC(spix) REG32((spix) + 0x00000020U) /*!< SPI I2S clock prescaler register */
+#define SPI_QCTL(spix) REG32((spix) + 0x00000080U) /*!< 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 */
+#define SPI_CTL0_FF16 BIT(11) /*!< data frame size */
+#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 */
+
+/* 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 */
+
+/* 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 */
+
+/* SPI_QCTL(only for SPI1) */
+#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 */
+/* SPI and I2S 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 frame size */
+#define SPI_FRAMESIZE_16BIT SPI_CTL0_FF16 /*!< SPI frame size is 16 bits */
+#define SPI_FRAMESIZE_8BIT ((uint32_t)0x00000000U) /*!< SPI frame size is 8 bits */
+
+/* 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 */
+
+#ifdef GD32F350
+/* 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 */
+#endif /* GD32F350 */
+
+/* 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 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 */
+
+#ifdef GD32F350
+/* I2S flag definitions */
+#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 */
+#endif /* GD32F350 */
+
+/* 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 */
+void 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);
+
+#ifdef GD32F350
+/* 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);
+#endif /* GD32F350 */
+
+/* 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 */
+void 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);
+
+#endif /* GD32F3X0_SPI_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_syscfg.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_syscfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..861d0bec8cf5b935f2398acaec41dbd4fe418142
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_syscfg.h
@@ -0,0 +1,190 @@
+/*!
+ \file gd32f3x0_syscfg.h
+ \brief definitions for the SYSCFG
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_SYSCFG_H
+#define GD32F3X0_SYSCFG_H
+
+#include "gd32f3x0.h"
+
+/* SYSCFG definitions */
+#define SYSCFG SYSCFG_BASE
+
+/* registers definitions */
+#define SYSCFG_CFG0 REG32(SYSCFG + 0x00000000U) /*!< system configuration register 0 */
+#define SYSCFG_EXTISS0 REG32(SYSCFG + 0x00000008U) /*!< EXTI sources selection register 0 */
+#define SYSCFG_EXTISS1 REG32(SYSCFG + 0x0000000CU) /*!< EXTI sources selection register 1 */
+#define SYSCFG_EXTISS2 REG32(SYSCFG + 0x00000010U) /*!< EXTI sources selection register 2 */
+#define SYSCFG_EXTISS3 REG32(SYSCFG + 0x00000014U) /*!< EXTI sources selection register 3 */
+#define SYSCFG_CFG2 REG32(SYSCFG + 0x00000018U) /*!< system configuration register 2 */
+#define SYSCFG_CPSCTL REG32(SYSCFG + 0x00000020U) /*!< system I/O compensation control register */
+
+/* SYSCFG_CFG0 bits definitions */
+#define SYSCFG_CFG0_BOOT_MODE BITS(0,1) /*!< SYSCFG memory remap config */
+#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-M4 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_CPSCTL bits definitions */
+#define SYSCFG_CPSCTL_CPS_EN BIT(0) /*!< I/O compensation cell enable */
+#define SYSCFG_CPSCTL_CPS_RDY BIT(8) /*!< I/O compensation cell is ready or not */
+
+/* constants definitions */
+/* DMA remap definitions */
+#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_GPIOD ((uint8_t)0x03U) /*!< EXTI GPIOD 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 */
+
+/* I/O compensation cell enable/disable */
+#define SYSCFG_COMPENSATION(regval) (BIT(0) & ((uint32_t)(regval) << 0))
+#define SYSCFG_COMPENSATION_DISABLE SYSCFG_COMPENSATION(0) /*!< I/O compensation cell is power-down */
+#define SYSCFG_COMPENSATION_ENABLE SYSCFG_COMPENSATION(1) /*!< I/O compensation cell is enabled */
+
+/* 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);
+
+/* 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);
+
+/* configure the I/O compensation cell */
+void syscfg_compensation_config(uint32_t syscfg_compensation);
+/* check if the I/O compensation cell ready flag is set or not */
+FlagStatus syscfg_cps_rdy_flag_get(void);
+
+#endif /* GD32F3X0_SYSCFG_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_timer.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_timer.h
new file mode 100644
index 0000000000000000000000000000000000000000..b9e3cb9ed6dbd9b871a221a159908729e925b3d2
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_timer.h
@@ -0,0 +1,768 @@
+/*!
+ \file gd32f3x0_timer.h
+ \brief definitions for the TIMER
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+
+ 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 GD32F3X0_TIMER_H
+#define GD32F3X0_TIMER_H
+
+#include "gd32f3x0.h"
+
+/* TIMERx(x=0,1,2,5,13..16) definitions */
+#define TIMER0 (TIMER_BASE + 0x00012C00U)
+#define TIMER1 (TIMER_BASE + 0x00000000U)
+#define TIMER2 (TIMER_BASE + 0x00000400U)
+#ifdef GD32F350
+#define TIMER5 (TIMER_BASE + 0x00001000U)
+#endif
+#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) + 0x00000000U) /*!< TIMER control register 0 */
+#define TIMER_CTL1(timerx) REG32((timerx) + 0x00000004U) /*!< TIMER control register 1 */
+#define TIMER_SMCFG(timerx) REG32((timerx) + 0x00000008U) /*!< TIMER slave mode configuration register */
+#define TIMER_DMAINTEN(timerx) REG32((timerx) + 0x0000000CU) /*!< TIMER DMA and interrupt enable register */
+#define TIMER_INTF(timerx) REG32((timerx) + 0x00000010U) /*!< TIMER interrupt flag register */
+#define TIMER_SWEVG(timerx) REG32((timerx) + 0x00000014U) /*!< TIMER software event generation register */
+#define TIMER_CHCTL0(timerx) REG32((timerx) + 0x00000018U) /*!< TIMER channel control register 0 */
+#define TIMER_CHCTL1(timerx) REG32((timerx) + 0x0000001CU) /*!< TIMER channel control register 1 */
+#define TIMER_CHCTL2(timerx) REG32((timerx) + 0x00000020U) /*!< TIMER channel control register 2 */
+#define TIMER_CNT(timerx) REG32((timerx) + 0x00000024U) /*!< TIMER counter register */
+#define TIMER_PSC(timerx) REG32((timerx) + 0x00000028U) /*!< TIMER prescaler register */
+#define TIMER_CAR(timerx) REG32((timerx) + 0x0000002CU) /*!< TIMER counter auto reload register */
+#define TIMER_CREP(timerx) REG32((timerx) + 0x00000030U) /*!< TIMER counter repetition register */
+#define TIMER_CH0CV(timerx) REG32((timerx) + 0x00000034U) /*!< TIMER channel 0 capture/compare value register */
+#define TIMER_CH1CV(timerx) REG32((timerx) + 0x00000038U) /*!< TIMER channel 1 capture/compare value register */
+#define TIMER_CH2CV(timerx) REG32((timerx) + 0x0000003CU) /*!< TIMER channel 2 capture/compare value register */
+#define TIMER_CH3CV(timerx) REG32((timerx) + 0x00000040U) /*!< TIMER channel 3 capture/compare value register */
+#define TIMER_CCHP(timerx) REG32((timerx) + 0x00000044U) /*!< TIMER complementary channel protection register */
+#define TIMER_DMACFG(timerx) REG32((timerx) + 0x00000048U) /*!< TIMER DMA configuration register */
+#define TIMER_DMATB(timerx) REG32((timerx) + 0x0000004CU) /*!< TIMER DMA transfer buffer register */
+#define TIMER_IRMP(timerx) REG32((timerx) + 0x00000050U) /*!< TIMER channel input remap register */
+#define TIMER_CFG(timerx) REG32((timerx) + 0x000000FCU) /*!< 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 */
+#define TIMER_CNT_CNT32 BITS(0,31) /*!< 32 bit(TIMER1) 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 */
+#define TIMER_CAR_CARL32 BITS(0,31) /*!< 32 bit(TIMER1) 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 */
+#define TIMER_CH0CV_CH0VAL32 BITS(0,31) /*!< 32 bit(TIMER1) capture/compare value of channel 0 */
+
+/* TIMER_CH1CV */
+#define TIMER_CH1CV_CH1VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 1 */
+#define TIMER_CH1CV_CH1VAL32 BITS(0,31) /*!< 32 bit(TIMER1) capture/compare value of channel 1 */
+
+/* TIMER_CH2CV */
+#define TIMER_CH2CV_CH2VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 2 */
+#define TIMER_CH2CV_CH2VAL32 BITS(0,31) /*!< 32 bit(TIMER1) capture/compare value of channel 2 */
+
+/* TIMER_CH3CV */
+#define TIMER_CH3CV_CH3VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 3 */
+#define TIMER_CH3CV_CH3VAL32 BITS(0,31) /*!< 32 bit(TIMER1) 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
+{
+ uint32_t runoffstate; /*!< run mode off-state */
+ uint32_t ideloffstate; /*!< idle mode off-state */
+ uint16_t deadtime; /*!< dead time */
+ uint16_t breakpolarity; /*!< break polarity */
+ uint32_t outputautostate; /*!< output automatic enable */
+ uint32_t protectmode; /*!< complementary register protect control */
+ uint32_t breakstate; /*!< break enable */
+}timer_break_parameter_struct;
+
+/* channel output parameter struct definitions */
+typedef struct
+{
+ uint32_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 ((uint8_t)0x00U) /*!< DMA request of channel y is sent when update event occurs */
+#define TIMER_DMAREQUEST_CHANNELEVENT ((uint8_t)0x01U) /*!< 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 */
+#define TIMER_DMACFG_DMATA_DMATB DMACFG_DMATA(19) /*!< DMA transfer address is TIMER_DMATB */
+
+/* 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 ((uint8_t)0x00U) /*!< the prescaler is loaded right now */
+#define TIMER_PSC_RELOAD_UPDATE ((uint8_t)0x01U) /*!< 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)0x0010U) /*!< 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 ((uint8_t)0x00U) /*!< single pulse mode */
+#define TIMER_SP_MODE_REPETITIVE ((uint8_t)0x01U) /*!< repetitive pulse mode */
+
+/* update source */
+#define TIMER_UPDATE_SRC_REGULAR ((uint8_t)0x00U) /*!< update generate only by counter overflow/underflow */
+#define TIMER_UPDATE_SRC_GLOBAL ((uint8_t)0x01U) /*!< 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 ((uint32_t)0x00000800U) /*!< 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 ((uint32_t)0x00000000U) /*!< 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)0x0400U) /*!< 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)0x2000U) /*!< break input polarity is high */
+
+/* output automatic enable */
+#define TIMER_OUTAUTO_ENABLE ((uint16_t)0x4000U) /*!< 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)0x1000U) /*!< 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)) */
+
+/* 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 ((uint8_t)0x00U) /*!< the shadow registers update by when CMTG bit is set */
+#define TIMER_UPDATECTL_CCUTRI ((uint8_t)0x01U) /*!< the shadow registers update by 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 */
+
+/* master slave mode selection */
+#define TIMER_MASTER_SLAVE_MODE_ENABLE ((uint8_t)0x00U) /*!< master slave mode enable */
+#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint8_t)0x01U) /*!< 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 ((uint8_t)0x00U) /*!< TIMER hall sensor mode enable */
+#define TIMER_HALLINTERFACE_DISABLE ((uint8_t)0x01U) /*!< TIMER hall sensor mode disable */
+
+/* timerx(x=0,1,2,13,14,15,16) write CHxVAL register selection */
+#define TIMER_CHVSEL_ENABLE ((uint16_t)0x0002U) /*!< write CHxVAL register selection enable */
+#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CHxVAL register selection disable */
+
+/* the output value selection */
+#define TIMER_OUTSEL_DISABLE ((uint16_t)0x0000U) /*!< output value selection disable */
+#define TIMER_OUTSEL_ENABLE ((uint16_t)0x0001U) /*!< 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, uint32_t autoreload);
+/* configure TIMER counter register value */
+void timer_counter_value_config(uint32_t timer_periph , uint32_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, uint8_t spmode);
+/* configure TIMER update source */
+void timer_update_source_config(uint32_t timer_periph, uint8_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, uint8_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, uint8_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 /* GD32F3X0_TIMER_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_tsi.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_tsi.h
new file mode 100644
index 0000000000000000000000000000000000000000..ec03a4bc8a247c2323b27aad93ff072d43d9de55
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_tsi.h
@@ -0,0 +1,396 @@
+/*!
+ \file gd32f3x0_tsi.h
+ \brief definitions for the TSI
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_TSI_H
+#define GD32F3X0_TSI_H
+
+#include "gd32f3x0.h"
+
+/* TSI definitions */
+#define TSI TSI_BASE /*!< TSI base address */
+
+/* registers definitions */
+#define TSI_CTL0 REG32(TSI + 0x00000000U)/*!< TSI control register0 */
+#define TSI_INTEN REG32(TSI + 0x00000004U)/*!< TSI interrupt enable register */
+#define TSI_INTC REG32(TSI + 0x00000008U)/*!< TSI interrupt flag clear register */
+#define TSI_INTF REG32(TSI + 0x0000000CU)/*!< TSI interrupt flag register */
+#define TSI_PHM REG32(TSI + 0x00000010U)/*!< TSI pin hysteresis mode register */
+#define TSI_ASW REG32(TSI + 0x00000018U)/*!< TSI analog switch register */
+#define TSI_SAMPCFG REG32(TSI + 0x00000020U)/*!< TSI sample configuration register */
+#define TSI_CHCFG REG32(TSI + 0x00000028U)/*!< TSI channel configuration register */
+#define TSI_GCTL REG32(TSI + 0x00000030U)/*!< TSI group control register */
+#define TSI_G0CYCN REG32(TSI + 0x00000034U)/*!< TSI group 0 cycle number register */
+#define TSI_G1CYCN REG32(TSI + 0x00000038U)/*!< TSI group 1 cycle number register */
+#define TSI_G2CYCN REG32(TSI + 0x0000003CU)/*!< TSI group 2 cycle number register */
+#define TSI_G3CYCN REG32(TSI + 0x00000040U)/*!< TSI group 3 cycle number register */
+#define TSI_G4CYCN REG32(TSI + 0x00000044U)/*!< TSI group 4 cycle number register */
+#define TSI_G5CYCN REG32(TSI + 0x00000048U)/*!< TSI group 5 cycle number register */
+#define TSI_CTL1 REG32(TSI + 0x00000300U)/*!< TSI control registers1 */
+
+/* bits definitions */
+/* TSI_CTL0 */
+#define TSI_CTL0_TSIEN BIT(0) /*!< TSI enable */
+#define TSI_CTL0_TSIS BIT(1) /*!< TSI start */
+#define TSI_CTL0_TRGMOD BIT(2) /*!< trigger mode selection */
+#define TSI_CTL0_EGSEL BIT(3) /*!< edge selection */
+#define TSI_CTL0_PINMOD BIT(4) /*!< pin mode */
+#define TSI_CTL0_MCN BITS(5,7) /*!< max cycle number of a sequence */
+#define TSI_CTL0_CTCDIV BITS(12,14) /*!< CTCLK clock division factor */
+#define TSI_CTL0_ECDIV BIT(15) /*!< ECCLK clock division factor */
+#define TSI_CTL0_ECEN BIT(16) /*!< extend charge state enable */
+#define TSI_CTL0_ECDT BITS(17,23) /*!< extend charge State maximum duration time */
+#define TSI_CTL0_CTDT BITS(24,27) /*!< charge transfer state duration time */
+#define TSI_CTL0_CDT BITS(28,31) /*!< charge state duration time */
+
+/* TSI_INTEN */
+#define TSI_INTEN_CTCFIE BIT(0) /*!< charge transfer complete flag interrupt enable */
+#define TSI_INTEN_MNERRIE BIT(1) /*!< max cycle number error interrupt enable */
+
+/* TSI_INTC */
+#define TSI_INTC_CCTCF BIT(0) /*!< clear charge transfer complete flag */
+#define TSI_INTC_CMNERR BIT(1) /*!< clear max cycle number error */
+
+/* TSI_INTF */
+#define TSI_INTF_CTCF BIT(0) /*!< charge transfer complete flag */
+#define TSI_INTF_MNERR BIT(1) /*!< max cycle number error */
+
+/* TSI_PHM */
+#define TSI_PHM_G0P0 BIT(0) /*!< pin G0P0 Schmitt trigger hysteresis state */
+#define TSI_PHM_G0P1 BIT(1) /*!< pin G0P1 Schmitt trigger hysteresis state */
+#define TSI_PHM_G0P2 BIT(2) /*!< pin G0P2 Schmitt trigger hysteresis state */
+#define TSI_PHM_G0P3 BIT(3) /*!< pin G0P3 Schmitt trigger hysteresis state */
+#define TSI_PHM_G1P0 BIT(4) /*!< pin G1P0 Schmitt trigger hysteresis state */
+#define TSI_PHM_G1P1 BIT(5) /*!< pin G1P1 Schmitt trigger hysteresis state */
+#define TSI_PHM_G1P2 BIT(6) /*!< pin G1P2 Schmitt trigger hysteresis state */
+#define TSI_PHM_G1P3 BIT(7) /*!< pin G1P3 Schmitt trigger hysteresis state */
+#define TSI_PHM_G2P0 BIT(8) /*!< pin G2P0 Schmitt trigger hysteresis state */
+#define TSI_PHM_G2P1 BIT(9) /*!< pin G2P1 Schmitt trigger hysteresis state */
+#define TSI_PHM_G2P2 BIT(10) /*!< pin G2P2 Schmitt trigger hysteresis state */
+#define TSI_PHM_G2P3 BIT(11) /*!< pin G2P3 Schmitt trigger hysteresis state */
+#define TSI_PHM_G3P0 BIT(12) /*!< pin G3P0 Schmitt trigger hysteresis state */
+#define TSI_PHM_G3P1 BIT(13) /*!< pin G3P1 Schmitt trigger hysteresis state */
+#define TSI_PHM_G3P2 BIT(14) /*!< pin G3P2 Schmitt trigger hysteresis state */
+#define TSI_PHM_G3P3 BIT(15) /*!< pin G3P3 Schmitt trigger hysteresis state */
+#define TSI_PHM_G4P0 BIT(16) /*!< pin G4P0 Schmitt trigger hysteresis state */
+#define TSI_PHM_G4P1 BIT(17) /*!< pin G4P1 Schmitt trigger hysteresis state */
+#define TSI_PHM_G4P2 BIT(18) /*!< pin G4P2 Schmitt trigger hysteresis state */
+#define TSI_PHM_G4P3 BIT(19) /*!< pin G4P3 Schmitt trigger hysteresis state */
+#define TSI_PHM_G5P0 BIT(20) /*!< pin G5P0 Schmitt trigger hysteresis state */
+#define TSI_PHM_G5P1 BIT(21) /*!< pin G5P1 Schmitt trigger hysteresis state */
+#define TSI_PHM_G5P2 BIT(22) /*!< pin G5P2 Schmitt trigger hysteresis state */
+#define TSI_PHM_G5P3 BIT(23) /*!< pin G5P3 Schmitt trigger hysteresis state */
+
+/* TSI_ASW */
+#define TSI_ASW_G0P0 BIT(0) /*!< pin G0P0 analog switch state */
+#define TSI_ASW_G0P1 BIT(1) /*!< pin G0P1 analog switch state */
+#define TSI_ASW_G0P2 BIT(2) /*!< pin G0P2 analog switch state */
+#define TSI_ASW_G0P3 BIT(3) /*!< pin G0P3 analog switch state */
+#define TSI_ASW_G1P0 BIT(4) /*!< pin G1P0 analog switch state */
+#define TSI_ASW_G1P1 BIT(5) /*!< pin G1P1 analog switch state */
+#define TSI_ASW_G1P2 BIT(6) /*!< pin G1P2 analog switch state */
+#define TSI_ASW_G1P3 BIT(7) /*!< pin G1P3 analog switch state */
+#define TSI_ASW_G2P0 BIT(8) /*!< pin G2P0 analog switch state */
+#define TSI_ASW_G2P1 BIT(9) /*!< pin G2P1 analog switch state */
+#define TSI_ASW_G2P2 BIT(10) /*!< pin G2P2 analog switch state */
+#define TSI_ASW_G2P3 BIT(11) /*!< pin G2P3 analog switch state */
+#define TSI_ASW_G3P0 BIT(12) /*!< pin G3P0 analog switch state */
+#define TSI_ASW_G3P1 BIT(13) /*!< pin G3P1 analog switch state */
+#define TSI_ASW_G3P2 BIT(14) /*!< pin G3P2 analog switch state */
+#define TSI_ASW_G3P3 BIT(15) /*!< pin G3P3 analog switch state */
+#define TSI_ASW_G4P0 BIT(16) /*!< pin G4P0 analog switch state */
+#define TSI_ASW_G4P1 BIT(17) /*!< pin G4P1 analog switch state */
+#define TSI_ASW_G4P2 BIT(18) /*!< pin G4P2 analog switch state */
+#define TSI_ASW_G4P3 BIT(19) /*!< pin G4P3 analog switch state */
+#define TSI_ASW_G5P0 BIT(20) /*!< pin G5P0 analog switch state */
+#define TSI_ASW_G5P1 BIT(21) /*!< pin G5P1 analog switch state */
+#define TSI_ASW_G5P2 BIT(22) /*!< pin G5P2 analog switch state */
+#define TSI_ASW_G5P3 BIT(23) /*!< pin G5P3 analog switch state */
+
+/* TSI_SAMPCFG */
+#define TSI_SAMPCFG_G0P0 BIT(0) /*!< pin G0P0 sample pin mode */
+#define TSI_SAMPCFG_G0P1 BIT(1) /*!< pin G0P1 sample pin mode */
+#define TSI_SAMPCFG_G0P2 BIT(2) /*!< pin G0P2 sample pin mode */
+#define TSI_SAMPCFG_G0P3 BIT(3) /*!< pin G0P3 sample pin mode */
+#define TSI_SAMPCFG_G1P0 BIT(4) /*!< pin G1P0 sample pin mode */
+#define TSI_SAMPCFG_G1P1 BIT(5) /*!< pin G1P1 sample pin mode */
+#define TSI_SAMPCFG_G1P2 BIT(6) /*!< pin G1P2 sample pin mode */
+#define TSI_SAMPCFG_G1P3 BIT(7) /*!< pin G1P3 sample pin mode */
+#define TSI_SAMPCFG_G2P0 BIT(8) /*!< pin G2P0 sample pin mode */
+#define TSI_SAMPCFG_G2P1 BIT(9) /*!< pin G2P1 sample pin mode */
+#define TSI_SAMPCFG_G2P2 BIT(10) /*!< pin G2P2 sample pin mode */
+#define TSI_SAMPCFG_G2P3 BIT(11) /*!< pin G2P3 sample pin mode */
+#define TSI_SAMPCFG_G3P0 BIT(12) /*!< pin G3P0 sample pin mode */
+#define TSI_SAMPCFG_G3P1 BIT(13) /*!< pin G3P1 sample pin mode */
+#define TSI_SAMPCFG_G3P2 BIT(14) /*!< pin G3P2 sample pin mode */
+#define TSI_SAMPCFG_G3P3 BIT(15) /*!< pin G3P3 sample pin mode */
+#define TSI_SAMPCFG_G4P0 BIT(16) /*!< pin G4P0 sample pin mode */
+#define TSI_SAMPCFG_G4P1 BIT(17) /*!< pin G4P1 sample pin mode */
+#define TSI_SAMPCFG_G4P2 BIT(18) /*!< pin G4P2 sample pin mode */
+#define TSI_SAMPCFG_G4P3 BIT(19) /*!< pin G4P3 sample pin mode */
+#define TSI_SAMPCFG_G5P0 BIT(20) /*!< pin G5P0 sample pin mode */
+#define TSI_SAMPCFG_G5P1 BIT(21) /*!< pin G5P1 sample pin mode */
+#define TSI_SAMPCFG_G5P2 BIT(22) /*!< pin G5P2 sample pin mode */
+#define TSI_SAMPCFG_G5P3 BIT(23) /*!< pin G5P3 sample pin mode */
+
+/* TSI_CHCFG */
+#define TSI_CHCFG_G0P0 BIT(0) /*!< pin G0P0 channel pin mode */
+#define TSI_CHCFG_G0P1 BIT(1) /*!< pin G0P1 channel pin mode */
+#define TSI_CHCFG_G0P2 BIT(2) /*!< pin G0P2 channel pin mode */
+#define TSI_CHCFG_G0P3 BIT(3) /*!< pin G0P3 channel pin mode */
+#define TSI_CHCFG_G1P0 BIT(4) /*!< pin G1P0 channel pin mode */
+#define TSI_CHCFG_G1P1 BIT(5) /*!< pin G1P1 channel pin mode */
+#define TSI_CHCFG_G1P2 BIT(6) /*!< pin G1P2 channel pin mode */
+#define TSI_CHCFG_G1P3 BIT(7) /*!< pin G1P3 channel pin mode */
+#define TSI_CHCFG_G2P0 BIT(8) /*!< pin G2P0 channel pin mode */
+#define TSI_CHCFG_G2P1 BIT(9) /*!< pin G2P1 channel pin mode */
+#define TSI_CHCFG_G2P2 BIT(10) /*!< pin G2P2 channel pin mode */
+#define TSI_CHCFG_G2P3 BIT(11) /*!< pin G2P3 channel pin mode */
+#define TSI_CHCFG_G3P0 BIT(12) /*!< pin G3P0 channel pin mode */
+#define TSI_CHCFG_G3P1 BIT(13) /*!< pin G3P1 channel pin mode */
+#define TSI_CHCFG_G3P2 BIT(14) /*!< pin G3P2 channel pin mode */
+#define TSI_CHCFG_G3P3 BIT(15) /*!< pin G3P3 channel pin mode */
+#define TSI_CHCFG_G4P0 BIT(16) /*!< pin G4P0 channel pin mode */
+#define TSI_CHCFG_G4P1 BIT(17) /*!< pin G4P1 channel pin mode */
+#define TSI_CHCFG_G4P2 BIT(18) /*!< pin G4P2 channel pin mode */
+#define TSI_CHCFG_G4P3 BIT(19) /*!< pin G4P3 channel pin mode */
+#define TSI_CHCFG_G5P0 BIT(20) /*!< pin G5P0 channel pin mode */
+#define TSI_CHCFG_G5P1 BIT(21) /*!< pin G5P1 channel pin mode */
+#define TSI_CHCFG_G5P2 BIT(22) /*!< pin G5P2 channel pin mode */
+#define TSI_CHCFG_G5P3 BIT(23) /*!< pin G5P3 channel pin mode */
+
+/* TSI_GCTL */
+#define TSI_GCTL_GE0 BIT(0) /*!< group0 enable */
+#define TSI_GCTL_GE1 BIT(1) /*!< group1 enable */
+#define TSI_GCTL_GE2 BIT(2) /*!< group2 enable */
+#define TSI_GCTL_GE3 BIT(3) /*!< group3 enable */
+#define TSI_GCTL_GE4 BIT(4) /*!< group4 enable */
+#define TSI_GCTL_GE5 BIT(5) /*!< group5 enable */
+#define TSI_GCTL_GC0 BIT(16) /*!< group0 complete */
+#define TSI_GCTL_GC1 BIT(17) /*!< group1 complete */
+#define TSI_GCTL_GC2 BIT(18) /*!< group2 complete */
+#define TSI_GCTL_GC3 BIT(19) /*!< group3 complete */
+#define TSI_GCTL_GC4 BIT(20) /*!< group4 complete */
+#define TSI_GCTL_GC5 BIT(21) /*!< group5 complete */
+
+/* TSI_CTL1 */
+#define TSI_CTL1_CTCDIV BIT(24) /*!< CTCLK clock division factor */
+#define TSI_CTL1_ECDIV BITS(28,29) /*!< ECCLK clock division factor */
+
+/* constants definitions */
+/* TSI interrupt enable bit */
+#define TSI_INT_CCTCF TSI_INTEN_CTCFIE /*!< charge transfer complete flag interrupt enable */
+#define TSI_INT_MNERR TSI_INTEN_MNERRIE /*!< max cycle number error interrupt enable */
+
+/* I2C interrupt flags */
+#define TSI_INT_FLAG_CTCF TSI_INTF_CTCF /*!< charge transfer complete flag */
+#define TSI_INT_FLAG_MNERR TSI_INTF_MNERR /*!< max cycle number error */
+
+/* I2C interrupt clear flags */
+#define TSI_INT_FLAG_CTCF_CLR TSI_INTC_CCTCF /*!< clear charge transfer complete flag */
+#define TSI_INT_FLAG_MNERR_CLR TSI_INTC_CMNERR /*!< clear max cycle number error */
+
+/* I2C flags */
+#define TSI_FLAG_CTCF TSI_INTF_CTCF /*!< charge transfer complete flag */
+#define TSI_FLAG_MNERR TSI_INTF_MNERR /*!< max cycle number error */
+
+/* I2C clear flags */
+#define TSI_FLAG_CTCF_CLR TSI_INTC_CCTCF /*!< clear charge transfer complete flag */
+#define TSI_FLAG_MNERR_CLR TSI_INTC_CMNERR /*!< clear max cycle number error */
+
+/* CTCLK clock division factor */
+#define TSI_CTCDIV_DIV1 ((uint32_t)0x00000000U) /*!< fCTCLK = fHCLK */
+#define TSI_CTCDIV_DIV2 ((uint32_t)0x00000001U) /*!< fCTCLK = fHCLK/2 */
+#define TSI_CTCDIV_DIV4 ((uint32_t)0x00000002U) /*!< fCTCLK = fHCLK/4 */
+#define TSI_CTCDIV_DIV8 ((uint32_t)0x00000003U) /*!< fCTCLK = fHCLK/8 */
+#define TSI_CTCDIV_DIV16 ((uint32_t)0x00000004U) /*!< fCTCLK = fHCLK/16 */
+#define TSI_CTCDIV_DIV32 ((uint32_t)0x00000005U) /*!< fCTCLK = fHCLK/32 */
+#define TSI_CTCDIV_DIV64 ((uint32_t)0x00000006U) /*!< fCTCLK = fHCLK/64 */
+#define TSI_CTCDIV_DIV128 ((uint32_t)0x00000007U) /*!< fCTCLK = fHCLK/128 */
+#define TSI_CTCDIV_DIV256 ((uint32_t)0x00000008U) /*!< fCTCLK = fHCLK/256 */
+#define TSI_CTCDIV_DIV512 ((uint32_t)0x00000009U) /*!< fCTCLK = fHCLK/512 */
+#define TSI_CTCDIV_DIV1024 ((uint32_t)0x0000000AU) /*!< fCTCLK = fHCLK/1024 */
+#define TSI_CTCDIV_DIV2048 ((uint32_t)0x0000000BU) /*!< fCTCLK = fHCLK/2048 */
+#define TSI_CTCDIV_DIV4096 ((uint32_t)0x0000000CU) /*!< fCTCLK = fHCLK/4096 */
+#define TSI_CTCDIV_DIV8192 ((uint32_t)0x0000000DU) /*!< fCTCLK = fHCLK/8192 */
+#define TSI_CTCDIV_DIV16384 ((uint32_t)0x0000000EU) /*!< fCTCLK = fHCLK/16384 */
+#define TSI_CTCDIV_DIV32768 ((uint32_t)0x0000000FU) /*!< fCTCLK = fHCLK/32768 */
+
+/* charge transfer state duration Time */
+#define CTL_CTDT(regval) (BITS(24,27) & ((uint32_t)(regval) << 24U))
+#define TSI_TRANSFER_1CTCLK CTL_CTDT(0) /*!< the duration time of transfer state is 1 CTCLK */
+#define TSI_TRANSFER_2CTCLK CTL_CTDT(1) /*!< the duration time of transfer state is 2 CTCLK */
+#define TSI_TRANSFER_3CTCLK CTL_CTDT(2) /*!< the duration time of transfer state is 3 CTCLK */
+#define TSI_TRANSFER_4CTCLK CTL_CTDT(3) /*!< the duration time of transfer state is 4 CTCLK */
+#define TSI_TRANSFER_5CTCLK CTL_CTDT(4) /*!< the duration time of transfer state is 5 CTCLK */
+#define TSI_TRANSFER_6CTCLK CTL_CTDT(5) /*!< the duration time of transfer state is 6 CTCLK */
+#define TSI_TRANSFER_7CTCLK CTL_CTDT(6) /*!< the duration time of transfer state is 7 CTCLK */
+#define TSI_TRANSFER_8CTCLK CTL_CTDT(7) /*!< the duration time of transfer state is 8 CTCLK */
+#define TSI_TRANSFER_9CTCLK CTL_CTDT(8) /*!< the duration time of transfer state is 9 CTCLK */
+#define TSI_TRANSFER_10CTCLK CTL_CTDT(9) /*!< the duration time of transfer state is 10 CTCLK */
+#define TSI_TRANSFER_11CTCLK CTL_CTDT(10) /*!< the duration time of transfer state is 11 CTCLK */
+#define TSI_TRANSFER_12CTCLK CTL_CTDT(11) /*!< the duration time of transfer state is 12 CTCLK */
+#define TSI_TRANSFER_13CTCLK CTL_CTDT(12) /*!< the duration time of transfer state is 13 CTCLK */
+#define TSI_TRANSFER_14CTCLK CTL_CTDT(13) /*!< the duration time of transfer state is 14 CTCLK */
+#define TSI_TRANSFER_15CTCLK CTL_CTDT(14) /*!< the duration time of transfer state is 15 CTCLK */
+#define TSI_TRANSFER_16CTCLK CTL_CTDT(15) /*!< the duration time of transfer state is 16 CTCLK */
+
+/* charge state duration time */
+#define CTL_CDT(regval) (BITS(28,31) & ((uint32_t)(regval) << 28U))
+#define TSI_CHARGE_1CTCLK CTL_CDT(0) /*!< the duration time of charge state is 1 CTCLK */
+#define TSI_CHARGE_2CTCLK CTL_CDT(1) /*!< the duration time of charge state is 2 CTCLK */
+#define TSI_CHARGE_3CTCLK CTL_CDT(2) /*!< the duration time of charge state is 3 CTCLK */
+#define TSI_CHARGE_4CTCLK CTL_CDT(3) /*!< the duration time of charge state is 4 CTCLK */
+#define TSI_CHARGE_5CTCLK CTL_CDT(4) /*!< the duration time of charge state is 5 CTCLK */
+#define TSI_CHARGE_6CTCLK CTL_CDT(5) /*!< the duration time of charge state is 6 CTCLK */
+#define TSI_CHARGE_7CTCLK CTL_CDT(6) /*!< the duration time of charge state is 7 CTCLK */
+#define TSI_CHARGE_8CTCLK CTL_CDT(7) /*!< the duration time of charge state is 8 CTCLK */
+#define TSI_CHARGE_9CTCLK CTL_CDT(8) /*!< the duration time of charge state is 9 CTCLK */
+#define TSI_CHARGE_10CTCLK CTL_CDT(9) /*!< the duration time of charge state is 10 CTCLK */
+#define TSI_CHARGE_11CTCLK CTL_CDT(10) /*!< the duration time of charge state is 11 CTCLK */
+#define TSI_CHARGE_12CTCLK CTL_CDT(11) /*!< the duration time of charge state is 12 CTCLK */
+#define TSI_CHARGE_13CTCLK CTL_CDT(12) /*!< the duration time of charge state is 13 CTCLK */
+#define TSI_CHARGE_14CTCLK CTL_CDT(13) /*!< the duration time of charge state is 14 CTCLK */
+#define TSI_CHARGE_15CTCLK CTL_CDT(14) /*!< the duration time of charge state is 15 CTCLK */
+#define TSI_CHARGE_16CTCLK CTL_CDT(15) /*!< the duration time of charge state is 16 CTCLK */
+
+/* max cycle number of a sequence */
+#define CTL_MCN(regval) (BITS(5,7) & ((uint32_t)(regval) << 5U))
+#define TSI_MAXNUM255 CTL_MCN(0) /*!< the max cycle number of a sequence is 255 */
+#define TSI_MAXNUM511 CTL_MCN(1) /*!< the max cycle number of a sequence is 511 */
+#define TSI_MAXNUM1023 CTL_MCN(2) /*!< the max cycle number of a sequence is 1023 */
+#define TSI_MAXNUM2047 CTL_MCN(3) /*!< the max cycle number of a sequence is 2047 */
+#define TSI_MAXNUM4095 CTL_MCN(4) /*!< the max cycle number of a sequence is 4095 */
+#define TSI_MAXNUM8191 CTL_MCN(5) /*!< the max cycle number of a sequence is 8191 */
+#define TSI_MAXNUM16383 CTL_MCN(6) /*!< the max cycle number of a sequence is 16383 */
+
+/* ECCLK clock division factor */
+#define TSI_EXTEND_DIV1 ((uint32_t)0x00000000U) /*!< fECCLK = fHCLK */
+#define TSI_EXTEND_DIV2 ((uint32_t)0x00000001U) /*!< fECCLK = fHCLK/2 */
+#define TSI_EXTEND_DIV3 ((uint32_t)0x00000002U) /*!< fECCLK = fHCLK/3 */
+#define TSI_EXTEND_DIV4 ((uint32_t)0x00000003U) /*!< fECCLK = fHCLK/4 */
+#define TSI_EXTEND_DIV5 ((uint32_t)0x00000004U) /*!< fECCLK = fHCLK/5 */
+#define TSI_EXTEND_DIV6 ((uint32_t)0x00000005U) /*!< fECCLK = fHCLK/6 */
+#define TSI_EXTEND_DIV7 ((uint32_t)0x00000006U) /*!< fECCLK = fHCLK/7 */
+#define TSI_EXTEND_DIV8 ((uint32_t)0x00000007U) /*!< fECCLK = fHCLK/8 */
+
+/* extend charge state maximum duration time */
+#define TSI_EXTENDMAX(regval) (BITS(17,23) & ((uint32_t)(regval) << 17U)) /* value range 1..128,extend charge state maximum duration time */
+
+/* hardware trigger mode */
+#define TSI_FALLING_TRIGGER 0x00U /*!< falling edge trigger TSI charge transfer sequence */
+#define TSI_RISING_TRIGGER 0x01U /*!< rising edge trigger TSI charge transfer sequence */
+
+/* pin mode */
+#define TSI_OUTPUT_LOW 0x00U /*!< TSI pin will output low when IDLE */
+#define TSI_INPUT_FLOATING 0x01U /*!< TSI pin will keep input_floating when IDLE */
+
+/* function declarations */
+/* reset TSI peripheral */
+void tsi_deinit(void);
+/* initialize TSI plus prescaler,charge plus,transfer plus,max cycle number */
+void tsi_init(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration,uint32_t max_number);
+/* enable TSI module */
+void tsi_enable(void);
+/* disable TSI module */
+void tsi_disable(void);
+/* enable sample pin */
+void tsi_sample_pin_enable(uint32_t sample);
+/* disable sample pin */
+void tsi_sample_pin_disable(uint32_t sample);
+/* enable channel pin */
+void tsi_channel_pin_enable(uint32_t channel);
+/* disable channel pin */
+void tsi_channel_pin_disable(uint32_t channel);
+
+/* configure TSI triggering by software */
+void tsi_sofeware_mode_config(void);
+/* start a charge-transfer sequence when TSI is in software trigger mode */
+void tsi_software_start(void);
+/* stop a charge-transfer sequence when TSI is in software trigger mode */
+void tsi_software_stop(void);
+/* configure TSI triggering by hardware */
+void tsi_hardware_mode_config(uint8_t trigger_edge);
+/* configure TSI pin mode when charge-transfer sequence is IDLE */
+void tsi_pin_mode_config(uint8_t pin_mode);
+/* configure extend charge state */
+void tsi_extend_charge_config(ControlStatus extend,uint8_t prescaler,uint32_t max_duration);
+
+/* configure charge plus and transfer plus */
+void tsi_plus_config(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration);
+/* configure the max cycle number of a charge-transfer sequence */
+void tsi_max_number_config(uint32_t max_number);
+/* switch on hysteresis pin */
+void tsi_hysteresis_on(uint32_t group_pin);
+/* switch off hysteresis pin */
+void tsi_hysteresis_off(uint32_t group_pin);
+/* switch on analog pin */
+void tsi_analog_on(uint32_t group_pin);
+/* switch off analog pin */
+void tsi_analog_off(uint32_t group_pin);
+
+/* enable TSI interrupt */
+void tsi_interrupt_enable(uint32_t source);
+/* disable TSI interrupt */
+void tsi_interrupt_disable(uint32_t source);
+/* clear interrupt flag */
+void tsi_interrupt_flag_clear(uint32_t flag);
+/* get TSI interrupt flag */
+FlagStatus tsi_interrupt_flag_get(uint32_t flag);
+
+/* clear flag */
+void tsi_flag_clear(uint32_t flag);
+/* get flag */
+FlagStatus tsi_flag_get(uint32_t flag);
+
+/* enbale group */
+void tsi_group_enable(uint32_t group);
+/* disbale group */
+void tsi_group_disable(uint32_t group);
+/* get group complete status */
+FlagStatus tsi_group_status_get(uint32_t group);
+/* get the cycle number for group0 as soon as a charge-transfer sequence completes */
+uint16_t tsi_group0_cycle_get(void);
+/* get the cycle number for group1 as soon as a charge-transfer sequence completes */
+uint16_t tsi_group1_cycle_get(void);
+/* get the cycle number for group2 as soon as a charge-transfer sequence completes */
+uint16_t tsi_group2_cycle_get(void);
+/* get the cycle number for group3 as soon as a charge-transfer sequence completes */
+uint16_t tsi_group3_cycle_get(void);
+/* get the cycle number for group4 as soon as a charge-transfer sequence completes */
+uint16_t tsi_group4_cycle_get(void);
+/* get the cycle number for group5 as soon as a charge-transfer sequence completes */
+uint16_t tsi_group5_cycle_get(void);
+
+#endif /* GD32F3X0_TSI_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_usart.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_usart.h
new file mode 100644
index 0000000000000000000000000000000000000000..fb06b818de1b92ee95fc5c015486277f87f8c3b7
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_usart.h
@@ -0,0 +1,595 @@
+/*!
+ \file gd32f3x0_usart.h
+ \brief definitions for the USART
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_USART_H
+#define GD32F3X0_USART_H
+
+#include "gd32f3x0.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_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_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_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 RFCS register */
+ 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 flag */
+ USART_INT_FLAG_RT = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 26U, USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout interrupt flag */
+ USART_INT_FLAG_AM = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 14U, USART_STAT_REG_OFFSET, 17U), /*!< address match interrupt flag */
+ USART_INT_FLAG_PERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 8U, USART_STAT_REG_OFFSET, 0U), /*!< parity error interrupt flag */
+ USART_INT_FLAG_TBE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt flag */
+ USART_INT_FLAG_TC = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 6U), /*!< transmission complete interrupt flag */
+ USART_INT_FLAG_RBNE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt flag */
+ USART_INT_FLAG_RBNE_ORERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 3U), /*!< overrun error interrupt flag */
+ USART_INT_FLAG_IDLE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 4U, USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected interrupt 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 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 flag */
+ USART_INT_FLAG_CTS = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 10U, USART_STAT_REG_OFFSET, 9U), /*!< CTS interrupt flag */
+ USART_INT_FLAG_ERR_NERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 2U), /*!< noise error interrupt flag */
+ USART_INT_FLAG_ERR_ORERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 3U), /*!< overrun error interrupt flag */
+ USART_INT_FLAG_ERR_FERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 1U), /*!< frame error interrupt flag */
+ /* interrupt flags in RFCS register */
+ USART_INT_FLAG_RFFINT = USART_REGIDX_BIT2(USART_RFCS_REG_OFFSET, 9U, USART_RFCS_REG_OFFSET, 15U), /*!< receive FIFO full interrupt 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 */
+
+/* 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 the address of the USART in wake up by address match mode */
+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);
+/* configure LIN break frame 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 USART clock */
+void usart_clock_enable(uint32_t usart_periph);
+/* disable USART 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 in USART IrDA low-power mode or SmartCard mode */
+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);
+
+/* 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);
+/* enable USART command */
+void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype);
+
+/* 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 flag in STAT register */
+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 interrupt);
+/* disable USART interrupt */
+void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum interrupt);
+/* 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 int_flag);
+
+#endif /* GD32F3X0_USART_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_wwdgt.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_wwdgt.h
new file mode 100644
index 0000000000000000000000000000000000000000..9905fa75c1ef87de17d71dac321e3fc434a44862
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Include/gd32f3x0_wwdgt.h
@@ -0,0 +1,93 @@
+/*!
+ \file gd32f3x0_wwdgt.h
+ \brief definitions for the WWDGT
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_WWDGT_H
+#define GD32F3X0_WWDGT_H
+
+#include "gd32f3x0.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 */
+/* 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 */
+
+#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 /* GD32F3X0_WWDGT_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_adc.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_adc.c
new file mode 100644
index 0000000000000000000000000000000000000000..490f3f96632ab33ff21f3bd1bc15f7d86dffa019
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_adc.c
@@ -0,0 +1,869 @@
+/*!
+ \file gd32f3x0_adc.c
+ \brief ADC driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_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 enable the vbat channel
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void adc_vbat_enable(void)
+{
+ /* enable the vbat channel */
+ ADC_CTL1 |= ADC_CTL1_VBETEN;
+}
+
+/*!
+ \brief disable the vbat channel
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void adc_vbat_disable(void)
+{
+ /* disable the vbat channel */
+ ADC_CTL1 &= ~ADC_CTL1_VBETEN;
+}
+
+/*!
+ \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..18): 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..18): 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_T1_CH1: TIMER1 CH1 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_T1_TRGO: TIMER1 TRGO event select
+ \arg ADC_EXTTRIG_INSERTED_T1_CH0: TIMER1 CH0 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..18): 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);
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_cec.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_cec.c
new file mode 100644
index 0000000000000000000000000000000000000000..42b0d502536a543cad170b76bd27e2336948cb10
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_cec.c
@@ -0,0 +1,499 @@
+/*!
+ \file gd32f3x0_cec.c
+ \brief CEC driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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.
+*/
+
+#ifdef GD32F350
+
+#include "gd32f3x0_cec.h"
+
+/*!
+ \brief reset HDMI-CEC controller
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cec_deinit(void)
+{
+ rcu_periph_reset_enable(RCU_CECRST);
+ rcu_periph_reset_disable(RCU_CECRST);
+}
+
+/*!
+ \brief configure signal free time,the signal free time counter start option,own address
+ \param[in] sftmopt: signal free time counter start option
+ only one parameter can be selected which is shown as below:
+ \arg CEC_SFT_START_STAOM: signal free time counter starts counting when STAOM is asserted
+ \arg CEC_SFT_START_LAST: signal free time counter starts automatically after transmission/reception end
+ \param[in] sft: signal free time
+ only one parameter can be selected which is shown as below:
+ \arg CEC_SFT_PROTOCOL_PERIOD: the signal free time will perform as HDMI-CEC protocol description
+ \arg CEC_SFT_1POINT5_PERIOD: 1.5 nominal data bit periods
+ \arg CEC_SFT_2POINT5_PERIOD: 2.5 nominal data bit periods
+ \arg CEC_SFT_3POINT5_PERIOD: 3.5 nominal data bit periods
+ \arg CEC_SFT_4POINT5_PERIOD: 4.5 nominal data bit periods
+ \arg CEC_SFT_5POINT5_PERIOD: 5.5 nominal data bit periods
+ \arg CEC_SFT_6POINT5_PERIOD: 6.5 nominal data bit periods
+ \arg CEC_SFT_7POINT5_PERIOD: 7.5 nominal data bit periods
+ \param[in] address: own address
+ only one parameter can be selected which is shown as below:
+ \arg CEC_OWN_ADDRESS_CLEAR: own address is cleared
+ \arg CEC_OWN_ADDRESSx(x=0..14): own address is x
+ \param[out] none
+ \retval none
+*/
+void cec_init(uint32_t sftmopt, uint32_t sft, uint32_t address)
+{
+ uint32_t cfg;
+ cfg = CEC_CFG;
+ /* clear SFTMOPT bit,SFT[2:0] */
+ cfg &= ~(CEC_CFG_SFTOPT | CEC_CFG_SFT);
+ /* assign SFTMOPT bit,SFT[2:0] */
+ cfg |= (sftmopt | sft);
+ CEC_CFG = cfg;
+ if(CEC_OWN_ADDRESS_CLEAR == address){
+ CEC_CFG &= ~CEC_CFG_OWN_ADDRESS;
+ }else{
+ CEC_CFG |= address;
+ }
+}
+
+/*!
+ \brief configure generate Error-bit when detected some abnormal situation or not,
+ whether stop receive message when detected bit rising error
+ \param[in] broadcast:
+ only one parameter can be selected which is shown as below:
+ \arg CEC_BROADCAST_ERROR_BIT_ON:generate Error-bit in broadcast
+ \arg CEC_BROADCAST_ERROR_BIT_OFF:do not generate Error-bit in broadcast
+ \param[in] singlecast_lbpe:
+ only one parameter can be selected which is shown as below:
+ \arg CEC_LONG_PERIOD_ERROR_BIT_ON:generate Error-bit on long bit period error
+ \arg CEC_LONG_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on long bit period error
+ \param[in] singlecast_bre:
+ only one parameter can be selected which is shown as below:
+ \arg CEC_RISING_PERIOD_ERROR_BIT_ON:generate Error-bit on bit rising error
+ \arg CEC_RISING_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on bit rising error
+ \param[in] rxbrestp:
+ only one parameter can be selected which is shown as below:
+ \arg CEC_STOP_RISING_ERROR_BIT_ON: stop reception when detected bit rising error
+ \arg CEC_STOP_RISING_ERROR_BIT_OFF: do not stop reception when detected bit rising error
+ \param[out] none
+ \retval none
+*/
+void cec_error_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre, uint32_t rxbrestp)
+{
+ uint32_t cfg;
+ cfg = CEC_CFG;
+ /* clear BCNG bit, BPLEG bit, BREG bit */
+ cfg &= ~(CEC_CFG_BCNG | CEC_CFG_BPLEG | CEC_CFG_BREG);
+ /* assign BCNG bit, BPLEG bit, BREG bit */
+ cfg |= (broadcast | singlecast_lbpe | singlecast_bre);
+ CEC_CFG = cfg;
+ if(CEC_STOP_RISING_ERROR_BIT_ON == rxbrestp){
+ CEC_CFG |= CEC_CFG_BRES;
+ }else{
+ CEC_CFG &= ~CEC_CFG_BRES;
+ }
+}
+
+/*!
+ \brief enable HDMI-CEC controller
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cec_enable(void)
+{
+ CEC_CTL |= CEC_CTL_CECEN;
+}
+
+/*!
+ \brief disable HDMI-CEC controller
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cec_disable(void)
+{
+ CEC_CTL &= ~CEC_CTL_CECEN;
+}
+
+/*!
+ \brief start CEC message transmission
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cec_transmission_start(void)
+{
+ CEC_CTL |= CEC_CTL_STAOM;
+}
+
+/*!
+ \brief end CEC message transmission
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cec_transmission_end(void)
+{
+ CEC_CTL |= CEC_CTL_ENDOM;
+}
+
+/*!
+ \brief enable CEC listen mode.
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cec_listen_mode_enable(void)
+{
+ CEC_CFG |= CEC_CFG_LMEN;
+}
+
+/*!
+ \brief disable CEC listen mode.
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cec_listen_mode_disable(void)
+{
+ CEC_CFG &= ~CEC_CFG_LMEN;
+}
+
+/*!
+ \brief configure and clear own address.the controller can be configured to multiple own address
+ \param[in] address: own address
+ one or more parameters can be selected which are shown as below:
+ \arg CEC_OWN_ADDRESS_CLEAR: own address is cleared
+ \arg CEC_OWN_ADDRESSx(x=0..14): own address is x
+ \param[out] none
+ \retval none
+*/
+void cec_own_address_config(uint32_t address)
+{
+ if(CEC_OWN_ADDRESS_CLEAR == address){
+ CEC_CFG &= ~CEC_CFG_OWN_ADDRESS;
+ } else {
+ CEC_CFG |= address;
+ }
+}
+
+/*!
+ \brief configure signal free time and the signal free time counter start option
+ \param[in] sftmopt: signal free time counter start option
+ only one parameter can be selected which is shown as below:
+ \arg CEC_SFT_START_STAOM: signal free time counter starts counting when STAOM is asserted
+ \arg CEC_SFT_START_LAST: signal free time counter starts automatically after transmission/reception end
+ \param[in] sft: signal free time
+ only one parameter can be selected which is shown as below:
+ \arg CEC_SFT_PROTOCOL_PERIOD: the signal free time will perform as HDMI-CEC protocol description
+ \arg CEC_SFT_1POINT5_PERIOD: 1.5 nominal data bit periods
+ \arg CEC_SFT_2POINT5_PERIOD: 2.5 nominal data bit periods
+ \arg CEC_SFT_3POINT5_PERIOD: 3.5 nominal data bit periods
+ \arg CEC_SFT_4POINT5_PERIOD: 4.5 nominal data bit periods
+ \arg CEC_SFT_5POINT5_PERIOD: 5.5 nominal data bit periods
+ \arg CEC_SFT_6POINT5_PERIOD: 6.5 nominal data bit periods
+ \arg CEC_SFT_7POINT5_PERIOD: 7.5 nominal data bit periods
+ \param[out] none
+ \retval none
+*/
+void cec_sft_config(uint32_t sftmopt, uint32_t sft)
+{
+ uint32_t cfg;
+ cfg = CEC_CFG;
+ /* clear SFTMOPT bit,SFT[2:0] */
+ cfg &= ~(CEC_CFG_SFTOPT | CEC_CFG_SFT);
+ /* assign SFTMOPT bit,SFT[2:0] */
+ cfg |= (sftmopt | sft);
+ CEC_CFG = cfg;
+}
+
+/*!
+ \brief configure generate Error-bit when detected some abnormal situation or not
+ \param[in] broadcast:
+ only one parameter can be selected which is shown as below:
+ \arg CEC_BROADCAST_ERROR_BIT_ON:generate Error-bit in broadcast
+ \arg CEC_BROADCAST_ERROR_BIT_OFF:do not generate Error-bit in broadcast
+ \param[in] singlecast_lbpe:
+ only one parameter can be selected which is shown as below:
+ \arg CEC_LONG_PERIOD_ERROR_BIT_ON:generate Error-bit on long bit period error
+ \arg CEC_LONG_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on long bit period error
+ \param[in] singlecast_bre:
+ only one parameter can be selected which is shown as below:
+ \arg CEC_RISING_PERIOD_ERROR_BIT_ON:generate Error-bit on bit rising error
+ \arg CEC_RISING_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on bit rising error
+ \param[out] none
+ \retval none
+*/
+void cec_generate_errorbit_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre)
+{
+ uint32_t cfg;
+ cfg = CEC_CFG;
+ /* clear BCNG bit, RLBPEGEN bit, RBREGEN bit */
+ cfg &= ~(CEC_CFG_BCNG | CEC_CFG_BPLEG | CEC_CFG_BREG);
+ /* assign BCNG bit, RLBPEGEN bit, RBREGEN bit */
+ cfg |= (broadcast | singlecast_lbpe | singlecast_bre);
+ CEC_CFG = cfg;
+}
+
+/*!
+ \brief whether stop receive message when detected bit rising error
+ \param[in] rxbrestp:
+ only one parameter can be selected which is shown as below:
+ \arg CEC_STOP_RISING_ERROR_BIT_ON: stop reception when detected bit rising error
+ \arg CEC_STOP_RISING_ERROR_BIT_OFF: do not stop reception when detected bit rising error
+ \param[out] none
+ \retval none
+*/
+void cec_stop_receive_bre_config(uint32_t rxbrestp)
+{
+ if(CEC_STOP_RISING_ERROR_BIT_ON == rxbrestp){
+ CEC_CFG |= CEC_CFG_BRES;
+ } else {
+ CEC_CFG &= ~CEC_CFG_BRES;
+ }
+}
+
+/*!
+ \brief enable reception bit timing tolerance
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cec_reception_tolerance_enable(void)
+{
+ CEC_CFG |= CEC_CFG_RTOL;
+}
+
+/*!
+ \brief disable reception bit timing tolerance
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cec_reception_tolerance_disable(void)
+{
+ CEC_CFG &= ~CEC_CFG_RTOL;
+}
+
+/*!
+ \brief send a data by the CEC peripheral
+ \param[in] data: the data to transmit
+ \param[out] none
+ \retval none
+*/
+void cec_data_send(uint8_t data)
+{
+ CEC_TDATA = (uint32_t)data;
+}
+
+/*!
+ \brief receive a data by the CEC peripheral
+ \param[in] data: the data to receive
+ \param[out] none
+ \retval none
+*/
+uint8_t cec_data_receive(void)
+{
+ return (uint8_t)CEC_RDATA;
+}
+
+
+/*!
+ \brief enable interrupt
+ \param[in] flag: specify which flag
+ one or more parameters can be selected which are shown as below:
+ \arg CEC_INT_BR: enable Rx-byte data received interrupt
+ \arg CEC_INT_REND: enable end of reception interrupt
+ \arg CEC_INT_RO: enable RX overrun interrupt
+ \arg CEC_INT_BRE: enable bit rising error interrupt
+ \arg CEC_INT_BPSE: enable short bit period error interrupt
+ \arg CEC_INT_BPLE: enable long bit period error interrupt
+ \arg CEC_INT_RAE: enable Rx ACK error interrupt
+ \arg CEC_INT_ARBF: enable arbitration lost interrupt
+ \arg CEC_INT_TBR: enable Tx-byte data request interrupt
+ \arg CEC_INT_TEND: enable transmission successfully end interrupt
+ \arg CEC_INT_TU: enable Tx data buffer underrun interrupt
+ \arg CEC_INT_TERR: enable Tx-error interrupt
+ \arg CEC_INT_TAERR: enable Tx ACK error interrupt
+ \param[out] none
+ \retval none
+*/
+void cec_interrupt_enable(uint32_t flag)
+{
+ CEC_INTEN |= flag;
+}
+
+/*!
+ \brief disable interrupt
+ \param[in] flag: specify which flag
+ one or more parameters can be selected which are shown as below:
+ \arg CEC_INT_BR: disable Rx-byte data received interrupt
+ \arg CEC_INT_REND: disable end of reception interrupt
+ \arg CEC_INT_RO: disable RX overrun interrupt
+ \arg CEC_INT_BRE: disable bit rising error interrupt
+ \arg CEC_INT_BPSE: disable short bit period error interrupt
+ \arg CEC_INT_BPLE: disable long bit period error interrupt
+ \arg CEC_INT_RAE: disable Rx ACK error interrupt
+ \arg CEC_INT_ARBF: disable arbitration lost interrupt
+ \arg CEC_INT_TBR: disable Tx-byte data request interrupt
+ \arg CEC_INT_TEND: disable transmission successfully end interrupt
+ \arg CEC_INT_TU: disable Tx data buffer underrun interrupt
+ \arg CEC_INT_TERR: disable Tx-error interrupt
+ \arg CEC_INT_TAERR: disable Tx ACK error interrupt
+
+ \param[out] none
+ \retval none
+*/
+void cec_interrupt_disable(uint32_t flag)
+{
+ CEC_INTEN &= ~flag;
+}
+
+
+/*!
+ \brief get CEC status
+ \param[in] flag: specify which flag
+ one or more parameters can be selected which are shown as below:
+ \arg CEC_FLAG_BR: Rx-byte data received
+ \arg CEC_FLAG_REND: end of reception
+ \arg CEC_FLAG_RO: RX overrun
+ \arg CEC_FLAG_BRE: bit rising error
+ \arg CEC_FLAG_BPSE: short bit period error
+ \arg CEC_FLAG_BPLE: long bit period error
+ \arg CEC_FLAG_RAE: Rx ACK error
+ \arg CEC_FLAG_ARBF: arbitration lost
+ \arg CEC_FLAG_TBR: Tx-byte data request
+ \arg CEC_FLAG_TEND: transmission successfully end
+ \arg CEC_FLAG_TU: Tx data buffer underrun
+ \arg CEC_FLAG_TERR: Tx-error
+ \arg CEC_FLAG_TAERR Tx ACK error flag
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus cec_flag_get(uint32_t flag)
+{
+ if(CEC_INTF & flag){
+ return SET;
+ }else{
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear CEC status
+ \param[in] flag: specify which flag
+ one or more parameters can be selected which are shown as below:
+ \arg CEC_FLAG_BR: Rx-byte data received
+ \arg CEC_FLAG_REND: end of reception
+ \arg CEC_FLAG_RO: RX overrun
+ \arg CEC_FLAG_BRE: bit rising error
+ \arg CEC_FLAG_BPSE: short bit period error
+ \arg CEC_FLAG_BPLE: long bit period error
+ \arg CEC_FLAG_RAE: Rx ACK error
+ \arg CEC_FLAG_ARBF: arbitration lost
+ \arg CEC_FLAG_TBR: Tx-byte data request
+ \arg CEC_FLAG_TEND: transmission successfully end
+ \arg CEC_FLAG_TU: Tx data buffer underrun
+ \arg CEC_FLAG_TERR: Tx-error
+ \arg CEC_FLAG_TAERR: Tx ACK error flag
+
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+void cec_flag_clear(uint32_t flag)
+{
+ CEC_INTF |= flag;
+}
+
+/*!
+ \brief get CEC int flag and status
+ \param[in] flag: specify which flag
+ one or more parameters can be selected which are shown as below:
+ \arg CEC_INT_FLAG_BR: Rx-byte data received
+ \arg CEC_INT_FLAG_REND: end of reception
+ \arg CEC_INT_FLAG_RO: RX overrun
+ \arg CEC_INT_FLAG_BRE: bit rising error
+ \arg CEC_INT_FLAG_BPSE: short bit period error
+ \arg CEC_INT_FLAG_BPLE: long bit period error
+ \arg CEC_INT_FLAG_RAE: Rx ACK error
+ \arg CEC_INT_FLAG_ARBF: arbitration lost
+ \arg CEC_INT_FLAG_TBR: Tx-byte data request
+ \arg CEC_INT_FLAG_TEND: transmission successfully end
+ \arg CEC_INT_FLAG_TU: Tx data buffer underrun
+ \arg CEC_INT_FLAG_TERR: Tx-error
+ \arg CEC_INT_FLAG_TAERR: Tx ACK error flag
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus cec_interrupt_flag_get(uint32_t flag)
+{
+ uint32_t interrupt_enable = 0U,interrupt_flag = 0U;
+ interrupt_flag = (CEC_INTF & flag);
+ interrupt_enable = (CEC_INTEN & flag);
+ if(interrupt_flag && interrupt_enable){
+ return SET;
+ }else{
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear CEC int flag and status
+ \param[in] flag: specify which flag
+ one or more parameters can be selected which are shown as below:
+ \arg CEC_INT_FLAG_BR: Rx-byte data received
+ \arg CEC_INT_FLAG_REND: end of reception
+ \arg CEC_INT_FLAG_RO: RX overrun
+ \arg CEC_INT_FLAG_BRE: bit rising error
+ \arg CEC_INT_FLAG_BPSE: short bit period error
+ \arg CEC_INT_FLAG_BPLE: long bit period error
+ \arg CEC_INT_FLAG_RAE: Rx ACK error
+ \arg CEC_INT_FLAG_ARBF: arbitration lost
+ \arg CEC_INT_FLAG_TBR: Tx-byte data request
+ \arg CEC_INT_FLAG_TEND: transmission successfully end
+ \arg CEC_INT_FLAG_TU: Tx data buffer underrun
+ \arg CEC_INT_FLAG_TERR: Tx-error
+ \arg CEC_INT_FLAG_TAERR: Tx ACK error flag
+ \param[out] none
+ \retval none
+*/
+void cec_interrupt_flag_clear(uint32_t flag)
+{
+ CEC_INTF = flag;
+}
+
+
+#endif
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_cmp.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_cmp.c
new file mode 100644
index 0000000000000000000000000000000000000000..2a5d6c79227a97579a4cecd48e7a7b20ce7038c3
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_cmp.c
@@ -0,0 +1,255 @@
+/*!
+ \file gd32f3x0_cmp.c
+ \brief CMP driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_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] cmp_periph
+ \arg CMP0: comparator 0
+ \arg CMP1: comparator 1
+ \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_DAC: PA4 (DAC) input
+ \arg CMP_PA5: PA5 input
+ \arg CMP_PA_0_2: PA0 or 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(uint32_t cmp_periph, operating_mode_enum operating_mode, inverting_input_enum inverting_input, cmp_hysteresis_enum output_hysteresis)
+{
+ if(CMP0 == cmp_periph){
+ /* initialize comparator 0 mode */
+ CMP_CS &= ~(uint32_t)(CMP_CS_CMP0M | CMP_CS_CMP0MSEL | CMP_CS_CMP0HST );
+ CMP_CS |= CS_CMP0M(operating_mode) | CS_CMP0MSEL(inverting_input) | CS_CMP0HST(output_hysteresis);
+ }else{
+ /* initialize comparator 1 mode */
+ CMP_CS &= ~(uint32_t)(CMP_CS_CMP1M | CMP_CS_CMP1MSEL | CMP_CS_CMP1HST );
+ CMP_CS |= CS_CMP1M(operating_mode) | CS_CMP1MSEL(inverting_input) | CS_CMP1HST(output_hysteresis);
+ }
+}
+
+/*!
+ \brief initialize comparator output
+ \param[in] cmp_periph
+ \arg CMP0: comparator 0
+ \arg CMP1: comparator 1
+ \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_TIMER1IC3: TIMER 1 channel3 input capture
+ \arg CMP_OUTPUT_TIMER1OCPRECLR: TIMER 1 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(uint32_t cmp_periph, cmp_output_enum output_slection, uint32_t output_polarity)
+{
+ /* initialize comparator 0 output */
+ if(CMP0 == cmp_periph){
+ CMP_CS &= ~(uint32_t)CMP_CS_CMP0OSEL;
+ CMP_CS |= CS_CMP0OSEL(output_slection);
+ /* output polarity */
+ if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){
+ CMP_CS |= CMP_CS_CMP0PL;
+ }else{
+ CMP_CS &= ~CMP_CS_CMP0PL;
+ }
+ }else{
+ /* initialize comparator 1 output */
+ CMP_CS &= ~(uint32_t)CMP_CS_CMP1OSEL;
+ CMP_CS |= CS_CMP1OSEL(output_slection);
+ /* output polarity */
+ if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){
+ CMP_CS |= CMP_CS_CMP1PL;
+ }else{
+ CMP_CS &= ~CMP_CS_CMP1PL;
+ }
+ }
+}
+
+/*!
+ \brief enable comparator
+ \param[in] cmp_periph
+ \arg CMP0: comparator 0
+ \arg CMP1: comparator 1
+ \param[out] none
+ \retval none
+*/
+void cmp_enable(uint32_t cmp_periph)
+{
+ if(CMP0 == cmp_periph){
+ CMP_CS |= CMP_CS_CMP0EN;
+ }else{
+ CMP_CS |= CMP_CS_CMP1EN;
+ }
+}
+
+/*!
+ \brief disable comparator
+ \param[in] cmp_periph
+ \arg CMP0: comparator 0
+ \arg CMP1: comparator 1
+ \param[out] none
+ \retval none
+*/
+void cmp_disable(uint32_t cmp_periph)
+{
+ if(CMP0 == cmp_periph){
+ CMP_CS &= ~CMP_CS_CMP0EN;
+ }else{
+ CMP_CS &= ~CMP_CS_CMP1EN;
+ }
+}
+
+/*!
+ \brief enable comparator switch
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cmp_switch_enable(void)
+{
+ CMP_CS |= CMP_CS_CMP0SW;
+}
+
+/*!
+ \brief disable comparator switch
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cmp_switch_disable(void)
+{
+ CMP_CS &= ~CMP_CS_CMP0SW;
+}
+
+/*!
+ \brief enable the window mode
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cmp_window_enable(void)
+{
+ CMP_CS |= CMP_CS_WNDEN;
+}
+
+/*!
+ \brief disable the window mode
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void cmp_window_disable(void)
+{
+ CMP_CS &= ~CMP_CS_WNDEN;
+}
+
+/*!
+ \brief lock the comparator
+ \param[in] cmp_periph
+ \arg CMP0: comparator 0
+ \arg CMP1: comparator 1
+ \param[out] none
+ \retval none
+*/
+void cmp_lock_enable(uint32_t cmp_periph)
+{
+ if(CMP0 == cmp_periph){
+ /* lock CMP0 */
+ CMP_CS |= CMP_CS_CMP0LK;
+ }else{
+ /* lock CMP1 */
+ CMP_CS |= CMP_CS_CMP1LK;
+ }
+}
+
+/*!
+ \brief get output level
+ \param[in] cmp_periph
+ \arg CMP0: comparator 0
+ \arg CMP1: comparator 1
+ \param[out] none
+ \retval the output level
+*/
+uint32_t cmp_output_level_get(uint32_t cmp_periph)
+{
+ if(CMP0 == cmp_periph){
+ /* get output level of CMP0 */
+ if(CMP_CS & CMP_CS_CMP0O){
+ return CMP_OUTPUTLEVEL_HIGH;
+ }else{
+ return CMP_OUTPUTLEVEL_LOW;
+ }
+ }else{
+ /* get output level of CMP1 */
+ if(CMP_CS & CMP_CS_CMP1O){
+ return CMP_OUTPUTLEVEL_HIGH;
+ }else{
+ return CMP_OUTPUTLEVEL_LOW;
+ }
+ }
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_crc.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_crc.c
new file mode 100644
index 0000000000000000000000000000000000000000..4166723b2850558e19727c34f05184e84ca2fba8
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_crc.c
@@ -0,0 +1,207 @@
+/*!
+ \file gd32f3x0_crc.c
+ \brief CRC driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_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
+ only one parameter can be selected which is shown as below:
+ \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
+ only one parameter can be selected which is shown as below:
+ \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);
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_ctc.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_ctc.c
new file mode 100644
index 0000000000000000000000000000000000000000..c065ddb7e5463ff0fa5b4ab5e4fbf5bf8116a1a7
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_ctc.c
@@ -0,0 +1,382 @@
+/*!
+ \file gd32f3x0_ctc.c
+ \brief CTC driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_ctc.h"
+
+#define CTC_FLAG_MASK ((uint32_t)0x00000700U)
+
+/*!
+ \brief reset CTC clock trim controller
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void ctc_deinit(void)
+{
+ /* reset CTC */
+ rcu_periph_reset_enable(RCU_CTCRST);
+ rcu_periph_reset_disable(RCU_CTCRST);
+}
+
+/*!
+ \brief configure reference signal source polarity
+ \param[in] polarity:
+ only one parameter can be selected which is shown as below:
+ \arg CTC_REFSOURCE_POLARITY_FALLING: reference signal source polarity is falling edge
+ \arg CTC_REFSOURCE_POLARITY_RISING: reference signal source polarity is rising edge
+ \param[out] none
+ \retval none
+*/
+void ctc_refsource_polarity_config(uint32_t polarity)
+{
+ CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPOL);
+ CTC_CTL1 |= (uint32_t)polarity;
+}
+
+/*!
+ \brief select reference signal source
+ \param[in] refs:
+ only one parameter can be selected which is shown as below:
+ \arg CTC_REFSOURCE_GPIO: GPIO is selected
+ \arg CTC_REFSOURCE_LXTAL: LXTAL is clock selected
+ \arg CTC_REFSOURCE_USBSOF: USBSOF is selected
+ \param[out] none
+ \retval none
+*/
+void ctc_refsource_signal_select(uint32_t refs)
+{
+ CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFSEL);
+ CTC_CTL1 |= (uint32_t)refs;
+}
+
+/*!
+ \brief configure reference signal source prescaler
+ \param[in] prescaler:
+ only one parameter can be selected which is shown as below:
+ \arg CTC_REFSOURCE_PSC_OFF: reference signal not divided
+ \arg CTC_REFSOURCE_PSC_DIV2: reference signal divided by 2
+ \arg CTC_REFSOURCE_PSC_DIV4: reference signal divided by 4
+ \arg CTC_REFSOURCE_PSC_DIV8: reference signal divided by 8
+ \arg CTC_REFSOURCE_PSC_DIV16: reference signal divided by 16
+ \arg CTC_REFSOURCE_PSC_DIV32: reference signal divided by 32
+ \arg CTC_REFSOURCE_PSC_DIV64: reference signal divided by 64
+ \arg CTC_REFSOURCE_PSC_DIV128: reference signal divided by 128
+ \param[out] none
+ \retval none
+*/
+void ctc_refsource_prescaler_config(uint32_t prescaler)
+{
+ CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPSC);
+ CTC_CTL1 |= (uint32_t)prescaler;
+}
+
+/*!
+ \brief configure clock trim base limit value
+ \param[in] limit_value: 8-bit clock trim base limit value
+ \arg 0x00-0xFF
+ \param[out] none
+ \retval none
+*/
+void ctc_clock_limit_value_config(uint8_t limit_value)
+{
+ CTC_CTL1 &= (uint32_t)(~CTC_CTL1_CKLIM);
+ CTC_CTL1 |= CTL1_CKLIM(limit_value);
+}
+
+/*!
+ \brief configure CTC counter reload value
+ \param[in] reload_value: 16-bit CTC counter reload value
+ \arg 0x0000-0xFFFF
+ \param[out] none
+ \retval none
+*/
+void ctc_counter_reload_value_config(uint16_t reload_value)
+{
+ CTC_CTL1 &= (uint32_t)(~CTC_CTL1_RLVALUE);
+ CTC_CTL1 |= (uint32_t)reload_value;
+}
+
+/*!
+ \brief enable CTC trim counter
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void ctc_counter_enable(void)
+{
+ CTC_CTL0 |= (uint32_t)CTC_CTL0_CNTEN;
+}
+
+/*!
+ \brief disable CTC trim counter
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void ctc_counter_disable(void)
+{
+ CTC_CTL0 &= (uint32_t)(~CTC_CTL0_CNTEN);
+}
+
+/*!
+ \brief configure the IRC48M trim value
+ \param[in] trim_value: 8-bit IRC48M trim value
+ \arg 0x00-0x3F
+ \param[out] none
+ \retval none
+*/
+void ctc_irc48m_trim_value_config(uint8_t trim_value)
+{
+ /* clear TRIMVALUE bits */
+ CTC_CTL0 &= (~(uint32_t)CTC_CTL0_TRIMVALUE);
+ /* set TRIMVALUE bits */
+ CTC_CTL0 |= CTL0_TRIMVALUE(trim_value);
+}
+
+/*!
+ \brief generate software reference source sync pulse
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void ctc_software_refsource_pulse_generate(void)
+{
+ CTC_CTL0 |= (uint32_t)CTC_CTL0_SWREFPUL;
+}
+
+/*!
+ \brief configure hardware automatically trim mode
+ \param[in] hardmode:
+ only one parameter can be selected which is shown as below:
+ \arg CTC_HARDWARE_TRIM_MODE_ENABLE: hardware automatically trim mode enable
+ \arg CTC_HARDWARE_TRIM_MODE_DISABLE: hardware automatically trim mode disable
+ \param[out] none
+ \retval none
+*/
+void ctc_hardware_trim_mode_config(uint32_t hardmode)
+{
+ CTC_CTL0 &= (uint32_t)(~CTC_CTL0_AUTOTRIM);
+ CTC_CTL0 |= (uint32_t)hardmode;
+}
+
+/*!
+ \brief read CTC counter capture value when reference sync pulse occurred
+ \param[in] none
+ \param[out] none
+ \retval the 16-bit CTC counter capture value
+*/
+uint16_t ctc_counter_capture_value_read(void)
+{
+ uint16_t capture_value = 0U;
+ capture_value = (uint16_t)GET_STAT_REFCAP(CTC_STAT);
+ return (capture_value);
+}
+
+/*!
+ \brief read CTC trim counter direction when reference sync pulse occurred
+ \param[in] none
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+ \arg SET: CTC trim counter direction is down-counting
+ \arg RESET: CTC trim counter direction is up-counting
+*/
+FlagStatus ctc_counter_direction_read(void)
+{
+ FlagStatus ret_status = RESET;
+ if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){
+ ret_status = SET;
+ }
+ return ret_status;
+}
+
+/*!
+ \brief read CTC counter reload value
+ \param[in] none
+ \param[out] none
+ \retval the 16-bit CTC counter reload value
+*/
+uint16_t ctc_counter_reload_value_read(void)
+{
+ uint16_t reload_value = 0U;
+ reload_value = (uint16_t)(CTC_CTL1 & CTC_CTL1_RLVALUE);
+ return (reload_value);
+}
+
+/*!
+ \brief read the IRC48M trim value
+ \param[in] none
+ \param[out] none
+ \retval the 8-bit IRC48M trim value
+*/
+uint8_t ctc_irc48m_trim_value_read(void)
+{
+ uint8_t trim_value = 0U;
+ trim_value = (uint8_t)GET_CTL0_TRIMVALUE(CTC_CTL0);
+ return (trim_value);
+}
+
+/*!
+ \brief enable the CTC interrupt
+ \param[in] interrupt: CTC interrupt enable
+ one or more parameters can be selected which are shown as below:
+ \arg CTC_INT_CKOK: clock trim OK interrupt enable
+ \arg CTC_INT_CKWARN: clock trim warning interrupt enable
+ \arg CTC_INT_ERR: error interrupt enable
+ \arg CTC_INT_EREF: expect reference interrupt enable
+ \param[out] none
+ \retval none
+*/
+void ctc_interrupt_enable(uint32_t interrupt)
+{
+ CTC_CTL0 |= (uint32_t)interrupt;
+}
+
+/*!
+ \brief disable the CTC interrupt
+ \param[in] interrupt: CTC interrupt enable source
+ one or more parameters can be selected which are shown as below:
+ \arg CTC_INT_CKOK: clock trim OK interrupt enable
+ \arg CTC_INT_CKWARN: clock trim warning interrupt enable
+ \arg CTC_INT_ERR: error interrupt enable
+ \arg CTC_INT_EREF: expect reference interrupt enable
+ \param[out] none
+ \retval none
+*/
+void ctc_interrupt_disable(uint32_t interrupt)
+{
+ CTC_CTL0 &= (uint32_t)(~(interrupt));
+}
+
+/*!
+ \brief get CTC flag
+ \param[in] flag: the CTC flag
+ only one parameter can be selected which is shown as below:
+ \arg CTC_FLAG_CKOK: clock trim OK flag
+ \arg CTC_FLAG_CKWARN: clock trim warning flag
+ \arg CTC_FLAG_ERR: error flag
+ \arg CTC_FLAG_EREF: expect reference flag
+ \arg CTC_FLAG_CKERR: clock trim error bit
+ \arg CTC_FLAG_REFMISS: reference sync pulse miss
+ \arg CTC_FLAG_TRIMERR: trim value error bit
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus ctc_flag_get(uint32_t flag)
+{
+ FlagStatus ret_status = RESET;
+
+ if(RESET != (CTC_STAT & flag)){
+ ret_status = SET;
+ }
+ return ret_status;
+}
+
+/*!
+ \brief clear CTC flag
+ \param[in] flag: the CTC flag
+ only one parameter can be selected which is shown as below:
+ \arg CTC_FLAG_CKOK: clock trim OK flag
+ \arg CTC_FLAG_CKWARN: clock trim warning flag
+ \arg CTC_FLAG_ERR: error flag
+ \arg CTC_FLAG_EREF: expect reference flag
+ \arg CTC_FLAG_CKERR: clock trim error bit
+ \arg CTC_FLAG_REFMISS: reference sync pulse miss
+ \arg CTC_FLAG_TRIMERR: trim value error bit
+ \param[out] none
+ \retval none
+*/
+void ctc_flag_clear(uint32_t flag)
+{
+ if(flag & CTC_FLAG_MASK){
+ CTC_INTC |= CTC_INTC_ERRIC;
+ }else{
+ CTC_INTC |= flag;
+ }
+}
+
+/*!
+ \brief get CTC interrupt flag
+ \param[in] interrupt: the CTC interrupt flag
+ only one parameter can be selected which is shown as below:
+ \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt
+ \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt
+ \arg CTC_INT_FLAG_ERR: error interrupt
+ \arg CTC_INT_FLAG_EREF: expect reference interrupt
+ \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt
+ \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt
+ \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus ctc_interrupt_flag_get(uint32_t interrupt)
+{
+ uint32_t ctc_int = 0U, intenable = 0U;
+ FlagStatus ret_status = RESET;
+
+ if(interrupt & CTC_FLAG_MASK){
+ intenable = CTC_CTL0 & CTC_INT_ERR;
+ }else{
+ intenable = CTC_CTL0 & interrupt;
+ }
+ ctc_int = CTC_STAT & interrupt;
+
+ if(ctc_int && intenable){
+ ret_status = SET;
+ }
+ return ret_status;
+}
+
+/*!
+ \brief clear CTC interrupt flag
+ \param[in] interrupt: the CTC interrupt flag
+ only one parameter can be selected which is shown as below:
+ \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt
+ \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt
+ \arg CTC_INT_FLAG_ERR: error interrupt
+ \arg CTC_INT_FLAG_EREF: expect reference interrupt
+ \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt
+ \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt
+ \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt
+ \param[out] none
+ \retval none
+*/
+void ctc_interrupt_flag_clear(uint32_t interrupt)
+{
+ if(interrupt & CTC_FLAG_MASK){
+ CTC_INTC |= CTC_INTC_ERRIC;
+ }else{
+ CTC_INTC |= interrupt;
+ }
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_dac.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_dac.c
new file mode 100644
index 0000000000000000000000000000000000000000..689118c41e41e458ac3e5c5c85a3ea0627de67db
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_dac.c
@@ -0,0 +1,387 @@
+/*!
+ \file gd32f3x0_dac.c
+ \brief DAC driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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.
+*/
+
+#ifdef GD32F350
+#include "gd32f3x0_dac.h"
+
+/*!
+ \brief deinitialize DAC
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_deinit(void)
+{
+ rcu_periph_reset_enable(RCU_DACRST);
+ rcu_periph_reset_disable(RCU_DACRST);
+}
+
+/*!
+ \brief enable DAC
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_enable(void)
+{
+ DAC_CTL |= DAC_CTL_DEN;
+}
+
+/*!
+ \brief disable DAC
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_disable(void)
+{
+ DAC_CTL &= ~DAC_CTL_DEN;
+}
+
+/*!
+ \brief enable DAC DMA
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_dma_enable(void)
+{
+ DAC_CTL |= DAC_CTL_DDMAEN;
+}
+
+/*!
+ \brief disable DAC DMA
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_dma_disable(void)
+{
+ DAC_CTL &= ~DAC_CTL_DDMAEN;
+}
+
+/*!
+ \brief enable DAC output buffer
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_output_buffer_enable(void)
+{
+ DAC_CTL &= ~DAC_CTL_DBOFF;
+}
+
+/*!
+ \brief disable DAC output buffer
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_output_buffer_disable(void)
+{
+ DAC_CTL |= DAC_CTL_DBOFF;
+}
+
+/*!
+ \brief enable DAC trigger
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_trigger_enable(void)
+{
+ DAC_CTL |= DAC_CTL_DTEN;
+}
+
+/*!
+ \brief disable DAC trigger
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_trigger_disable(void)
+{
+ DAC_CTL &= ~DAC_CTL_DTEN;
+}
+
+/*!
+ \brief enable DAC software trigger
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_software_trigger_enable(void)
+{
+ DAC_SWT |= DAC_SWT_SWTR;
+}
+
+/*!
+ \brief disable DAC software trigger
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_software_trigger_disable(void)
+{
+ DAC_SWT &= ~DAC_SWT_SWTR;
+}
+
+/*!
+ \brief enable DAC interrupt(DAC DMA underrun interrupt)
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_interrupt_enable(void)
+{
+ DAC_CTL |= DAC_CTL_DDUDRIE;
+}
+
+/*!
+ \brief disable DAC interrupt(DAC DMA underrun interrupt)
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_interrupt_disable(void)
+{
+ DAC_CTL &= ~DAC_CTL_DDUDRIE;
+}
+
+/*!
+ \brief set DAC tgigger source
+ \param[in] triggersource: external triggers of DAC
+ \arg DAC_TRIGGER_T1_TRGO: trigger source is TIMER1 TRGO
+ \arg DAC_TRIGGER_T2_TRGO: trigger source is TIMER2 TRGO
+ \arg DAC_TRIGGER_T5_TRGO: trigger source is TIMER5 TRGO
+ \arg DAC_TRIGGER_T14_TRGO: trigger source is TIMER14 TRGO
+ \arg DAC_TRIGGER_EXTI_9: trigger source is EXTI interrupt line9 event
+ \arg DAC_TRIGGER_SOFTWARE: software trigger
+ \param[out] none
+ \retval none
+*/
+void dac_trigger_source_config(uint32_t triggersource)
+{
+ DAC_CTL &= ~DAC_CTL_DTSEL;
+ DAC_CTL |= triggersource;
+}
+
+/*!
+ \brief configure DAC wave mode
+ \param[in] wave_mode
+ \arg DAC_WAVE_DISABLE: wave disable
+ \arg DAC_WAVE_MODE_LFSR: LFSR noise mode
+ \arg DAC_WAVE_MODE_TRIANGLE: triangle noise mode
+ \param[out] none
+ \retval none
+*/
+void dac_wave_mode_config(uint32_t wave_mode)
+{
+ DAC_CTL &= ~DAC_CTL_DWM;
+ DAC_CTL |= wave_mode;
+}
+
+/*!
+ \brief configure DAC wave bit width
+ \param[in] bit_width
+ \arg DAC_WAVE_BIT_WIDTH_1: bit width of the wave signal is 1
+ \arg DAC_WAVE_BIT_WIDTH_2: bit width of the wave signal is 2
+ \arg DAC_WAVE_BIT_WIDTH_3: bit width of the wave signal is 3
+ \arg DAC_WAVE_BIT_WIDTH_4: bit width of the wave signal is 4
+ \arg DAC_WAVE_BIT_WIDTH_5: bit width of the wave signal is 5
+ \arg DAC_WAVE_BIT_WIDTH_6: bit width of the wave signal is 6
+ \arg DAC_WAVE_BIT_WIDTH_7: bit width of the wave signal is 7
+ \arg DAC_WAVE_BIT_WIDTH_8: bit width of the wave signal is 8
+ \arg DAC_WAVE_BIT_WIDTH_9: bit width of the wave signal is 9
+ \arg DAC_WAVE_BIT_WIDTH_10: bit width of the wave signal is 10
+ \arg DAC_WAVE_BIT_WIDTH_11: bit width of the wave signal is 11
+ \arg DAC_WAVE_BIT_WIDTH_12: bit width of the wave signal is 12
+ \param[out] none
+ \retval none
+*/
+void dac_wave_bit_width_config(uint32_t bit_width)
+{
+ DAC_CTL &= ~DAC_CTL_DWBW;
+ DAC_CTL |= bit_width;
+}
+
+/*!
+ \brief configure DAC LFSR noise mode
+ \param[in] unmask_bits
+ \arg DAC_LFSR_BIT0: unmask the LFSR bit0
+ \arg DAC_LFSR_BITS1_0: unmask the LFSR bits[1:0]
+ \arg DAC_LFSR_BITS2_0: unmask the LFSR bits[2:0]
+ \arg DAC_LFSR_BITS3_0: unmask the LFSR bits[3:0]
+ \arg DAC_LFSR_BITS4_0: unmask the LFSR bits[4:0]
+ \arg DAC_LFSR_BITS5_0: unmask the LFSR bits[5:0]
+ \arg DAC_LFSR_BITS6_0: unmask the LFSR bits[6:0]
+ \arg DAC_LFSR_BITS7_0: unmask the LFSR bits[7:0]
+ \arg DAC_LFSR_BITS8_0: unmask the LFSR bits[8:0]
+ \arg DAC_LFSR_BITS9_0: unmask the LFSR bits[9:0]
+ \arg DAC_LFSR_BITS10_0: unmask the LFSR bits[10:0]
+ \arg DAC_LFSR_BITS11_0: unmask the LFSR bits[11:0]
+ \param[out] none
+ \retval none
+*/
+void dac_lfsr_noise_config(uint32_t unmask_bits)
+{
+ DAC_CTL &= ~DAC_CTL_DWBW;
+ DAC_CTL |= unmask_bits;
+}
+
+/*!
+ \brief configure DAC triangle noise mode
+ \param[in] amplitude
+ \arg DAC_TRIANGLE_AMPLITUDE_1: triangle amplitude is 1
+ \arg DAC_TRIANGLE_AMPLITUDE_3: triangle amplitude is 3
+ \arg DAC_TRIANGLE_AMPLITUDE_7: triangle amplitude is 7
+ \arg DAC_TRIANGLE_AMPLITUDE_15: triangle amplitude is 15
+ \arg DAC_TRIANGLE_AMPLITUDE_31: triangle amplitude is 31
+ \arg DAC_TRIANGLE_AMPLITUDE_63: triangle amplitude is 63
+ \arg DAC_TRIANGLE_AMPLITUDE_127: triangle amplitude is 127
+ \arg DAC_TRIANGLE_AMPLITUDE_255: triangle amplitude is 255
+ \arg DAC_TRIANGLE_AMPLITUDE_511: triangle amplitude is 511
+ \arg DAC_TRIANGLE_AMPLITUDE_1023: triangle amplitude is 1023
+ \arg DAC_TRIANGLE_AMPLITUDE_2047: triangle amplitude is 2047
+ \arg DAC_TRIANGLE_AMPLITUDE_4095: triangle amplitude is 4095
+ \param[out] none
+ \retval none
+*/
+void dac_triangle_noise_config(uint32_t amplitude)
+{
+ DAC_CTL &= ~DAC_CTL_DWBW;
+ DAC_CTL |= amplitude;
+}
+
+/*!
+ \brief get DAC output value
+ \param[in] none
+ \param[out] none
+ \retval DAC output data
+*/
+uint16_t dac_output_value_get(void)
+{
+ uint16_t data = 0U;
+ data = (uint16_t)DAC_DO;
+ return data;
+}
+
+/*!
+ \brief get the specified DAC flag(DAC DMA underrun flag)
+ \param[in] none
+ \param[out] none
+ \retval the state of dac bit(SET or RESET)
+*/
+FlagStatus dac_flag_get(void)
+{
+ /* check the DMA underrun flag */
+ if((uint8_t)RESET != (DAC_STAT & DAC_STAT_DDUDR)){
+ return SET;
+ }else{
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear the specified DAC flag(DAC DMA underrun flag)
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_flag_clear(void)
+{
+ DAC_STAT |= DAC_STAT_DDUDR;
+}
+
+/*!
+ \brief get the specified DAC interrupt flag(DAC DMA underrun interrupt flag)
+ \param[in] none
+ \param[out] none
+ \retval the state of DAC interrupt flag(SET or RESET)
+*/
+FlagStatus dac_interrupt_flag_get(void)
+{
+ FlagStatus temp_flag = RESET;
+ uint32_t ddudr_flag = 0U, ddudrie_flag = 0U;
+ /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */
+ ddudr_flag = DAC_STAT & DAC_STAT_DDUDR;
+ ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE;
+ if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){
+ temp_flag = SET;
+ }
+ return temp_flag;
+}
+
+/*!
+ \brief clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag)
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void dac_interrupt_flag_clear(void)
+{
+ DAC_STAT |= DAC_STAT_DDUDR;
+}
+
+/*!
+ \brief set DAC data holding register value
+ \param[in] dac_align
+ \arg DAC_ALIGN_8B_R: data right 8b alignment
+ \arg DAC_ALIGN_12B_R: data right 12b alignment
+ \arg DAC_ALIGN_12B_L: data left 12b alignment
+ \param[in] data: data to be loaded
+ \param[out] none
+ \retval none
+*/
+void dac_data_set(uint32_t dac_align, uint16_t data)
+{
+ switch(dac_align){
+ /* data right 12b alignment */
+ case DAC_ALIGN_12B_R:
+ DAC_R12DH = data;
+ break;
+ /* data left 12b alignment */
+ case DAC_ALIGN_12B_L:
+ DAC_L12DH = data;
+ break;
+ /* data right 8b alignment */
+ case DAC_ALIGN_8B_R:
+ DAC_R8DH = data;
+ break;
+ default:
+ break;
+ }
+}
+#endif /* GD32F350 */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_dbg.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_dbg.c
new file mode 100644
index 0000000000000000000000000000000000000000..1ff7928c80f0d22986969e92bcbf3fac503863c1
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_dbg.c
@@ -0,0 +1,131 @@
+/*!
+ \file gd32f3x0_dbg.c
+ \brief DBG driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_dbg.h"
+
+#define DBG_RESET_VAL ((uint32_t)0x00000000U) /*!< DBG reset value */
+
+/*!
+ \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:
+ one or more parameters can be selected which are shown as below:
+ \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:
+ one or more parameters can be selected which are shown as below:
+ \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: refer to dbg_periph_enum
+ one or more parameters can be selected which are shown as below:
+ \arg DBG_SLEEP_HOLD: keep debugger connection during sleep mode
+ \arg DBG_DEEPSLEEP_HOLD: keep debugger connection during deepsleep mode
+ \arg DBG_STANDBY_HOLD: keep debugger connection during standby mode
+ \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted
+ \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted
+ \arg DBG_TIMERx_HOLD (x=0,1,2,5,13,14,15,16,TIMER5 is only available in GD32F350): hold TIMERx counter when core is halted
+ \arg DBG_I2Cx_HOLD (x=0,1): hold I2Cx 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: refer to dbg_periph_enum
+ one or more parameters can be selected which are shown as below:
+ \arg DBG_SLEEP_HOLD: keep debugger connection during sleep mode
+ \arg DBG_DEEPSLEEP_HOLD: keep debugger connection during deepsleep mode
+ \arg DBG_STANDBY_HOLD: keep debugger connection during standby mode
+ \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted
+ \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted
+ \arg DBG_TIMERx_HOLD (x=0,1,2,5,13,14,15,16,TIMER5 is only available in GD32F350): hold TIMERx counter when core is halted
+ \arg DBG_I2Cx_HOLD (x=0,1): hold I2Cx 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));
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_dma.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_dma.c
new file mode 100644
index 0000000000000000000000000000000000000000..971a0b72b6654f145ad1cf42f86d41f45646bec8
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_dma.c
@@ -0,0 +1,561 @@
+/*!
+ \file gd32f3x0_dma.c
+ \brief DMA driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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
+ only one parameter can be selected which is shown as below:
+ \arg DMA_CHx(x=0..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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..6)
+ \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;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_exti.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_exti.c
new file mode 100644
index 0000000000000000000000000000000000000000..e14ed36472d90d521539de8092885b9734447d60
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_exti.c
@@ -0,0 +1,253 @@
+/*!
+ \file gd32f3x0_exti.c
+ \brief EXTI driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_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, enable the configuration of EXTI initialize
+ \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..19,21,22): 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 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 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 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 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..19,21,22): 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..19,21,22): EXTI line x
+ \param[out] none
+ \retval none
+*/
+void exti_software_interrupt_disable(exti_line_enum linex)
+{
+ EXTI_SWIEV &= ~(uint32_t)linex;
+}
+
+/*!
+ \brief get EXTI line x 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..19,21,22): 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 line x 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..19,21,22): EXTI line x
+ \param[out] none
+ \retval none
+*/
+void exti_flag_clear(exti_line_enum linex)
+{
+ EXTI_PD = (uint32_t)linex;
+}
+
+/*!
+ \brief get EXTI line x 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..19,21,22): 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 line x 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..19,21,22): EXTI line x
+ \param[out] none
+ \retval none
+*/
+void exti_interrupt_flag_clear(exti_line_enum linex)
+{
+ EXTI_PD = (uint32_t)linex;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_fmc.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_fmc.c
new file mode 100644
index 0000000000000000000000000000000000000000..e1341fa363be95d00bafbb490cff11dde63ea435
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_fmc.c
@@ -0,0 +1,888 @@
+/*!
+ \file gd32f3x0_fmc.c
+ \brief FMC driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_fmc.h"
+
+/* FMC main memory programming functions */
+
+/*!
+ \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
+ only one parameter can be selected which is shown as below:
+ \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 fmc wait state enable
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fmc_wait_state_enable(void)
+{
+ /* unlock the main flash */
+ fmc_unlock();
+
+ /* set the WSEN bit in register FMC_WSEN */
+ FMC_WSEN |= FMC_WSEN_WSEN;
+
+ /* lock the main flash after operation */
+ fmc_lock();
+}
+
+/*!
+ \brief fmc wait state disable
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void fmc_wait_state_disable(void)
+{
+ /* unlock the main flash */
+ fmc_unlock();
+
+ /* reset the WSEN bit in register FMC_WSEN */
+ FMC_WSEN &= ~FMC_WSEN_WSEN;
+
+ /* lock the main flash after operation */
+ fmc_lock();
+}
+
+/*!
+ \brief erase page
+ \param[in] page_address: target page start address
+ \param[out] none
+ \retval fmc_state
+*/
+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
+*/
+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 word at the corresponding address
+ \param[in] address: address to program
+ \param[in] data: word to program
+ \param[out] none
+ \retval fmc_state
+*/
+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 program a half word at the corresponding address
+ \param[in] address: address to program
+ \param[in] data: word to program
+ \param[out] none
+ \retval fmc_state
+*/
+fmc_state_enum fmc_halfword_program(uint32_t address, uint16_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;
+
+ REG16(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 program a word at the corresponding address without erasing
+ \param[in] address: address to program
+ \param[in] data: word to program
+ \param[out] none
+ \retval fmc_state
+*/
+fmc_state_enum fmc_word_reprogram(uint32_t address, uint32_t data)
+{
+ fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ FMC_WSEN |= FMC_WSEN_BPEN;
+
+ 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;
+}
+
+/* FMC option bytes programming functions */
+
+/*!
+ \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;
+ }
+}
+
+/*!
+ \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 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
+*/
+fmc_state_enum ob_erase(void)
+{
+ uint16_t fmc_spc;
+
+ 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;
+ }
+
+ 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 = fmc_spc;
+ OB_USER = OB_USER_DEFAULT;
+
+ /* 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) depending on current option byte
+ \param[in] ob_wp: write protection configuration data
+ setting the bit of ob_wp means enabling the corresponding sector write protection
+ \param[out] none
+ \retval fmc_state
+*/
+fmc_state_enum ob_write_protection_enable(uint16_t ob_wp)
+{
+ uint8_t ob_wrp0, ob_wrp1;
+ ob_parm_struct ob_parm;
+ fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ ob_parm_get(&ob_parm);
+ ob_wp = (uint16_t)(~ob_wp);
+ ob_wrp0 = (uint8_t)(ob_wp & OB_LWP);
+ ob_wrp1 = (uint8_t)((ob_wp & OB_HWP) >> 8U);
+
+ if(0xFFU == (uint8_t)OB_WP0){
+ if (0xFFU == (uint8_t)OB_WP1){
+ if(FMC_READY == fmc_state){
+ /* set the OBPG bit*/
+ FMC_CTL |= FMC_CTL_OBPG;
+
+ if(0xFFU != ob_wrp0){
+ OB_WP0 = ob_wrp0 ;
+ /* wait for the FMC ready */
+ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ }
+
+ if((FMC_READY == fmc_state) && (0xFFU != ob_wrp1)){
+ OB_WP1 = ob_wrp1 ;
+ /* 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_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_value_modify(OB_WP_ADDR0, ob_wp ,&ob_parm);
+ /* 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 configure security protection
+ \param[in] ob_spc: specify security protection code
+ only one parameter can be selected which is shown as below:
+ \arg FMC_NSPC: no security protection
+ \arg FMC_LSPC: low security protection
+ \arg FMC_HSPC: high security protection
+ \param[out] none
+ \retval fmc_state
+*/
+fmc_state_enum ob_security_protection_config(uint8_t ob_spc)
+{
+ fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+ ob_parm_struct ob_parm;
+ ob_parm_get(&ob_parm);
+
+ /* 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;
+ }
+
+ 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_value_modify(OB_SPC_ADDR, (uint16_t)ob_spc ,&ob_parm);
+ /* 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 depending on current option byte
+ \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: generate a reset instead of entering deepsleep mode
+ \arg OB_STDBY_RST: generate a reset instead of 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
+*/
+fmc_state_enum ob_user_write(uint8_t ob_user)
+{
+ /* check whether FMC is ready or not */
+ fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ ob_parm_struct ob_parm;
+ ob_parm_get(&ob_parm);
+
+ 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_value_modify(OB_USER_ADDR, (uint16_t)ob_user, &ob_parm);
+
+ /* 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 program the FMC data option byte
+ \param[in] address: OB_DATA_ADDR0 or OB_DATA_ADDR1
+ only one parameter can be selected which is shown as below:
+ \arg OB_DATA_ADDR0: option byte data address 0
+ \arg OB_DATA_ADDR1: option byte data address 1
+ \param[in] data: the byte to be programmed
+ \param[out] none
+ \retval fmc_state
+*/
+fmc_state_enum ob_data_program(uint32_t address, uint8_t data)
+{
+ fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ ob_parm_struct ob_parm;
+ ob_parm_get(&ob_parm);
+ if(0xFFU == REG8(address))
+ {
+ if(FMC_READY == fmc_state){
+ /* set the OBPG bit */
+ FMC_CTL |= FMC_CTL_OBPG;
+
+ REG16(address) = data ;
+
+ /* 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_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_value_modify(address, (uint16_t)data ,&ob_parm);
+ /* 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 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 >> 8U);
+}
+
+/*!
+ \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 >> 16U);
+}
+
+/*!
+ \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
+ one or more parameters can be selected which are shown as below:
+ \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
+ one or more parameters can be selected which are shown as below:
+ \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_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
+ only one parameter can be selected which is shown as below:
+ \arg FMC_FLAG_PGERR: FMC programming 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 flag set or reset
+ \param[in] flag: check FMC flag
+ only one parameter can be selected which is shown as below:
+ \arg FMC_FLAG_PGERR: FMC programming 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_interrupt_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
+ only one parameter can be selected which is shown as below:
+ \arg FMC_FLAG_PGERR: FMC programming 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_interrupt_flag_clear(uint32_t flag)
+{
+ /* clear the flags */
+ FMC_STAT = 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;
+}
+
+/*!
+ \brief get current option byte value
+ \param[in] ob_parm: pointer to option byte parameter struct
+ \param[out] ob_parm: pointer to option byte parameter struct
+ \retval none
+*/
+void ob_parm_get(ob_parm_struct *ob_parm)
+{
+ /* get current option byte value */
+ ob_parm->spc = (uint8_t)OB_SPC;
+ ob_parm->user = (uint8_t)OB_USER;
+ ob_parm->data0 = (uint8_t)OB_DATA0;
+ ob_parm->data1 = (uint8_t)OB_DATA1;
+ ob_parm->wp0 = (uint8_t)OB_WP0;
+ ob_parm->wp1 = (uint8_t)OB_WP1;
+}
+
+/*!
+ \brief modify the target option byte depending on the original value
+ \param[in] address: target option byte address
+ \param[in] value: target option byte value
+ \param[in] ob_parm: pointer to option byte parameter struct
+ \param[out] none
+ \retval none
+*/
+void ob_value_modify(uint32_t address, uint16_t value,ob_parm_struct *ob_parm)
+{
+ uint8_t spc, user, data0, data1, wp0, wp1;
+ /* store the original option bytes */
+ spc = ob_parm->spc;
+ user = ob_parm->user;
+ data0 = ob_parm->data0;
+ data1 = ob_parm->data1;
+ wp0 = ob_parm->wp0;
+ wp1 = ob_parm->wp1;
+
+ /* bring in the target option byte */
+ if(OB_SPC_ADDR == address){
+ spc = (uint8_t)value;
+ }else if(OB_DATA_ADDR0 == address){
+ data0 = (uint8_t)value;
+ }else if(OB_DATA_ADDR1 == address){
+ data1 = (uint8_t)value;
+ }else if(OB_USER_ADDR == address){
+ user = user & (uint8_t)value;
+ }else{
+ wp0 = wp0 & ((uint8_t) (value));
+ wp1 = wp1 & ((uint8_t) (value >> 8U));
+ }
+ /* basing on original value, modify the target option byte */
+ OB_SPC = spc;
+ OB_USER = user;
+ if(0xFFU != data0){
+ OB_DATA0 = data0;
+ }
+ if(0xFFU != data1){
+ OB_DATA1 = data1;
+ }
+ if(0xFFU != wp0){
+ OB_WP0 = wp0;
+ }
+ if(0xFFU != wp1){
+ OB_WP1 = wp1;
+ }
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_fwdgt.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_fwdgt.c
new file mode 100644
index 0000000000000000000000000000000000000000..a3fcc3c564f64baa4f71dac8f74703106785995d
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_fwdgt.c
@@ -0,0 +1,180 @@
+/*!
+ \file gd32f3x0_fwdgt.c
+ \brief FWDGT driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_fwdgt.h"
+
+/*!
+ \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 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) && (RESET != flag_status));
+
+ if (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) && (RESET != flag_status));
+
+ if (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) && (RESET != flag_status));
+
+ if (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(FWDGT_STAT & flag){
+ return SET;
+ }
+ return RESET;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_gpio.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..6af393fe13d3c0189f188ba825ccc611fe28d841
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_gpio.c
@@ -0,0 +1,424 @@
+/*!
+ \file gd32f3x0_gpio.c
+ \brief GPIO driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_gpio.h"
+
+/*!
+ \brief reset GPIO port
+ \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,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 GPIOD:
+ /* reset GPIOD */
+ rcu_periph_reset_enable(RCU_GPIODRST);
+ rcu_periph_reset_disable(RCU_GPIODRST);
+ 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,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,F)
+ \param[in] mode: gpio pin mode
+ only one parameter can be selected which is shown as below:
+ \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
+ only one parameter can be selected which is shown as below:
+ \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,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,F)
+ \param[in] otype: gpio pin output mode
+ only one parameter can be selected which is shown as below:
+ \arg GPIO_OTYPE_PP: push pull mode
+ \arg GPIO_OTYPE_OD: open drain mode
+ \param[in] speed: gpio pin output max speed
+ only one parameter can be selected which is shown as below:
+ \arg GPIO_OSPEED_2MHZ: output max speed 2MHz
+ \arg GPIO_OSPEED_10MHZ: output max speed 10MHz
+ \arg GPIO_OSPEED_50MHZ: output max speed 50MHz
+ \arg GPIO_OSPEED_MAX: GPIO very high output speed, max speed more than 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 ospeed0,ospeed1;
+
+ 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 */
+ ospeed0 = GPIO_OSPD0(gpio_periph);
+
+ if(GPIO_OSPEED_MAX == speed){
+ ospeed1 = GPIO_OSPD1(gpio_periph);
+
+ for(i = 0U;i < 16U;i++){
+ if((1U << i) & pin){
+ /* enable very high output speed function of the pin when the corresponding OSPDy(y=0..15)
+ is "11" (output max speed 50MHz) */
+ ospeed0 |= GPIO_OSPEED_SET(i,0x03);
+ ospeed1 |= (1U << i);
+ }
+ }
+ GPIO_OSPD0(gpio_periph) = ospeed0;
+ GPIO_OSPD1(gpio_periph) = ospeed1;
+ }else{
+ for(i = 0U;i < 16U;i++){
+ if((1U << i) & pin){
+ /* clear the specified pin output speed bits */
+ ospeed0 &= ~GPIO_OSPEED_MASK(i);
+ /* set the specified pin output speed bits */
+ ospeed0 |= GPIO_OSPEED_SET(i,speed);
+ }
+ }
+ GPIO_OSPD0(gpio_periph) = ospeed0;
+ }
+}
+
+/*!
+ \brief set GPIO pin bit
+ \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,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,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,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,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,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
+ only one parameter can be selected which is shown as below:
+ \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,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,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,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,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,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,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,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,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,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,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
+ only one parameter can be selected which is shown as below:
+ \arg GPIO_AF_0: TIMER2, TIMER13, TIMER14, TIMER16, SPI0, SPI1, I2S0, CK_OUT, USART0, CEC,
+ IFRP, TSI, CTC, I2C0, I2C1, SWDIO, SWCLK
+ \arg GPIO_AF_1: USART0, USART1, TIMER2, TIMER14, I2C0, I2C1, IFRP, CEC
+ \arg GPIO_AF_2: TIMER0, TIMER1, TIMER15, TIMER16, I2S0
+ \arg GPIO_AF_3: TSI, I2C0, TIMER14
+ \arg GPIO_AF_4(port A,B only): USART1, I2C0, I2C1, TIMER13
+ \arg GPIO_AF_5(port A,B only): TIMER15, TIMER16, USBFS, I2S0
+ \arg GPIO_AF_6(port A,B only): CTC, SPI1
+ \arg GPIO_AF_7(port A,B only): CMP0, CMP1
+ \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,D,F)
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,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
+ only one parameter can be selected which is shown as below:
+ \arg GPIOx(x = A,B,C,D,F)
+ \param[out] none
+ \retval none
+*/
+void gpio_port_toggle(uint32_t gpio_periph)
+{
+ GPIO_TG(gpio_periph) = 0x0000FFFFU;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_i2c.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_i2c.c
new file mode 100644
index 0000000000000000000000000000000000000000..2f428b1881da9ff69bc9a126c463b9d8a07e4f89
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_i2c.c
@@ -0,0 +1,729 @@
+/*!
+ \file gd32f3x0_i2c.c
+ \brief I2C driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_i2c.h"
+
+/* I2C register bit mask */
+#define I2CCLK_MAX ((uint32_t)0x0000003FU) /*!< 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 position of ACK and PEC when receiving
+ \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 whether to enable I2C PEC calculation or not
+ \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 whether ARP is enabled under SMBus
+ \param[in] i2c_periph: I2Cx(x=0,1)
+ \param[in] arpstate:
+ 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 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
+ \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
+ \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
+ \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: interrupt type
+ 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
+ \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
+ \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
+ \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));
+ }
+}
+
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_misc.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_misc.c
new file mode 100644
index 0000000000000000000000000000000000000000..d467c32b825d5498679718fc860555d0622fcdef
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_misc.c
@@ -0,0 +1,189 @@
+/*!
+ \file gd32f3x0_misc.c
+ \brief MISC driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_misc.h"
+
+/*!
+ \brief set the priority group
+ \param[in] nvic_prigroup: the NVIC priority group
+ only one parameter can be selected which is shown as below:
+ \arg NVIC_PRIGROUP_PRE0_SUB4:0 bits for pre-emption priority 4 bits for subpriority
+ \arg NVIC_PRIGROUP_PRE1_SUB3:1 bits for pre-emption priority 3 bits for subpriority
+ \arg NVIC_PRIGROUP_PRE2_SUB2:2 bits for pre-emption priority 2 bits for subpriority
+ \arg NVIC_PRIGROUP_PRE3_SUB1:3 bits for pre-emption priority 1 bits for subpriority
+ \arg NVIC_PRIGROUP_PRE4_SUB0:4 bits for pre-emption priority 0 bits for subpriority
+ \param[out] none
+ \retval none
+*/
+void nvic_priority_group_set(uint32_t nvic_prigroup)
+{
+ /* set the priority group value */
+ SCB->AIRCR = NVIC_AIRCR_VECTKEY_MASK | nvic_prigroup;
+}
+
+/*!
+ \brief enable NVIC request
+ \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
+ \param[in] nvic_irq_pre_priority: the pre-emption priority needed to set
+ \param[in] nvic_irq_sub_priority: the subpriority needed to set
+ \param[out] none
+ \retval none
+*/
+void nvic_irq_enable(uint8_t nvic_irq,
+ uint8_t nvic_irq_pre_priority,
+ uint8_t nvic_irq_sub_priority)
+{
+ uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U;
+
+ /* use the priority group value to get the temp_pre and the temp_sub */
+ switch ((SCB->AIRCR) & (uint32_t)0x700U) {
+ case NVIC_PRIGROUP_PRE0_SUB4:
+ temp_pre = 0U;
+ temp_sub = 0x4U;
+ break;
+ case NVIC_PRIGROUP_PRE1_SUB3:
+ temp_pre = 1U;
+ temp_sub = 0x3U;
+ break;
+ case NVIC_PRIGROUP_PRE2_SUB2:
+ temp_pre = 2U;
+ temp_sub = 0x2U;
+ break;
+ case NVIC_PRIGROUP_PRE3_SUB1:
+ temp_pre = 3U;
+ temp_sub = 0x1U;
+ break;
+ case NVIC_PRIGROUP_PRE4_SUB0:
+ temp_pre = 4U;
+ temp_sub = 0x0U;
+ break;
+ default:
+ nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
+ temp_pre = 2U;
+ temp_sub = 0x2U;
+ break;
+ }
+
+ /* get the temp_priority to fill the NVIC->IP register */
+ temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre);
+ temp_priority |= nvic_irq_sub_priority &(0x0FU >> (0x4U - temp_sub));
+ temp_priority = temp_priority << 0x04U;
+ NVIC->IP[nvic_irq] = (uint8_t)temp_priority;
+
+ /* enable the selected IRQ */
+ NVIC->ISER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU);
+}
+
+/*!
+ \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->ICER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU);
+}
+
+/*!
+ \brief set the NVIC vector table base address
+ \param[in] nvic_vict_tab: the RAM or FLASH base address
+ only one parameter can be selected which is shown as below:
+ \arg NVIC_VECTTAB_RAM: RAM base address
+ \are 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
+ only one parameter can be selected which is shown as below:
+ \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
+ only one parameter can be selected which is shown as below:
+ \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
+ only one parameter can be selected which is shown as below:
+ \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;
+ }
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_pmu.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_pmu.c
new file mode 100644
index 0000000000000000000000000000000000000000..c537c600da8394f62d498baa1959e74c692d8b0a
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_pmu.c
@@ -0,0 +1,407 @@
+/*!
+ \file gd32f3x0_pmu.c
+ \brief PMU driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_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_MID: LDO output voltage mid 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 enable low-driver mode in deep-sleep mode
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void pmu_lowdriver_mode_enable(void)
+{
+ PMU_CTL &= ~PMU_CTL_LDEN;
+ PMU_CTL |= PMU_LOWDRIVER_ENABLE;
+}
+
+/*!
+ \brief disable low-driver mode in deep-sleep mode
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void pmu_lowdriver_mode_disable(void)
+{
+ PMU_CTL &= ~PMU_CTL_LDEN;
+ PMU_CTL |= PMU_LOWDRIVER_DISABLE;
+}
+
+/*!
+ \brief enable high-driver mode
+ this bit set by software only when IRC8M or HXTAL used as system clock
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void pmu_highdriver_mode_enable(void)
+{
+ PMU_CTL |= PMU_CTL_HDEN;
+}
+
+/*!
+ \brief disable high-driver mode
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void pmu_highdriver_mode_disable(void)
+{
+ PMU_CTL &= ~PMU_CTL_HDEN;
+}
+
+/*!
+ \brief switch high-driver mode
+ this bit set by software only when IRC8M or HXTAL used as system clock
+ \param[in] highdr_switch:
+ only one parameter can be selected which is shown as below:
+ \arg PMU_HIGHDR_SWITCH_NONE: disable high-driver mode switch
+ \arg PMU_HIGHDR_SWITCH_EN: enable high-driver mode switch
+ \param[out] none
+ \retval none
+*/
+void pmu_highdriver_switch_select(uint32_t highdr_switch)
+{
+ /* wait for HDRF flag to be set */
+ while(SET != pmu_flag_get(PMU_FLAG_HDR)){
+ }
+ PMU_CTL &= ~PMU_CTL_HDS;
+ PMU_CTL |= highdr_switch;
+}
+
+/*!
+ \brief low-driver mode when use low power LDO
+ \param[in] mode:
+ only one parameter can be selected which is shown as below:
+ \arg PMU_NORMALDR_LOWPWR: normal-driver when use low power LDO
+ \arg PMU_LOWDR_LOWPWR: low-driver mode enabled when LDEN is 11 and use low power LDO
+ \param[out] none
+ \retval none
+*/
+void pmu_lowpower_driver_config(uint32_t mode)
+{
+ PMU_CTL &= ~PMU_CTL_LDLP;
+ PMU_CTL |= mode;
+}
+
+/*!
+ \brief low-driver mode when use normal power LDO
+ \param[in] mode:
+ only one parameter can be selected which is shown as below:
+ \arg PMU_NORMALDR_NORMALPWR: normal-driver when use low power LDO
+ \arg PMU_LOWDR_NORMALPWR: low-driver mode enabled when LDEN is 11 and use low power LDO
+ \param[out] none
+ \retval none
+*/
+void pmu_normalpower_driver_config(uint32_t mode)
+{
+ PMU_CTL &= ~PMU_CTL_LDNP;
+ PMU_CTL |= mode;
+}
+
+/*!
+ \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-M4 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[ 4 ];
+ /* 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-M4 system control register */
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+
+ reg_snap[ 0 ] = REG32( 0xE000E010U );
+ reg_snap[ 1 ] = REG32( 0xE000E100U );
+ reg_snap[ 2 ] = REG32( 0xE000E104U );
+ reg_snap[ 3 ] = REG32( 0xE000E108U );
+
+ REG32( 0xE000E010U ) &= 0x00010004U;
+ REG32( 0xE000E180U ) = 0XB7FFEF19U;
+ REG32( 0xE000E184U ) = 0XFFFFFBFFU;
+ REG32( 0xE000E188U ) = 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 ] ;
+ REG32( 0xE000E108U ) = reg_snap[ 3 ] ;
+
+ /* reset sleepdeep bit of Cortex-M4 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-M4 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_PIN4: WKUP Pin 4 (PC5)
+ \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_PIN4: WKUP Pin 4 (PC5)
+ \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
+ \arg PMU_FLAG_LDOVSR: LDO voltage select ready flag
+ \arg PMU_FLAG_HDR: high-driver ready flag
+ \arg PMU_FLAG_HDSR: high-driver switch ready flag
+ \arg PMU_FLAG_LDR: low-driver mode ready 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;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_rcu.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_rcu.c
new file mode 100644
index 0000000000000000000000000000000000000000..980092bd5f969455077bb440f2d65a8698db49fd
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_rcu.c
@@ -0,0 +1,1204 @@
+/*!
+ \file gd32f3x0_rcu.c
+ \brief RCU driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_rcu.h"
+
+/* define clock source */
+#define SEL_IRC8M ((uint32_t)0x00000000U)
+#define SEL_HXTAL ((uint32_t)0x00000001U)
+#define SEL_PLL ((uint32_t)0x00000002U)
+
+/* 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);
+#if (defined(GD32F350))
+ RCU_CFG0 &= ~(RCU_CFG0_USBFSPSC);
+ RCU_CFG2 &= ~(RCU_CFG2_CECSEL | RCU_CFG2_USBFSPSC2);
+#endif /* GD32F350 */
+ RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS);
+ RCU_CFG1 &= ~(RCU_CFG1_PREDV | RCU_CFG1_PLLMF5 | RCU_CFG1_PLLPRESEL);
+ RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_ADCSEL);
+ RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV;
+ RCU_CFG2 &= ~RCU_CFG2_ADCPSC2;
+ RCU_CTL1 &= ~RCU_CTL1_IRC28MEN;
+ RCU_ADDCTL &= ~RCU_ADDCTL_IRC48MEN;
+ RCU_INT = 0x00000000U;
+ RCU_ADDINT = 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,D,F): GPIO ports clock
+ \arg RCU_DMA: DMA clock
+ \arg RCU_CRC: CRC clock
+ \arg RCU_TSI: TSI clock
+ \arg RCU_CFGCMP: CFGCMP clock
+ \arg RCU_ADC: ADC clock
+ \arg RCU_TIMERx (x=0,1,2,5,13,14,15,16): TIMER clock (RCU_TIMER5 only for GD32F350)
+ \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_USBFS: USBFS clock (only for GD32F350)
+ \arg RCU_PMU: PMU clock
+ \arg RCU_DAC: DAC clock (only for GD32F350)
+ \arg RCU_CEC: CEC clock (only for GD32F350)
+ \arg RCU_CTC: CTC clock
+ \arg RCU_RTC: RTC 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,D,F): GPIO ports clock
+ \arg RCU_DMA: DMA clock
+ \arg RCU_CRC: CRC clock
+ \arg RCU_TSI: TSI clock
+ \arg RCU_CFGCMP: CFGCMP clock
+ \arg RCU_ADC: ADC clock
+ \arg RCU_TIMERx (x=0,1,2,5,13,14,15,16): TIMER clock (RCU_TIMER5 only for GD32F350)
+ \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_USBFS: USBFS clock (only for GD32F350)
+ \arg RCU_PMU: PMU clock
+ \arg RCU_DAC: DAC clock (only for GD32F350)
+ \arg RCU_CEC: CEC clock (only for GD32F350)
+ \arg RCU_CTC: CTC clock
+ \arg RCU_RTC: RTC 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,D,F): reset GPIO ports
+ \arg RCU_TSIRST: reset TSI
+ \arg RCU_CFGCMPRST: reset CFGCMP
+ \arg RCU_ADCRST: reset ADC
+ \arg RCU_TIMERxRST (x=0,1,2,5,13,14,15,16): reset TIMER (RCU_TIMER5 only for GD32F350)
+ \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_USBFSRST: reset USBFS (only for GD32F350)
+ \arg RCU_PMURST: reset PMU
+ \arg RCU_DACRST: reset DAC (only for GD32F350)
+ \arg RCU_CECRST: reset CEC (only for GD32F350)
+ \arg RCU_CTCRST: reset CTC
+ \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,D,F): reset GPIO ports
+ \arg RCU_TSIRST: reset TSI
+ \arg RCU_CFGCMPRST: reset CFGCMP
+ \arg RCU_ADCRST: reset ADC
+ \arg RCU_TIMERxRST (x=0,1,2,5,13,14,15,16): reset TIMER (RCU_TIMER5 only for GD32F350)
+ \arg RCU_SPIxRST (x=0,1,2): reset SPI
+ \arg RCU_USARTxRST (x=0,1): reset USART
+ \arg RCU_WWDGTRST: reset WWDGT
+ \arg RCU_I2CxRST (x=0,1,2): reset I2C
+ \arg RCU_USBFSRST: reset USBFS (only for GD32F350)
+ \arg RCU_PMURST: reset PMU
+ \arg RCU_DACRST: reset DAC (only for GD32F350)
+ \arg RCU_CECRST: reset CEC (only for GD32F350)
+ \arg RCU_CTCRST: reset CTC
+ \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
+ only one parameter can be selected which is shown as below:
+ \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 USBFS clock prescaler selection
+ \param[in] ck_usbfs: USBFS clock prescaler selection
+ only one parameter can be selected which is shown as below:
+ \arg RCU_USBFS_CKPLL_DIV1_5: select CK_PLL/1.5 as CK_USBFS
+ \arg RCU_USBFS_CKPLL_DIV1: select CK_PLL as CK_USBFS
+ \arg RCU_USBFS_CKPLL_DIV2_5: select CK_PLL/2.5 as CK_USBFS
+ \arg RCU_USBFS_CKPLL_DIV2: select CK_PLL/2 as CK_USBFS
+ \arg RCU_USBFS_CKPLL_DIV3: select CK_PLL/3 as CK_USBFS
+ \arg RCU_USBFS_CKPLL_DIV3_5: select CK_PLL/3.5 as CK_USBFS
+ \param[out] none
+ \retval none
+*/
+void rcu_usbfs_clock_config(uint32_t ck_usbfs)
+{
+ /* reset the USBFSPSC bits and set according to ck_usbfs */
+ RCU_CFG0 &= ~RCU_CFG0_USBFSPSC;
+ RCU_CFG2 &= ~RCU_CFG2_USBFSPSC2;
+
+ RCU_CFG0 |= (ck_usbfs & (~RCU_CFG2_USBFSPSC2));
+ RCU_CFG2 |= (ck_usbfs & RCU_CFG2_USBFSPSC2);
+}
+
+/*!
+ \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 preselection
+ \param[in] pll_presel: PLL clock source preselection
+ only one parameter can be selected which is shown as below:
+ \arg RCU_PLLPRESEL_IRC48M: select IRC48M as PLL preselection clock
+ \arg RCU_PLLPRESEL_HXTAL: select HXTAL as PLL preselection clock
+ \param[out] none
+ \retval none
+*/
+void rcu_pll_preselection_config(uint32_t pll_presel)
+{
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL);
+ RCU_CFG1 |= pll_presel;
+}
+
+/*!
+ \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_IRC48M: select HXTAL or IRC48M 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..64): 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_CFG1 &= ~(RCU_CFG1_PLLMF5);
+ RCU_CFG0 |= (pll_src | (pll_mul & (~RCU_CFG1_PLLMF5)));
+ RCU_CFG1 |= (pll_mul & RCU_CFG1_PLLMF5);
+}
+
+/*!
+ \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 CEC clock source selection
+ \param[in] ck_cec: CEC clock source selection
+ only one parameter can be selected which is shown as below:
+ \arg RCU_CECSRC_IRC8M_DIV244: CK_CEC select CK_IRC8M/244
+ \arg RCU_CECSRC_LXTAL: CK_CEC select CK_LXTAL
+ \param[out] none
+ \retval none
+*/
+void rcu_cec_clock_config(uint32_t ck_cec)
+{
+ /* reset the CECSEL bit and set according to ck_cec */
+ RCU_CFG2 &= ~RCU_CFG2_CECSEL;
+ RCU_CFG2 |= ck_cec;
+}
+
+/*!
+ \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 CK48M clock source selection
+ \param[in] ck48m_clock_source: CK48M clock source selection
+ only one parameter can be selected which is shown as below:
+ \arg RCU_CK48MSRC_PLL48M: CK_PLL48M selected as CK48M source clock
+ \arg RCU_CK48MSRC_IRC48M: CK_IRC48M selected as CK48M source clock
+ \param[out] none
+ \retval none
+*/
+void rcu_ck48m_clock_config(uint32_t ck48m_clock_source)
+{
+ uint32_t reg;
+
+ reg = RCU_ADDCTL;
+ /* reset the CK48MSEL bit and set according to ck48m_clock_source */
+ reg &= ~RCU_ADDCTL_CK48MSEL;
+ RCU_ADDCTL = (reg | ck48m_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 or IRC48M 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 HXTALPREDV 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_IRC48MSTB: IRC48M 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_IRC48MSTB: IRC48M 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_IRC48MSTB_CLR: IRC48M 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
+ \arg RCU_INT_IRC48MSTB: IRC48M 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
+ \arg RCU_INT_IRC48MSTB: IRC48M 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_IRC48M: IRC48M
+ \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++;
+ }
+ 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 IRC48M stable */
+ case RCU_IRC48M:
+ while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){
+ osci_stat = rcu_flag_get(RCU_FLAG_IRC48MSTB);
+ stb_cnt++;
+ }
+
+ /* check whether flag is set or not */
+ if (RESET != rcu_flag_get(RCU_FLAG_IRC48MSTB)){
+ 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_IRC48M: IRC48M
+ \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_IRC48M: IRC48M
+ \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_IRC48M:
+ 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_IRC48M:
+ 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_0_7: the core voltage is 0.7V
+ \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_CEC: CEC clock frequency
+ \arg CK_USART: USART clock frequency
+ \param[out] none
+ \retval clock frequency of system, AHB, APB1, APB2, ADC, CEC or USRAT
+*/
+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, cec_freq = 0U, usart_freq = 0U;
+ uint32_t pllmf = 0U, pllmf4 = 0U, pllmf5 = 0U, pllsel = 0U, pllpresel = 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);
+ pllmf5 = GET_BITS(RCU_CFG1, 31, 31);
+ /* high 16 bits */
+ if(1U == pllmf4){
+ pllmf += 17U;
+ }else{
+ if(pllmf == 15U){
+ pllmf += 1U;
+ }else{
+ pllmf += 2U;
+ }
+ }
+ if(1U == pllmf5){
+ pllmf += 31U;
+ }
+
+ /* PLL clock source selection, HXTAL or IRC48M or IRC8M/2 */
+ pllsel = GET_BITS(RCU_CFG0, 16, 16);
+ pllpresel = GET_BITS(RCU_CFG1, 30, 30);
+ if(0U != pllsel){
+ prediv = (GET_BITS(RCU_CFG1,0, 3) + 1U);
+ if(0U == pllpresel){
+ cksys_freq = (HXTAL_VALUE / prediv) * pllmf;
+ }else{
+ cksys_freq = (IRC48M_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);
+ switch(adcps){
+ case 0:
+ if(0U == adcps2){
+ adc_freq = apb2_freq / 2U;
+ }else{
+ adc_freq = ahb_freq / 3U;
+ }
+ break;
+ case 1:
+ if(0U == adcps2){
+ adc_freq = apb2_freq / 4U;
+ }else{
+ adc_freq = ahb_freq / 5U;
+ }
+ break;
+ case 2:
+ if(0U == adcps2){
+ adc_freq = apb2_freq / 6U;
+ }else{
+ adc_freq = ahb_freq / 7U;
+ }
+ break;
+ case 3:
+ if(0U == adcps2){
+ adc_freq = apb2_freq / 8U;
+ }else{
+ adc_freq = ahb_freq / 9U;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ ck_freq = adc_freq;
+ break;
+ case CK_CEC:
+ /* calculate CEC clock frequency */
+ if(RCU_CECSRC_LXTAL != (RCU_CFG2 & RCU_CFG2_CECSEL)){
+ cec_freq = IRC8M_VALUE / 244U;
+ }else{
+ cec_freq = LXTAL_VALUE;
+ }
+ ck_freq = cec_freq;
+ break;
+ case CK_USART:
+ /* calculate USART 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;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_rtc.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_rtc.c
new file mode 100644
index 0000000000000000000000000000000000000000..5b7a3f59e1a652f46cbddf143cb54a4ea6eef14f
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_rtc.c
@@ -0,0 +1,966 @@
+/*!
+ \file gd32f3x0_rtc.c
+ \brief RTC driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_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(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) && (RESET == flag_status));
+
+ if(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(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) && (RESET == flag_status));
+
+ if(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 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 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) && (RESET == flag_status));
+
+ if(RESET != flag_status){
+ error_status = SUCCESS;
+ }
+
+ /* enable the write protection */
+ RTC_WPK = RTC_LOCK_KEY;
+
+ return error_status;
+}
+
+/*!
+ \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(RESET != (RTC_STAT & flag)){
+ flag_state = SET;
+ }
+ return flag_state;
+}
+
+/*!
+ \brief clear specified flag
+ \param[in] flag: specify which flag to clear
+ \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 1Hz 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(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) && (RESET != flag_status));
+
+ if(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 ajust 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 ajust 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) && (RESET != flag_status));
+
+ temp = RTC_CTL & RTC_CTL_REFEN;
+ /* check if the function of reference clock detection is disabled */
+ if((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;
+}
+
+
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_spi.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_spi.c
new file mode 100644
index 0000000000000000000000000000000000000000..3aa2f3deb3503c13293f03d2bccd0a88117a11e1
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_spi.c
@@ -0,0 +1,792 @@
+/*!
+ \file gd32f3x0_spi.c
+ \brief SPI driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_spi.h"
+
+#define SPI_INIT_MASK ((uint32_t)0x00003040U) /*!< SPI parameter initialization mask */
+#define I2S_INIT_MASK ((uint32_t)0x0000F047U) /*!< I2S parameter initialization mask */
+
+#define SPI_I2SPSC_DEFAULT_VALUE ((uint32_t)0x00000002U) /*!< default value of SPI_I2SPSC register */
+
+/*!
+ \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_16BIT, SPI_FRAMESIZE_8BIT
+ 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 none
+*/
+void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct)
+{
+ uint32_t reg = 0U;
+ reg = SPI_CTL0(spi_periph);
+ reg &= SPI_INIT_MASK;
+
+ /* select SPI as master or slave */
+ reg |= spi_struct->device_mode;
+ /* select SPI transfer mode */
+ reg |= spi_struct->trans_mode;
+ /* select SPI frame size */
+ reg |= spi_struct->frame_size;
+ /* select SPI NSS use hardware or software */
+ reg |= spi_struct->nss;
+ /* select SPI LSB or MSB */
+ reg |= spi_struct->endian;
+ /* select SPI polarity and phase */
+ reg |= spi_struct->clock_polarity_phase;
+ /* select SPI prescale to adjust transmit speed */
+ reg |= spi_struct->prescale;
+
+ /* write to SPI_CTL0 register */
+ SPI_CTL0(spi_periph) = (uint32_t)reg;
+
+ /* select SPI mode */
+ SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL);
+}
+
+/*!
+ \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);
+}
+
+
+#ifdef GD32F350
+/*!
+ \brief initialize I2S parameter
+ \param[in] spi_periph: SPI0
+ \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: SPI0
+ \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_DEFAULT_VALUE;
+
+ /* 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: SPI0
+ \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: SPI0
+ \param[out] none
+ \retval none
+*/
+void i2s_disable(uint32_t spi_periph)
+{
+ SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN);
+}
+
+#endif /* GD32F350 */
+
+/*!
+ \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_16BIT: SPI frame size is 16 bits
+ \arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits
+ \param[out] none
+ \retval none
+*/
+void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format)
+{
+ /* clear SPI_CTL0_FF16 bit */
+ SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16);
+ /* confige SPI_CTL0_FF16 bit */
+ SPI_CTL0(spi_periph) |= (uint32_t)frame_format;
+}
+
+/*!
+ \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)
+{
+ SPI_DATA(spi_periph) = (uint32_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)
+{
+ 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 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
+ \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: SPI1
+ \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: SPI1
+ \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: SPI1
+ \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: SPI1
+ \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: SPI1
+ \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: SPI1
+ \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
+ \arg I2S_FLAG_FERR: format error interrupt flag
+ \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{
+ 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);
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_syscfg.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_syscfg.c
new file mode 100644
index 0000000000000000000000000000000000000000..7a4aef5fc63e47a883e6a7b7e3dc35e24fca97ea
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_syscfg.c
@@ -0,0 +1,227 @@
+/*!
+ \file gd32f3x0_syscfg.c
+ \brief SYSCFG driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_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
+ one or more parameters can be selected which is shown as below:
+ \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
+ \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
+ one or more parameters can be selected which is shown as below:
+ \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
+ \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
+ only one parameter can be selected which is shown as below:
+ \arg EXTI_SOURCE_GPIOx(x = A,B,C,D,F): EXTI GPIO port
+ \param[in] exti_pin: specify the EXTI line
+ only one parameter can be selected which is shown as below:
+ \arg EXTI_SOURCE_PINx(x = 0..15): 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
+ one or more parameters can be selected which is shown as below:
+ \arg SYSCFG_LOCK_LOCKUP: Cortex-M4 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 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;
+}
+
+/*!
+ \brief configure the I/O compensation cell
+ \param[in] syscfg_compensation: specifies the I/O compensation cell mode
+ only one parameter can be selected which is shown as below:
+ \arg SYSCFG_COMPENSATION_ENABLE: I/O compensation cell is enabled
+ \arg SYSCFG_COMPENSATION_DISABLE: I/O compensation cell is disabled
+ \param[out] none
+ \retval none
+*/
+void syscfg_compensation_config(uint32_t syscfg_compensation)
+{
+ uint32_t reg;
+
+ reg = SYSCFG_CPSCTL;
+ /* reset the SYSCFG_CPSCTL_CPS_EN bit and set according to syscfg_compensation */
+ reg &= ~SYSCFG_CPSCTL_CPS_EN;
+ SYSCFG_CPSCTL = (reg | syscfg_compensation);
+}
+
+/*!
+ \brief check if the I/O compensation cell ready flag is set or not
+ \param[in] none
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+ */
+FlagStatus syscfg_cps_rdy_flag_get(void)
+{
+ if(((uint32_t)RESET) != (SYSCFG_CPSCTL & SYSCFG_CPSCTL_CPS_RDY)){
+ return SET;
+ }else{
+ return RESET;
+ }
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_timer.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_timer.c
new file mode 100644
index 0000000000000000000000000000000000000000..0e34c5961888abe4df3187e8b32f29fde4861593
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_timer.c
@@ -0,0 +1,2063 @@
+/*!
+ \file gd32f3x0_timer.c
+ \brief TIMER driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+
+ 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 "gd32f3x0_timer.h"
+
+/*!
+ \brief deinit a TIMER
+ \param[in] timer_periph: TIMERx(x=0..2,13..16),TIMER5 just for GD32F350
+ \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 TIMER1:
+ /* reset TIMER1 */
+ rcu_periph_reset_enable(RCU_TIMER1RST);
+ rcu_periph_reset_disable(RCU_TIMER1RST);
+ break;
+ case TIMER2:
+ /* reset TIMER2 */
+ rcu_periph_reset_enable(RCU_TIMER2RST);
+ rcu_periph_reset_disable(RCU_TIMER2RST);
+ break;
+#ifdef GD32F350
+ case TIMER5:
+ /* reset TIMER5 */
+ rcu_periph_reset_enable(RCU_TIMER5RST);
+ rcu_periph_reset_disable(RCU_TIMER5RST);
+ break;
+#endif
+ 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,13..16),TIMER5 just for GD32F350
+ \param[in] timer_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,(TIMER1 32 bit)
+ 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) || (TIMER1 == 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) || (TIMER1 == 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,13..16),TIMER5 just for GD32F350
+ \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,13..16),TIMER5 just for GD32F350
+ \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,13..16),TIMER5 just for GD32F350
+ \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,13..16),TIMER5 just for GD32F350
+ \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,13..16),TIMER5 just for GD32F350
+ \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,13..16),TIMER5 just for GD32F350
+ \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,13..16),TIMER5 just for GD32F350
+ \param[in] prescaler: prescaler value
+ \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,13..16),TIMER5 just for GD32F350
+ \param[in] autoreload: the counter auto-reload value
+ \param[out] none
+ \retval none
+*/
+void timer_autoreload_value_config(uint32_t timer_periph, uint32_t autoreload)
+{
+ TIMER_CAR(timer_periph) = (uint32_t)autoreload;
+}
+
+/*!
+ \brief configure TIMER counter register value
+ \param[in] timer_periph: TIMERx(x=0..2,13..16),TIMER5 just for GD32F350
+ \param[in] counter: the counter value
+ \param[out] none
+ \retval none
+*/
+void timer_counter_value_config(uint32_t timer_periph, uint32_t counter)
+{
+ TIMER_CNT(timer_periph) = (uint32_t)counter;
+}
+
+/*!
+ \brief read TIMER counter value
+ \param[in] timer_periph: TIMERx(x=0..2,13..16),TIMER5 just for GD32F350
+ \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,13..16),TIMER5 just for GD32F350
+ \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,14..16),TIMER5 just for GD32F350
+ \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, uint8_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,13..16),TIMER5 just for GD32F350
+ \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, uint8_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,13..16),TIMER5 just for GD32F350
+ \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 disable, TIMERx(x=0..2,13..16),TIMER5 just for GD32F350
+ \arg TIMER_INT_CH0: channel 0 interrupt disable, TIMERx(x=0..2,13..16)
+ \arg TIMER_INT_CH1: channel 1 interrupt disable, TIMERx(x=0..2,14)
+ \arg TIMER_INT_CH2: channel 2 interrupt disable, TIMERx(x=0..2)
+ \arg TIMER_INT_CH3: channel 3 interrupt disable , TIMERx(x=0..2)
+ \arg TIMER_INT_CMT: commutation interrupt disable, TIMERx(x=0,14..16)
+ \arg TIMER_INT_TRG: trigger interrupt disable, TIMERx(x=0..2,14)
+ \arg TIMER_INT_BRK: break interrupt disable, 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,13..16),TIMER5 just for GD32F350
+ \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,13..16),TIMER5 just for GD32F350
+ \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,13..16),TIMER5 just for GD32F350
+ \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,13..16),TIMER5 just for GD32F350
+ \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,14..16),TIMER5 just for GD32F350
+ \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,14..16),TIMER5 just for GD32F350
+ \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)
+ \arg TIMER_DMACFG_DMATA_DMATB: DMA transfer address is TIMER_DMATB, 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,13..16), TIMER5 just for GD32F350
+ \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)(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)(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)(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=1,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, uint8_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,14),TIMER5 just for GD32F350
+ \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,14),TIMER5 just for GD32F350)
+ \arg TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output(TIMERx(x=0..2,14),TIMER5 just for GD32F350)
+ \arg TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output(TIMERx(x=0..2,14),TIMER5 just for GD32F350)
+ \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, uint8_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 */
+ }
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_tsi.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_tsi.c
new file mode 100644
index 0000000000000000000000000000000000000000..5a0bf95fec60086126681747fa371d54c8fb5886
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_tsi.c
@@ -0,0 +1,686 @@
+/*!
+ \file gd32f3x0_tsi.c
+ \brief TSI driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_tsi.h"
+
+/*!
+ \brief reset TSI peripheral
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void tsi_deinit(void)
+{
+ rcu_periph_reset_enable(RCU_TSIRST);
+ rcu_periph_reset_disable(RCU_TSIRST);
+}
+
+/*!
+ \brief initialize TSI plus prescaler,charge plus,transfer plus,max cycle number
+ \param[in] prescaler: CTCLK clock division factor
+ only one parameter can be selected which is shown as below:
+ \arg TSI_CTCDIV_DIV1: fCTCLK = fHCLK
+ \arg TSI_CTCDIV_DIV2: fCTCLK = fHCLK/2
+ \arg TSI_CTCDIV_DIV4: fCTCLK = fHCLK/4
+ \arg TSI_CTCDIV_DIV8: fCTCLK = fHCLK/8
+ \arg TSI_CTCDIV_DIV16: fCTCLK = fHCLK/16
+ \arg TSI_CTCDIV_DIV32: fCTCLK = fHCLK/32
+ \arg TSI_CTCDIV_DIV64: fCTCLK = fHCLK/64
+ \arg TSI_CTCDIV_DIV128: fCTCLK = fHCLK/128
+ \arg TSI_CTCDIV_DIV256: fCTCLK = fHCLK/256
+ \arg TSI_CTCDIV_DIV512: fCTCLK = fHCLK/512
+ \arg TSI_CTCDIV_DIV1024: fCTCLK = fHCLK/1024
+ \arg TSI_CTCDIV_DIV2048: fCTCLK = fHCLK/2048
+ \arg TSI_CTCDIV_DIV4096: fCTCLK = fHCLK/4096
+ \arg TSI_CTCDIV_DIV8192: fCTCLK = fHCLK/8192
+ \arg TSI_CTCDIV_DIV16384: fCTCLK = fHCLK/16384
+ \arg TSI_CTCDIV_DIV32768: fCTCLK = fHCLK/32768
+ \param[in] charge_duration: charge state duration time
+ only one parameter can be selected which is shown as below:
+ \arg TSI_CHARGE_1CTCLK(x=1..16): the duration time of charge state is x CTCLK
+ \param[in] transfer_duration: charge transfer state duration time
+ only one parameter can be selected which is shown as below:
+ \arg TSI_TRANSFER_xCTCLK(x=1..16): the duration time of transfer state is x CTCLK
+ \param[in] max_number: max cycle number
+ only one parameter can be selected which is shown as below:
+ \arg TSI_MAXNUM255: the max cycle number of a sequence is 255
+ \arg TSI_MAXNUM511: the max cycle number of a sequence is 511
+ \arg TSI_MAXNUM1023: the max cycle number of a sequence is 1023
+ \arg TSI_MAXNUM2047: the max cycle number of a sequence is 2047
+ \arg TSI_MAXNUM4095: the max cycle number of a sequence is 4095
+ \arg TSI_MAXNUM8191: the max cycle number of a sequence is 8191
+ \arg TSI_MAXNUM16383: the max cycle number of a sequence is 16383
+ \param[out] none
+ \retval none
+*/
+void tsi_init(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration,uint32_t max_number)
+{
+ uint32_t ctl0,ctl1;
+ if(RESET == (TSI_CTL0 & TSI_CTL0_TSIS)){
+ if(TSI_CTCDIV_DIV256 > prescaler){
+ /* config TSI_CTL0 */
+ ctl0 = TSI_CTL0;
+ /*configure TSI clock division factor,charge state duration time,charge transfer state duration time */
+ ctl0 &= ~(TSI_CTL0_CTCDIV|TSI_CTL0_CTDT|TSI_CTL0_CDT|TSI_CTL0_MCN);
+ ctl0 |= ((prescaler<<12U)|charge_duration|transfer_duration|max_number);
+ TSI_CTL0 = ctl0;
+
+ /* config TSI_CTL1 */
+ ctl1 = TSI_CTL1;
+ ctl1 &= ~TSI_CTL1_CTCDIV;
+ TSI_CTL1 = ctl1;
+ }else{
+ /* config TSI_CTL0 */
+ ctl0 = TSI_CTL0;
+ prescaler &= ~0x08U;
+ /*configure TSI clock division factor,charge state duration time,charge transfer state duration time */
+ ctl0 &= ~(TSI_CTL0_CTCDIV|TSI_CTL0_CTDT|TSI_CTL0_CDT|TSI_CTL0_MCN);
+ ctl0 |= ((prescaler<<12U)|charge_duration|transfer_duration|max_number);
+ TSI_CTL0 = ctl0;
+
+ /* config TSI_CTL1 */
+ ctl1 = TSI_CTL1;
+ ctl1 |= TSI_CTL1_CTCDIV;
+ TSI_CTL1 = ctl1;
+ }
+ }
+}
+
+/*!
+ \brief enable TSI module
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void tsi_enable(void)
+{
+ TSI_CTL0 |= TSI_CTL0_TSIEN;
+}
+
+/*!
+ \brief disable TSI module
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void tsi_disable(void)
+{
+ TSI_CTL0 &= ~TSI_CTL0_TSIEN;
+}
+
+/*!
+ \brief enable sample pin
+ \param[in] sample: sample pin
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_SAMPCFG_GxPy( x=0..5,y=0..3):pin y of group x is sample pin
+ \param[out] none
+ \retval none
+*/
+void tsi_sample_pin_enable(uint32_t sample)
+{
+ if(RESET == (TSI_CTL0 & TSI_CTL0_TSIS)){
+ TSI_SAMPCFG |= sample;
+ }
+}
+
+/*!
+ \brief disable sample pin
+ \param[in] sample: sample pin
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_SAMPCFG_GxPy( x=0..5,y=0..3): pin y of group x is sample pin
+ \param[out] none
+ \retval none
+*/
+void tsi_sample_pin_disable(uint32_t sample)
+{
+ if(RESET == (TSI_CTL0 & TSI_CTL0_TSIS)){
+ TSI_SAMPCFG &= ~sample;
+ }
+}
+
+/*!
+ \brief enable channel pin
+ \param[in] channel: channel pin
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_CHCFG_GxPy( x=0..5,y=0..3): pin y of group x
+ \param[out] none
+ \retval none
+*/
+void tsi_channel_pin_enable(uint32_t channel)
+{
+ TSI_CHCFG |= channel;
+}
+
+/*!
+ \brief disable channel pin
+ \param[in] channel: channel pin
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_CHCFG_GxPy( x=0..5,y=0..3): pin y of group x
+ \param[out] none
+ \retval none
+*/
+void tsi_channel_pin_disable(uint32_t channel)
+{
+ TSI_CHCFG &= ~channel;
+}
+
+/*!
+ \brief configure TSI triggering by software
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void tsi_sofeware_mode_config(void)
+{
+ if(RESET == (TSI_CTL0 & TSI_CTL0_TSIS)){
+ TSI_CTL0 &= ~TSI_CTL0_TRGMOD;
+ }
+}
+
+/*!
+ \brief start a charge-transfer sequence when TSI is in software trigger mode
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void tsi_software_start(void)
+{
+ TSI_CTL0 |= TSI_CTL0_TSIS;
+}
+
+/*!
+ \brief stop a charge-transfer sequence when TSI is in software trigger mode
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void tsi_software_stop(void)
+{
+ TSI_CTL0 &= ~TSI_CTL0_TSIS;
+}
+
+/*!
+ \brief configure TSI triggering by hardware
+ \param[in] trigger_edge: the edge type in hardware trigger mode
+ only one parameter can be selected which is shown as below:
+ \arg TSI_FALLING_TRIGGER: falling edge trigger TSI charge transfer sequence
+ \arg TSI_RISING_TRIGGER: rising edge trigger TSI charge transfer sequence
+ \param[out] none
+ \retval none
+*/
+void tsi_hardware_mode_config(uint8_t trigger_edge)
+{
+ if(RESET == (TSI_CTL0 & TSI_CTL0_TSIS)){
+ /*enable hardware mode*/
+ TSI_CTL0 |= TSI_CTL0_TRGMOD;
+ /*configure the edge type in hardware trigger mode*/
+ if(TSI_FALLING_TRIGGER == trigger_edge){
+ TSI_CTL0 &= ~TSI_CTL0_EGSEL;
+ }else{
+ TSI_CTL0 |= TSI_CTL0_EGSEL;
+ }
+ }
+}
+
+/*!
+ \brief configure TSI pin mode when charge-transfer sequence is IDLE
+ \param[in] pin_mode: pin mode when charge-transfer sequence is IDLE
+ only one parameter can be selected which is shown as below:
+ \arg TSI_OUTPUT_LOW: TSI pin will output low when IDLE
+ \arg TSI_INPUT_FLOATING: TSI pin will keep input_floating when IDLE
+ \param[out] none
+ \retval none
+*/
+void tsi_pin_mode_config(uint8_t pin_mode)
+{
+ if(RESET == (TSI_CTL0 & TSI_CTL0_TSIS)){
+ if(TSI_OUTPUT_LOW == pin_mode){
+ TSI_CTL0 &= ~TSI_CTL0_PINMOD;
+ }else{
+ TSI_CTL0 |= TSI_CTL0_PINMOD;
+ }
+ }
+}
+
+/*!
+ \brief configure extend charge state
+ \param[in] extend: enable or disable extend charge state
+ only one parameter can be selected which is shown as below:
+ \arg ENABLE: enable extend charge state
+ \arg DISABLE: disable extend charge state
+ \param[in] prescaler: ECCLK clock division factor
+ only one parameter can be selected which is shown as below:
+ \arg TSI_EXTEND_DIV1: fECCLK = fHCLK
+ \arg TSI_EXTEND_DIV2: fECCLK = fHCLK/2
+ \arg TSI_EXTEND_DIV3: fECCLK = fHCLK/3
+ \arg TSI_EXTEND_DIV4: fECCLK = fHCLK/4
+ \arg TSI_EXTEND_DIV5: fECCLK = fHCLK/5
+ \arg TSI_EXTEND_DIV6: fECCLK = fHCLK/6
+ \arg TSI_EXTEND_DIV7: fECCLK = fHCLK/7
+ \arg TSI_EXTEND_DIV8: fECCLK = fHCLK/8
+ \param[in] max_duration: value range 1...128,extend charge state maximum duration time is 1*tECCLK~128*tECCLK
+ \param[out] none
+ \retval none
+*/
+void tsi_extend_charge_config(ControlStatus extend,uint8_t prescaler,uint32_t max_duration)
+{
+ uint32_t ctl0,ctl1;
+ if(RESET == (TSI_CTL0 & TSI_CTL0_TSIS)){
+ if(DISABLE == extend){
+ /*disable extend charge state*/
+ TSI_CTL0 &= ~TSI_CTL0_ECEN;
+ }else{
+ if(TSI_EXTEND_DIV3 > prescaler){
+ /*configure extend charge state maximum duration time*/
+ ctl0 = TSI_CTL0;
+ ctl0 &= ~TSI_CTL0_ECDT;
+ ctl0 |= TSI_EXTENDMAX((max_duration-1U));
+ TSI_CTL0 = ctl0;
+ /*configure ECCLK clock division factor*/
+ ctl0 = TSI_CTL0;
+ ctl0 &= ~TSI_CTL0_ECDIV;
+ ctl0 |= (uint32_t)prescaler<<15U;
+ TSI_CTL0 = ctl0;
+ /*enable extend charge state*/
+ TSI_CTL0 |= TSI_CTL0_ECEN;
+ }else{
+ /*configure extend charge state maximum duration time*/
+ ctl0 = TSI_CTL0;
+ ctl0 &= ~TSI_CTL0_ECDT;
+ ctl0 |= TSI_EXTENDMAX((max_duration-1U));
+ TSI_CTL0 = ctl0;
+ /*configure ECCLK clock division factor*/
+ ctl0 = TSI_CTL0;
+ ctl0 &= ~TSI_CTL0_ECDIV;
+ ctl0 |= (prescaler & 0x01U)<<15U;
+ TSI_CTL0 = ctl0;
+ ctl1 = TSI_CTL1;
+ ctl1 &= ~TSI_CTL1_ECDIV;
+ ctl1 |= (prescaler & 0x06U)<<28U;
+ TSI_CTL1 = ctl1;
+ /*enable extend charge state*/
+ TSI_CTL0 |= TSI_CTL0_ECEN;
+ }
+ }
+ }
+}
+
+/*!
+ \brief configure charge plus and transfer plus
+ \param[in] prescaler: CTCLK clock division factor
+ only one parameter can be selected which is shown as below:
+ \arg TSI_CTCDIV_DIV1: fCTCLK = fHCLK
+ \arg TSI_CTCDIV_DIV2: fCTCLK = fHCLK/2
+ \arg TSI_CTCDIV_DIV4: fCTCLK = fHCLK/4
+ \arg TSI_CTCDIV_DIV8: fCTCLK = fHCLK/8
+ \arg TSI_CTCDIV_DIV16: fCTCLK = fHCLK/16
+ \arg TSI_CTCDIV_DIV32: fCTCLK = fHCLK/32
+ \arg TSI_CTCDIV_DIV64: fCTCLK = fHCLK/64
+ \arg TSI_CTCDIV_DIV128: fCTCLK = fHCLK/128
+ \arg TSI_CTCDIV_DIV256: fCTCLK = fHCLK/256
+ \arg TSI_CTCDIV_DIV512: fCTCLK = fHCLK/512
+ \arg TSI_CTCDIV_DIV1024: fCTCLK = fHCLK/1024
+ \arg TSI_CTCDIV_DIV2048: fCTCLK = fHCLK/2048
+ \arg TSI_CTCDIV_DIV4096: fCTCLK = fHCLK/4096
+ \arg TSI_CTCDIV_DIV8192: fCTCLK = fHCLK/8192
+ \arg TSI_CTCDIV_DIV16384: fCTCLK = fHCLK/16384
+ \arg TSI_CTCDIV_DIV32768: fCTCLK = fHCLK/32768
+ \param[in] charge_duration: charge state duration time
+ only one parameter can be selected which is shown as below:
+ \arg TSI_CHARGE_xCTCLK(x=1..16): the duration time of charge state is x CTCLK
+ \param[in] transfer_duration: charge transfer state duration time
+ only one parameter can be selected which is shown as below:
+ \arg TSI_TRANSFER_xCTCLK(x=1..16): the duration time of transfer state is x CTCLK
+ \param[out] none
+ \retval none
+*/
+void tsi_plus_config(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration)
+{
+ uint32_t ctl0,ctl1;
+ if(RESET == (TSI_CTL0 & TSI_CTL0_TSIS)){
+ if(TSI_CTCDIV_DIV256 > prescaler){
+ /* config TSI_CTL0 */
+ ctl0 = TSI_CTL0;
+ /*configure TSI clock division factor,charge state duration time,charge transfer state duration time */
+ ctl0 &= ~(TSI_CTL0_CTCDIV|TSI_CTL0_CTDT|TSI_CTL0_CDT);
+ ctl0 |= ((prescaler<<12U)|charge_duration|transfer_duration);
+ TSI_CTL0 = ctl0;
+
+ /* config TSI_CTL1 */
+ ctl1 = TSI_CTL1;
+ ctl1 &= ~TSI_CTL1_CTCDIV;
+ TSI_CTL1 = ctl1;
+ }else{
+ /* config TSI_CTL */
+ ctl0 = TSI_CTL0;
+ prescaler &= ~0x08U;
+ /*configure TSI clock division factor,charge state duration time,charge transfer state duration time */
+ ctl0 &= ~(TSI_CTL0_CTCDIV|TSI_CTL0_CTDT|TSI_CTL0_CDT);
+ ctl0 |= ((prescaler<<12U)|charge_duration|transfer_duration);
+ TSI_CTL0 = ctl0;
+
+ /* config TSI_CTL2 */
+ ctl1 = TSI_CTL1;
+ ctl1 |= TSI_CTL1_CTCDIV;
+ TSI_CTL1 = ctl1;
+ }
+ }
+}
+
+/*!
+ \brief configure the max cycle number of a charge-transfer sequence
+ \param[in] max_number: max cycle number
+ only one parameter can be selected which is shown as below:
+ \arg TSI_MAXNUM255: the max cycle number of a sequence is 255
+ \arg TSI_MAXNUM511: the max cycle number of a sequence is 511
+ \arg TSI_MAXNUM1023: the max cycle number of a sequence is 1023
+ \arg TSI_MAXNUM2047: the max cycle number of a sequence is 2047
+ \arg TSI_MAXNUM4095: the max cycle number of a sequence is 4095
+ \arg TSI_MAXNUM8191: the max cycle number of a sequence is 8191
+ \arg TSI_MAXNUM16383: the max cycle number of a sequence is 16383
+ \param[out] none
+ \retval none
+*/
+void tsi_max_number_config(uint32_t max_number)
+{
+ if(RESET == (TSI_CTL0 & TSI_CTL0_TSIS)){
+ uint32_t maxnum;
+ maxnum = TSI_CTL0;
+ /*configure the max cycle number of a charge-transfer sequence*/
+ maxnum &= ~TSI_CTL0_MCN;
+ maxnum |= max_number;
+ TSI_CTL0 = maxnum;
+ }
+}
+
+/*!
+ \brief switch on hysteresis pin
+ \param[in] group_pin: select pin which will be switched on hysteresis
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_PHM_GxPy(x=0..5,y=0..3): pin y of group x switch on hysteresis
+ \param[out] none
+ \retval none
+*/
+void tsi_hysteresis_on(uint32_t group_pin)
+{
+ TSI_PHM |= group_pin;
+}
+
+/*!
+ \brief switch off hysteresis pin
+ \param[in] group_pin: select pin which will be switched off hysteresis
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_PHM_GxPy(x=0..5,y=0..3): pin y of group x switch off hysteresis
+ \param[out] none
+ \retval none
+*/
+void tsi_hysteresis_off(uint32_t group_pin)
+{
+ TSI_PHM &= ~group_pin;
+}
+
+/*!
+ \brief switch on analog pin
+ \param[in] group_pin: select pin which will be switched on analog
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_ASW_GxPy(x=0..5,y=0..3):pin y of group x switch on analog
+ \param[out] none
+ \retval none
+*/
+void tsi_analog_on(uint32_t group_pin)
+{
+ TSI_ASW |= group_pin;
+}
+
+/*!
+ \brief switch off analog pin
+ \param[in] group_pin: select pin which will be switched off analog
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_ASW_GxPy(x=0..5,y=0..3):pin y of group x switch off analog
+ \param[out] none
+ \retval none
+*/
+void tsi_analog_off(uint32_t group_pin)
+{
+ TSI_ASW &= ~group_pin;
+}
+
+/*!
+ \brief enable TSI interrupt
+ \param[in] source: select interrupt which will be enabled
+ only one parameter can be selected which is shown as below:
+ \arg TSI_INT_CCTCF: charge-transfer complete flag interrupt enable
+ \arg TSI_INT_MNERR: max cycle number error interrupt enable
+ \param[out] none
+ \retval none
+*/
+void tsi_interrupt_enable(uint32_t source)
+{
+ TSI_INTEN |= source;
+}
+
+/*!
+ \brief disable TSI interrupt
+ \param[in] source: select interrupt which will be disabled
+ only one parameter can be selected which is shown as below:
+ \arg TSI_INT_CCTCF: charge-transfer complete flag interrupt disable
+ \arg TSI_INT_MNERR: max cycle number error interrupt disable
+ \param[out] none
+ \retval none
+*/
+void tsi_interrupt_disable(uint32_t source)
+{
+ TSI_INTEN &= ~source;
+}
+
+/*!
+ \brief clear TSI interrupt flag
+ \param[in] flag: select flag which will be cleared
+ only one parameter can be selected which is shown as below:
+ \arg TSI_INT_FLAG_CTCF_CLR: clear charge-transfer complete flag
+ \arg TSI_INT_FLAG_MNERR_CLR: clear max cycle number error
+ \param[out] none
+ \retval none
+*/
+void tsi_interrupt_flag_clear(uint32_t flag)
+{
+ TSI_INTC |= flag;
+}
+
+/*!
+ \brief get TSI interrupt flag
+ \param[in] flag:
+ only one parameter can be selected which is shown as below:
+ \arg TSI_INT_FLAG_CTCF: charge-transfer complete flag
+ \arg TSI_INT_FLAG_MNERR: max Cycle Number Error
+ \param[out] none
+ \retval FlagStatus:SET or RESET
+*/
+FlagStatus tsi_interrupt_flag_get(uint32_t flag)
+{
+ uint32_t interrupt_enable = 0U,interrupt_flag = 0U;
+ interrupt_flag = (TSI_INTF & flag);
+ interrupt_enable = (TSI_INTEN & flag);
+ if(interrupt_flag && interrupt_enable){
+ return SET;
+ }else{
+ return RESET;
+ }
+}
+
+/*!
+ \brief clear flag
+ \param[in] flag: select flag which will be cleared
+ only one parameter can be selected which is shown as below:
+ \arg TSI_FLAG_CTCF_CLR: clear charge-transfer complete flag
+ \arg TSI_FLAG_MNERR_CLR: clear max cycle number error
+ \param[out] none
+ \retval none
+*/
+void tsi_flag_clear(uint32_t flag)
+{
+ TSI_INTC |= flag;
+}
+
+/*!
+ \brief get flag
+ \param[in] flag:
+ only one parameter can be selected which is shown as below:
+ \arg TSI_FLAG_CTCF: charge-transfer complete flag
+ \arg TSI_FLAG_MNERR: max Cycle Number Error
+ \param[out] none
+ \retval FlagStatus:SET or RESET
+*/
+FlagStatus tsi_flag_get(uint32_t flag)
+{
+ FlagStatus flag_status;
+ if(TSI_INTF & flag){
+ flag_status = SET;
+ }else{
+ flag_status = RESET;
+ }
+ return flag_status;
+}
+
+/*!
+ \brief enbale group
+ \param[in] group: select group to be enabled
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_GCTL_GEx(x=0..5): the x group will be enabled
+ \param[out] none
+ \retval none
+*/
+void tsi_group_enable(uint32_t group)
+{
+ TSI_GCTL |= group;
+}
+
+/*!
+ \brief disbale group
+ \param[in] group: select group to be disabled
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_GCTL_GEx(x=0..5):the x group will be disabled
+ \param[out] none
+ \retval none
+*/
+void tsi_group_disable(uint32_t group)
+{
+ TSI_GCTL &= ~group;
+}
+
+/*!
+ \brief get group complete status
+ \param[in] group: select group
+ one or more parameters can be selected which are shown as below:
+ \arg TSI_GCTL_GCx(x=0..5): get the complete status of group x
+ \param[out] none
+ \retval FlagStatus: group complete status,SET or RESET
+*/
+FlagStatus tsi_group_status_get(uint32_t group)
+{
+ FlagStatus flag_status;
+ if(TSI_GCTL & group){
+ flag_status = SET;
+ }else{
+ flag_status = RESET;
+ }
+ return flag_status;
+}
+
+/*!
+ \brief get the cycle number for group0 as soon as a charge-transfer sequence completes
+ \param[in] none
+ \param[out] none
+ \retval group0 cycle number
+*/
+uint16_t tsi_group0_cycle_get(void)
+{
+ return (uint16_t)TSI_G0CYCN;
+}
+
+/*!
+ \brief get the cycle number for group1 as soon as a charge-transfer sequence completes
+ \param[in] none
+ \param[out] none
+ \retval group1 cycle number
+*/
+uint16_t tsi_group1_cycle_get(void)
+{
+ return (uint16_t)TSI_G1CYCN;
+}
+
+/*!
+ \brief get the cycle number for group2 as soon as a charge-transfer sequence completes
+ \param[in] none
+ \param[out] none
+ \retval group2 cycle number
+*/
+uint16_t tsi_group2_cycle_get(void)
+{
+ return (uint16_t)TSI_G2CYCN;
+}
+
+/*!
+ \brief get the cycle number for group3 as soon as a charge-transfer sequence completes
+ \param[in] none
+ \param[out] none
+ \retval group3 cycle number
+*/
+uint16_t tsi_group3_cycle_get(void)
+{
+ return (uint16_t)TSI_G3CYCN;
+}
+
+/*!
+ \brief get the cycle number for group4 as soon as a charge-transfer sequence completes
+ \param[in] none
+ \param[out] none
+ \retval group4 cycle number
+*/
+uint16_t tsi_group4_cycle_get(void)
+{
+ return (uint16_t)TSI_G4CYCN;
+}
+
+/*!
+ \brief get the cycle number for group5 as soon as a charge-transfer sequence completes
+ \param[in] none
+ \param[out] none
+ \retval group5 cycle number
+*/
+uint16_t tsi_group5_cycle_get(void)
+{
+ return (uint16_t)TSI_G5CYCN;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_usart.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_usart.c
new file mode 100644
index 0000000000000000000000000000000000000000..f4dd5a4ca323c2ca144dc77351016d6606e763f6
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_usart.c
@@ -0,0 +1,1308 @@
+/*!
+ \file gd32f3x0_usart.c
+ \brief USART driver
+
+ \version 2017-06-06 V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_usart.h"
+
+/* USART register bit offset */
+#define CTL1_ADDR_OFFSET ((uint32_t)24U) /* bit offset of ADDR in USART_CTL1 */
+#define GP_GUAT_OFFSET ((uint32_t)8U) /* bit offset of GUAT in USART_GP */
+#define CTL2_SCRTNUM_OFFSET ((uint32_t)17U) /* bit offset of SCRTNUM in USART_CTL2 */
+#define RT_BL_OFFSET ((uint32_t)24U) /* bit offset of BL in USART_RT */
+#define CTL0_DEA_OFFSET ((uint32_t)21U) /* bit offset of DEA in USART_CTL0 */
+#define CTL0_DED_OFFSET ((uint32_t)16U) /* bit offset of DED in USART_CTL0 */
+
+/*!
+ \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) << CTL1_ADDR_OFFSET));
+}
+
+/*!
+ \brief configure the address of the USART in wake up by address match 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 configure LIN break frame 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 USART 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 USART 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) << GP_GUAT_OFFSET));
+}
+
+/*!
+ \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 << CTL2_SCRTNUM_OFFSET));
+}
+
+/*!
+ \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) << RT_BL_OFFSET));
+}
+
+/*!
+ \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 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) << CTL0_DEA_OFFSET));
+}
+
+/*!
+ \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) << CTL0_DED_OFFSET));
+}
+
+/*!
+ \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 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 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
+ \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] interrupt: interrupt
+ 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 interrupt)
+{
+ USART_REG_VAL(usart_periph, interrupt) |= BIT(USART_BIT_POS(interrupt));
+}
+
+/*!
+ \brief disable USART interrupt
+ \param[in] usart_periph: USARTx(x=0,1)
+ \param[in] interrupt: interrupt
+ 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 interrupt)
+{
+ USART_REG_VAL(usart_periph, interrupt) &= ~BIT(USART_BIT_POS(interrupt));
+}
+
+/*!
+ \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 interrupt flag
+ \arg USART_INT_FLAG_RT: receiver timeout interrupt flag
+ \arg USART_INT_FLAG_AM: address match interrupt flag
+ \arg USART_INT_FLAG_PERR: parity error interrupt flag
+ \arg USART_INT_FLAG_TBE: transmitter buffer empty interrupt flag
+ \arg USART_INT_FLAG_TC: transmission complete interrupt flag
+ \arg USART_INT_FLAG_RBNE: read data buffer not empty interrupt flag
+ \arg USART_INT_FLAG_RBNE_ORERR: overrun error interrupt flag
+ \arg USART_INT_FLAG_IDLE: IDLE line detected interrupt flag
+ \arg USART_INT_FLAG_LBD: LIN break detected interrupt flag
+ \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode interrupt flag
+ \arg USART_INT_FLAG_CTS: CTS interrupt flag
+ \arg USART_INT_FLAG_ERR_NERR: noise error interrupt flag
+ \arg USART_INT_FLAG_ERR_ORERR: overrun error interrupt flag
+ \arg USART_INT_FLAG_ERR_FERR: frame error interrupt flag
+ \arg USART_INT_FLAG_RFFINT: receive FIFO full interrupt 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 interrupt flag
+ \arg USART_INT_FLAG_ERR_FERR: frame error interrupt flag
+ \arg USART_INT_FLAG_ERR_NERR: noise detected interrupt flag
+ \arg USART_INT_FLAG_RBNE_ORERR: overrun error interrupt flag
+ \arg USART_INT_FLAG_ERR_ORERR: overrun error interrupt flag
+ \arg USART_INT_FLAG_IDLE: idle line detected interrupt flag
+ \arg USART_INT_FLAG_TC: transmission complete interrupt flag
+ \arg USART_INT_FLAG_LBD: LIN break detected interrupt flag
+ \arg USART_INT_FLAG_CTS: CTS change interrupt flag
+ \arg USART_INT_FLAG_RT: receiver timeout interrupt flag
+ \arg USART_INT_FLAG_EB: end of block interrupt flag
+ \arg USART_INT_FLAG_AM: address match interrupt flag
+ \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode interrupt flag
+ \arg USART_INT_FLAG_RFFINT: receive FIFO full interrupt flag
+ \param[out] none
+ \retval none
+*/
+void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag)
+{
+ if(USART_INT_FLAG_RFFINT == int_flag){
+ USART_RFCS(usart_periph) &= (uint32_t)(~USART_RFCS_RFFINT);
+ }else{
+ USART_INTC(usart_periph) |= BIT(USART_BIT_POS2(int_flag));
+ }
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_wwdgt.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_wwdgt.c
new file mode 100644
index 0000000000000000000000000000000000000000..10af2b5fb89d0506dab8c11c890a6bfb1eb8caa0
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_standard_peripheral/Source/gd32f3x0_wwdgt.c
@@ -0,0 +1,142 @@
+/*!
+ \file gd32f3x0_wwdgt.c
+ \brief WWDGT driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "gd32f3x0_wwdgt.h"
+#include "gd32f3x0_rcu.h"
+
+/*!
+ \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: 0x00 - 0x7F
+ \param[out] none
+ \retval none
+*/
+void wwdgt_counter_update(uint16_t counter_value)
+{
+ uint32_t reg = 0x0U;
+
+ 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: 0x00 - 0x7F
+ \param[in] window: 0x00 - 0x7F
+ \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 = 0x0U, reg_ctl = 0x0U;
+
+ /* 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(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);
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_core.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_core.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3f6b5a0050c91d0b6467b6d2739f53f0c44b768
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_core.h
@@ -0,0 +1,300 @@
+/*!
+ \file usb_core.h
+ \brief USB core driver header file
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USB_CORE_H
+#define USB_CORE_H
+
+#include "usb_conf.h"
+#include "usb_regs.h"
+#include "usb_defines.h"
+
+#define USB_MAX_EP0_SIZE 64U /* endpoint 0 max packet size */
+#define RX_MAX_DATA_LENGTH 512U /* host rx buffer max data length */
+#define HC_MAX_PACKET_COUNT 140U /* host channel max packet count */
+
+#define USB_MAX_DEV_EPCOUNT USBFS_MAX_DEV_EPCOUNT
+#define USB_MAX_FIFOS (USBFS_MAX_HOST_CHANNELCOUNT * 2U - 1U)
+
+/* USB core status */
+typedef enum
+{
+ USB_OK = 0, /* USB core OK status */
+ USB_FAIL /* USB core fail status */
+}usb_status_enum;
+
+/* USB host channel status */
+typedef enum
+{
+ HC_IDLE = 0, /* USB host channel idle status */
+ HC_XF, /* USB host channel transfer status */
+ HC_HALTED, /* USB host channel halted status */
+ HC_NAK, /* USB host channel nak status */
+ HC_NYET, /* USB host channel nyet status */
+ HC_STALL, /* USB host channel stall status */
+ HC_TRACERR, /* USB host channel tracerr status */
+ HC_BBERR, /* USB host channel bberr status */
+ HC_DTGERR, /* USB host channel dtgerr status */
+}hc_status_enum;
+
+/* USB URB(USB request block) state */
+typedef enum
+{
+ URB_IDLE = 0, /* USB URB idle status */
+ URB_DONE, /* USB URB done status */
+ URB_NOTREADY, /* USB URB notready status */
+ URB_ERROR, /* USB URB error status */
+ URB_STALL, /* USB URB stall status */
+ URB_PING /* USB URB ping status */
+}urb_state_enum;
+
+/* USB core configuration */
+typedef struct
+{
+ uint8_t core_id; /* USB core id */
+ uint8_t core_speed; /* USB core speed */
+ uint8_t phy_interface; /* USB PHY interface */
+ uint8_t host_channel_num; /* USB host channel number */
+ uint8_t dev_endp_num; /* USB device endpoint number */
+ uint8_t sof_output; /* USB SOF output */
+ uint8_t low_power; /* USB low power */
+ uint16_t max_packet_size; /* USB max packet size */
+ uint16_t max_fifo_size; /* USB fifo size */
+}usb_core_cfgs_struct;
+
+typedef enum
+{
+ USBD_OK = 0, /* USB device ok status */
+ USBD_BUSY, /* USB device busy status */
+ USBD_FAIL, /* USB device fail stauts */
+}usbd_status_enum;
+
+/* USB control transfer state */
+typedef enum
+{
+ USB_CTRL_IDLE = 0, /* USB control transfer idle state */
+ USB_CTRL_SETUP, /* USB control transfer setup state */
+ USB_CTRL_DATA_IN, /* USB control transfer data in state */
+ USB_CTRL_DATA_OUT, /* USB control transfer data out state */
+ USB_CTRL_STATUS_IN, /* USB control transfer status in state*/
+ USB_CTRL_STATUS_OUT, /* USB control transfer status out state */
+ USB_CTRL_STALL /* USB control transfer stall state */
+}usbd_control_state_enum;
+
+/* USB transfer direction */
+typedef enum
+{
+ USB_RX = 0, /* receive direction type value */
+ USB_TX /* transmit direction type value */
+}usb_dir_enum;
+
+/* USB endpoint in device mode */
+typedef struct
+{
+ uint8_t endp_type; /* USB endpoint type */
+ uint8_t endp_frame; /* USB endpoint frame */
+ uint32_t endp_mps; /* USB endpoint max packet size */
+
+ /* Transaction level variables */
+ uint8_t *xfer_buff; /* USB transfer buffer */
+ uint32_t xfer_len; /* USB transfer length */
+ uint32_t xfer_count; /* USB transfer count */
+
+ uint32_t dma_addr; /* USBHS can use DMA */
+}usb_ep_struct;
+
+/* USB device standard request */
+typedef struct
+{
+ uint8_t bmRequestType; /* USB device request type */
+ uint8_t bRequest; /* USB device request */
+ uint16_t wValue; /* USB device request value */
+ uint16_t wIndex; /* USB device request index */
+ uint16_t wLength; /* USB device request length */
+}usb_device_req_struct;
+
+/* USB core device driver */
+typedef struct
+{
+ uint8_t config_num; /* USB configuration number */
+ __IO uint8_t status; /* USB status */
+ uint8_t ctl_status; /* USB control status */
+ uint8_t prev_status; /* USB previous status */
+ uint8_t connection_status; /* USB connection status */
+ uint32_t remote_wakeup; /* USB remote wakeup */
+
+ /* transfer level variables */
+ uint32_t remain_len; /* USB remain length */
+ uint32_t sum_len; /* USB sum length */
+ uint32_t ctl_len; /* USB control length */
+ uint8_t setup_packet[8 * 3]; /* USB setup packet */
+
+ usb_ep_struct in_ep[USB_MAX_DEV_EPCOUNT]; /* USB IN endpoint */
+ usb_ep_struct out_ep[USB_MAX_DEV_EPCOUNT]; /* USB OUT endpoint */
+
+ uint8_t *dev_desc; /* device descriptor */
+ uint8_t *config_desc; /* configuration descriptor */
+ uint8_t* *strings; /* configuration strings */
+
+ /* device class handler */
+ uint8_t (*class_init) (void *pudev, uint8_t config_index); /* device class initialize */
+ uint8_t (*class_deinit) (void *pudev, uint8_t config_index); /* device class deinitialize */
+ uint8_t (*class_req_handler) (void *pudev, usb_device_req_struct *req); /* device request handler */
+ uint8_t (*class_data_handler) (void *pudev, usb_dir_enum rx_tx, uint8_t ep_num); /* device data handler */
+}dcd_dev_struct;
+
+/* USB core host mode channel */
+typedef struct
+{
+ uint8_t dev_addr; /* device address */
+ uint8_t dev_speed; /* device speed */
+ uint8_t DPID; /* endpoint transfer data pid */
+ uint8_t endp_id; /* endpoint number */
+ uint8_t endp_in; /* endpoint in */
+ uint8_t endp_type; /* endpoint type */
+ uint16_t endp_mps; /* endpoint max pactet size */
+ uint16_t info; /* channel information */
+
+ uint8_t *xfer_buff; /* transfer buffer */
+ uint32_t xfer_len; /* transfer length */
+ uint32_t xfer_count; /* trasnfer count */
+
+ uint32_t err_count; /* USB transfer error count */
+
+ hc_status_enum status; /* channel status */
+ urb_state_enum urb_state; /* URB state */
+
+ uint8_t data_tg_in; /* data in toggle */
+ uint8_t data_tg_out; /* data out toggle */
+}usb_hostchannel_struct;
+
+/* USB core host driver */
+typedef struct
+{
+ uint8_t rx_buffer[RX_MAX_DATA_LENGTH]; /* rx buffer */
+ uint8_t connect_status; /* device connect status */
+ usb_hostchannel_struct host_channel[USB_MAX_FIFOS]; /* host channel */
+ void (*vbus_drive) (void *pudev, uint8_t state); /* the vbus driver function */
+}hcd_dev_struct;
+
+#ifdef USE_OTG_MODE
+
+/* USB core OTG-mode driver */
+typedef struct
+{
+ uint8_t OTG_State; /* OTG state */
+ uint8_t OTG_PrevState; /* OTG previous state */
+ uint8_t OTG_Mode; /* OTG mode */
+}otg_dev_struct;
+
+#endif /* USE_OTG_MODE */
+
+/* USB core driver */
+typedef struct
+{
+ usb_core_cfgs_struct cfg;
+
+#ifdef USE_DEVICE_MODE
+ dcd_dev_struct dev;
+#endif /* USE_DEVICE_MODE */
+
+#ifdef USE_HOST_MODE
+ hcd_dev_struct host;
+#endif /* USE_HOST_MODE */
+
+#ifdef USE_OTG_MODE
+ otg_dev_struct otg;
+#endif /* USE_OTG_MODE */
+
+ void (*udelay) (const uint32_t usec);
+ void (*mdelay) (const uint32_t msec);
+}usb_core_handle_struct;
+
+/* function declarations */
+
+/* global APIs */
+/* initializes the USB controller registers and prepares the core device mode or host mode operation */
+usb_status_enum usb_core_init (usb_core_handle_struct *pudev);
+/* initialize core parameters */
+usb_status_enum usb_core_select (usb_core_handle_struct *pudev, usb_core_id_enum core_id);
+/* read a packet from the Rx FIFO associated with the endpoint */
+void* usb_fifo_read (uint8_t *dest, uint16_t len);
+/* write a packet into the Tx FIFO associated with the endpoint */
+usb_status_enum usb_fifo_write (uint8_t *src, uint8_t chep_num, uint16_t len);
+/* flush a Tx FIFO or all Tx FIFOs */
+usb_status_enum usb_txfifo_flush (usb_core_handle_struct *pudev, uint8_t fifo_num);
+/* flush the entire Rx FIFO */
+usb_status_enum usb_rxfifo_flush (usb_core_handle_struct *pudev);
+/* set operation mode (host or device) */
+usb_status_enum usb_mode_set (usb_core_handle_struct *pudev, uint8_t mode);
+
+/* host APIs */
+#ifdef USE_HOST_MODE
+
+/* initializes USB core for host mode */
+usb_status_enum usb_hostcore_init (usb_core_handle_struct *pudev);
+/* enables the host mode interrupts */
+usb_status_enum usb_hostint_enable (usb_core_handle_struct *pudev);
+/* initialize host channel */
+usb_status_enum usb_hostchannel_init (usb_core_handle_struct *pudev, uint8_t hc_num);
+/* halt channel */
+usb_status_enum usb_hostchannel_halt (usb_core_handle_struct *pudev, uint8_t hc_num);
+/* prepare host channel for transferring packets */
+usb_status_enum usb_hostchannel_startxfer (usb_core_handle_struct *pudev, uint8_t hc_num);
+/* reset host port */
+uint32_t usb_port_reset (usb_core_handle_struct *pudev);
+/* control the VBUS to power */
+void usb_vbus_drive (usb_core_handle_struct *pudev, uint8_t state);
+/* stop the USB host and clean up fifos */
+void usb_host_stop (usb_core_handle_struct *pudev);
+
+#endif /* USE_HOST_MODE */
+
+/* device APIs */
+#ifdef USE_DEVICE_MODE
+
+/* initialize USB core registers for device mode */
+usb_status_enum usb_devcore_init (usb_core_handle_struct *pudev);
+/* configures endpoint 0 to receive SETUP packets */
+void usb_ep0_startout (usb_core_handle_struct *pudev);
+/* active remote wakeup signalling */
+void usb_remotewakeup_active (usb_core_handle_struct *pudev);
+/* active USB core clock */
+void usb_clock_ungate (usb_core_handle_struct *pudev);
+/* stop the device and clean up fifos */
+void usb_device_stop (usb_core_handle_struct *pudev);
+
+#endif /* USE_DEVICE_MODE */
+
+#endif /* USB_CORE_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_defines.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_defines.h
new file mode 100644
index 0000000000000000000000000000000000000000..19b419bd19ffa61c573f846750e8f3e04dd49879
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_defines.h
@@ -0,0 +1,124 @@
+/*!
+ \file usb_defines.h
+ \brief USB core defines
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USB_DEFINES_H
+#define USB_DEFINES_H
+
+#include "usb_conf.h"
+
+#ifndef NULL
+ #define NULL (void *)0 /*!< USB null marco value*/
+#endif /* NULL */
+
+#define USB_CORE_SPEED_HIGH 0U /* USB core speed is high-speed */
+#define USB_CORE_SPEED_FULL 1U /* USB core speed is full-speed */
+
+#define USBFS_MAX_PACKET_SIZE 64U /* USBFS max packet size */
+#define USBFS_MAX_HOST_CHANNELCOUNT 8U /* USBFS host channel count */
+#define USBFS_MAX_DEV_EPCOUNT 4U /* USBFS device endpoint count */
+#define USBFS_MAX_FIFO_WORDLEN 320U /* USBFS max fifo size in words */
+
+#define USBHS_MAX_PACKET_SIZE 512U /* USBHS max packet size */
+#define USBHS_MAX_HOST_CHANNELCOUNT 12U /* USBHS host channel count */
+#define USBHS_MAX_DEV_EPCOUNT 6U /* USBHS device endpoint count */
+#define USBHS_MAX_FIFO_WORDLEN 1280U /* USBHS max fifo size in words */
+
+#define USB_CORE_ULPI_PHY 1U /* USB core use external ULPI PHY */
+#define USB_CORE_EMBEDDED_PHY 2U /* USB core use embedded PHY */
+
+#define DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0U /* USB enumerate speed use high-speed PHY clock in 30MHz or 60MHz */
+#define DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1U /* USB enumerate speed use full-speed PHY clock in 30MHz or 60MHz */
+#define DSTAT_ENUMSPD_LS_PHY_6MHZ 2U /* USB enumerate speed use low-speed PHY clock in 6MHz */
+#define DSTAT_ENUMSPD_FS_PHY_48MHZ 3U /* USB enumerate speed use full-speed PHY clock in 48MHz */
+
+#define GRSTATR_RPCKST_IN 2U /* IN data packet received */
+#define GRSTATR_RPCKST_IN_XFER_COMP 3U /* IN transfer completed (generates an interrupt if poped) */
+#define GRSTATR_RPCKST_DATA_TOGGLE_ERR 5U /* data toggle error (generates an interrupt if poped) */
+#define GRSTATR_RPCKST_CH_HALTED 7U /* channel halted (generates an interrupt if poped) */
+
+#define DEVICE_MODE 0U /* USB core in device mode */
+#define HOST_MODE 1U /* USB core in host mode */
+#define OTG_MODE 2U /* USB core in OTG mode */
+
+#define USB_EPTYPE_CTRL 0U /* USB control endpoint type */
+#define USB_EPTYPE_ISOC 1U /* USB synchronous endpoint type */
+#define USB_EPTYPE_BULK 2U /* USB bulk endpoint type */
+#define USB_EPTYPE_INTR 3U /* USB interrupt endpoint type */
+#define USB_EPTYPE_MASK 3U /* USB endpoint type mask */
+
+#define RXSTAT_GOUT_NAK 1U /* global OUT NAK (triggers an interrupt) */
+#define RXSTAT_DATA_UPDT 2U /* OUT data packet received */
+#define RXSTAT_XFER_COMP 3U /* OUT transfer completed (triggers an interrupt) */
+#define RXSTAT_SETUP_COMP 4U /* SETUP transaction completed (triggers an interrupt) */
+#define RXSTAT_SETUP_UPDT 6U /* SETUP data packet received */
+
+#define DPID_DATA0 0U /* device endpoint data PID is DATA0 */
+#define DPID_DATA1 2U /* device endpoint data PID is DATA1 */
+#define DPID_DATA2 1U /* device endpoint data PID is DATA2 */
+#define DPID_MDATA 3U /* device endpoint data PID is MDATA */
+
+#define HC_PID_DATA0 0U /* host channel data PID is DATA0 */
+#define HC_PID_DATA2 1U /* host channel data PID is DATA2 */
+#define HC_PID_DATA1 2U /* host channel data PID is DATA1 */
+#define HC_PID_SETUP 3U /* host channel data PID is SETUP */
+
+#define HPRT_PRTSPD_HIGH_SPEED 0U /* host port speed use high speed */
+#define HPRT_PRTSPD_FULL_SPEED 1U /* host port speed use full speed */
+#define HPRT_PRTSPD_LOW_SPEED 2U /* host port speed use low speed */
+
+#define HCTLR_30_60_MHZ 0U /* USB PHY(ULPI) clock is 60MHz */
+#define HCTLR_48_MHZ 1U /* USB PHY(embedded full-speed) clock is 48MHz */
+#define HCTLR_6_MHZ 2U /* USB PHY(embedded low-speed) clock is 6MHz */
+
+#define HCCHAR_CTRL 0U /* control channel type */
+#define HCCHAR_ISOC 1U /* synchronous channel type */
+#define HCCHAR_BULK 2U /* bulk channel type */
+#define HCCHAR_INTR 3U /* interrupt channel type */
+
+typedef enum
+{
+ USB_HS_CORE_ID = 0,
+ USB_FS_CORE_ID = 1
+}usb_core_id_enum;
+
+typedef enum
+{
+ USB_SPEED_UNKNOWN = 0,
+ USB_SPEED_LOW,
+ USB_SPEED_FULL,
+ USB_SPEED_HIGH
+}usb_speed_enum;
+
+#endif /* USB_DEFINES_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_regs.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_regs.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d414a58e2ca600fc89a341610a78482a926208c
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_regs.h
@@ -0,0 +1,589 @@
+/*!
+ \file usb_regs.h
+ \brief USB FS cell registers definition and handle macros
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USB_REGS_H
+#define USB_REGS_H
+
+#include "usb_conf.h"
+
+#define USBFS USBFS_BASE /*!< base address of USBFS registers */
+
+/* registers location definitions */
+#define LOCATE_DIEPTFLEN(x) (0x104U + 4U * ((x) - 1U)) /*!< locate device IN endpoint-x (x = 1..3) transfer length registers */
+#define LOCATE_HCHCTL(x) (0x500U + 0x20U * (x)) /*!< locate host channel-x control registers */
+#define LOCATE_HCHINTF(x) (0x508U + 0x20U * (x)) /*!< locate host channel-x interrupt flag registers */
+#define LOCATE_HCHINTEN(x) (0x50CU + 0x20U * (x)) /*!< locate host channel-x interrupt enable registers */
+#define LOCATE_HCHLEN(x) (0x510U + 0x20U * (x)) /*!< locate host channel-x transfer length registers */
+#define LOCATE_DIEPCTL(x) (0x900U + 0x20U * (x)) /*!< locate device IN endpoint-x control registers */
+#define LOCATE_DOEPCTL(x) (0xB00U + 0x20U * (x)) /*!< locate device OUT endpoint-x control registers */
+#define LOCATE_DIEPINTF(x) (0x908U + 0x20U * (x)) /*!< locate device IN endpoint-x interrupt flag registers */
+#define LOCATE_DOEPINTF(x) (0xB08U + 0x20U * (x)) /*!< locate device OUT endpoint-x interrupt flag registers */
+#define LOCATE_DIEPLEN(x) (0x910U + 0x20U * (x)) /*!< locate device IN endpoint-x transfer length registers */
+#define LOCATE_DOEPLEN(x) (0xB10U + 0x20U * (x)) /*!< locate device OUT endpoint-x transfer length registers */
+#define LOCATE_DIEPxTFSTAT(x) (0x918U + 0x20U * (x)) /*!< locate Device IN endpoint-x transmit FIFO status register */
+#define LOCATE_FIFO(x) (((x) + 1U) << 12U) /*!< locate FIFO-x memory */
+
+/* registers definitions */
+#define USB_GOTGCS REG32(((USBFS) + 0x00000000U)) /*!< global OTG control and status register */
+#define USB_GOTGINTF REG32(((USBFS) + 0x00000004U)) /*!< global OTG interrupt flag register */
+#define USB_GAHBCS REG32(((USBFS) + 0x00000008U)) /*!< global AHB control and status register */
+#define USB_GUSBCS REG32(((USBFS) + 0x0000000CU)) /*!< global USB control and status register */
+#define USB_GRSTCTL REG32(((USBFS) + 0x00000010U)) /*!< global reset control register */
+#define USB_GINTF REG32(((USBFS) + 0x00000014U)) /*!< global interrupt flag register */
+#define USB_GINTEN REG32(((USBFS) + 0x00000018U)) /*!< global interrupt enable register */
+#define USB_GRSTATR REG32(((USBFS) + 0x0000001CU)) /*!< global receive status read register */
+#define USB_GRSTATP REG32(((USBFS) + 0x00000020U)) /*!< global receive status read and pop register */
+#define USB_GRFLEN REG32(((USBFS) + 0x00000024U)) /*!< global receive FIFO length register */
+#define USB_HNPTFLEN REG32(((USBFS) + 0x00000028U)) /*!< host non-periodic transmit FIFO length register */
+#define USB_DIEP0TFLEN REG32(((USBFS) + 0x00000028U)) /*!< device IN endpoint 0 transmit FIFO length register */
+#define USB_HNPTFQSTAT REG32(((USBFS) + 0x0000002CU)) /*!< host non-periodic transmint FIFO/queue status register */
+#define USB_GCCFG REG32(((USBFS) + 0x00000038U)) /*!< global core configuration register */
+#define USB_CID REG32(((USBFS) + 0x0000003CU)) /*!< core id register */
+#define USB_HPTFLEN REG32(((USBFS) + 0x00000100U)) /*!< host periodic transmit FIFO length register */
+#define USB_DIEPxTFLEN(x) REG32(((USBFS) + LOCATE_DIEPTFLEN(x))) /*!< device IN endpoint transmit FIFO length register */
+
+#define USB_HCTL REG32(((USBFS) + 0x00000400U)) /*!< host control register */
+#define USB_HFT REG32(((USBFS) + 0x00000404U)) /*!< host frame interval register */
+#define USB_HFINFR REG32(((USBFS) + 0x00000408U)) /*!< host frame information remaining register */
+#define USB_HPTFQSTAT REG32(((USBFS) + 0x00000410U)) /*!< host periodic transmit FIFO/queue status register */
+#define USB_HACHINT REG32(((USBFS) + 0x00000414U)) /*!< host all channels interrupt register */
+#define USB_HACHINTEN REG32(((USBFS) + 0x00000418U)) /*!< host all channels interrupt enable register */
+#define USB_HPCS REG32(((USBFS) + 0x00000440U)) /*!< host port control and status register */
+#define USB_HCHxCTL(x) REG32(((USBFS) + LOCATE_HCHCTL(x))) /*!< host channel-x control register */
+#define USB_HCHxINTF(x) REG32(((USBFS) + LOCATE_HCHINTF(x))) /*!< host channel-x interrupt flag register */
+#define USB_HCHxINTEN(x) REG32(((USBFS) + LOCATE_HCHINTEN(x))) /*!< host channel-x interrupt enable register */
+#define USB_HCHxLEN(x) REG32(((USBFS) + LOCATE_HCHLEN(x))) /*!< host channel-x tranfer length register */
+
+#define USB_DCFG REG32(((USBFS) + 0x00000800U)) /*!< device configuration register */
+#define USB_DCTL REG32(((USBFS) + 0x00000804U)) /*!< device control register */
+#define USB_DSTAT REG32(((USBFS) + 0x00000808U)) /*!< device status register */
+#define USB_DIEPINTEN REG32(((USBFS) + 0x00000810U)) /*!< device IN endpoint common interrupt enable register */
+#define USB_DOEPINTEN REG32(((USBFS) + 0x00000814U)) /*!< device OUT endpoint common interrupt enable register */
+#define USB_DAEPINT REG32(((USBFS) + 0x00000818U)) /*!< device all endpoints interrupt register */
+#define USB_DAEPINTEN REG32(((USBFS) + 0x0000081CU)) /*!< device all endpoints interrupt enable register */
+#define USB_DVBUSDT REG32(((USBFS) + 0x00000828U)) /*!< device vbus discharge time register */
+#define USB_DVBUSPT REG32(((USBFS) + 0x0000082CU)) /*!< device vbus pulsing time register */
+#define USB_DIEPFEINTEN REG32(((USBFS) + 0x00000834U)) /*!< device IN endpoint FIFO empty interrupt enable register */
+#define USB_DEP1INT REG32(((USBFS) + 0x00000838U)) /*!< device endpoint 1 interrupt register */
+#define USB_DEP1INTEN REG32(((USBFS) + 0x0000083CU)) /*!< device endpoint 1 interrupt enable register */
+#define USB_DIEP1INTEN REG32(((USBFS) + 0x00000844U)) /*!< device IN endpoint 1 interrupt enable register */
+#define USB_DOEP1INTEN REG32(((USBFS) + 0x00000884U)) /*!< device OUT endpoint 1 interrupt enable register */
+#define USB_DIEP0CTL REG32(((USBFS) + 0x00000900U)) /*!< device IN endpoint 0 control register */
+#define USB_DIEP0LEN REG32(((USBFS) + 0x00000910U)) /*!< device IN endpoint 0 transfer length register */
+#define USB_DOEP0CTL REG32(((USBFS) + 0x00000B00U)) /*!< device OUT endpoint 0 control register */
+#define USB_DOEP0LEN REG32(((USBFS) + 0x00000B10U)) /*!< device OUT endpoint 0 transfer length register */
+#define USB_DIEPxCTL(x) REG32(((USBFS) + LOCATE_DIEPCTL(x))) /*!< device IN endpoint-x control register */
+#define USB_DOEPxCTL(x) REG32(((USBFS) + LOCATE_DOEPCTL(x))) /*!< device OUT endpoint-x control register */
+#define USB_DIEPxINTF(x) REG32(((USBFS) + LOCATE_DIEPINTF(x))) /*!< device IN endpoint-x interrupt flag register */
+#define USB_DOEPxINTF(x) REG32(((USBFS) + LOCATE_DOEPINTF(x))) /*!< device OUT endpoint-x interrupt flag register */
+#define USB_DIEPxLEN(x) REG32(((USBFS) + LOCATE_DIEPLEN(x))) /*!< device IN endpoint-x transfer length register */
+#define USB_DOEPxLEN(x) REG32(((USBFS) + LOCATE_DOEPLEN(x))) /*!< device OUT endpoint-x transfer length register */
+#define USB_DIEPxTFSTAT(x) REG32(((USBFS) + LOCATE_DIEPxTFSTAT(x)))/*!< device IN endpoint-x transmit FIFO status register */
+
+#define USB_PWRCLKCTL REG32(((USBFS) + 0x0E00U)) /*!< power and clock register */
+
+#define USB_FIFO(x) (®32(((USBFS) + LOCATE_FIFO(x)))) /*!< FIFO memory */
+
+/* global OTG control and status register bits definitions */
+#define GOTGCS_BSV BIT(19) /*!< B-Session Valid */
+#define GOTGCS_ASV BIT(18) /*!< A-session valid */
+#define GOTGCS_DI BIT(17) /*!< debounce interval */
+#define GOTGCS_IDPS BIT(16) /*!< id pin status */
+#define GOTGCS_DHNPEN BIT(11) /*!< device HNP enable */
+#define GOTGCS_HHNPEN BIT(10) /*!< host HNP enable */
+#define GOTGCS_HNPREQ BIT(9) /*!< HNP request */
+#define GOTGCS_HNPS BIT(8) /*!< HNP successes */
+#define GOTGCS_SRPREQ BIT(1) /*!< SRP request */
+#define GOTGCS_SRPS BIT(0) /*!< SRP successes */
+
+/* global OTG interrupt flag register bits definitions */
+#define GOTGINTF_DF BIT(19) /*!< debounce finish */
+#define GOTGINTF_ADTO BIT(18) /*!< A-device timeout */
+#define GOTGINTF_HNPDET BIT(17) /*!< host negotiation request detected */
+#define GOTGINTF_HNPEND BIT(9) /*!< HNP end */
+#define GOTGINTF_SRPEND BIT(8) /*!< SRP end */
+#define GOTGINTF_SESEND BIT(2) /*!< session end */
+
+/* global AHB control and status register bits definitions */
+#define GAHBCS_PTXFTH BIT(8) /*!< periodic Tx FIFO threshold */
+#define GAHBCS_TXFTH BIT(7) /*!< tx FIFO threshold */
+#define GAHBCS_GINTEN BIT(0) /*!< global interrupt enable */
+
+/* global USB control and status register bits definitions */
+#define GUSBCS_FDM BIT(30) /*!< force device mode */
+#define GUSBCS_FHM BIT(29) /*!< force host mode */
+#define GUSBCS_UTT BITS(10, 13) /*!< USB turnaround time */
+#define GUSBCS_HNPCEN BIT(9) /*!< HNP capability enable */
+#define GUSBCS_SRPCEN BIT(8) /*!< SRP capability enable */
+#define GUSBCS_TOC BITS(0, 2) /*!< timeout calibration */
+
+/* global reset control register bits definitions */
+#define GRSTCTL_TXFNUM BITS(6, 10) /*!< tx FIFO number */
+#define GRSTCTL_TXFF BIT(5) /*!< tx FIFO flush */
+#define GRSTCTL_RXFF BIT(4) /*!< rx FIFO flush */
+#define GRSTCTL_HFCRST BIT(2) /*!< host frame counter reset */
+#define GRSTCTL_HCSRST BIT(1) /*!< HCLK soft reset */
+#define GRSTCTL_CSRST BIT(0) /*!< core soft reset */
+
+/* global interrupt flag register bits definitions */
+#define GINTF_WKUPIF BIT(31) /*!< wakeup interrupt flag */
+#define GINTF_SESIF BIT(30) /*!< session interrupt flag */
+#define GINTF_DISCIF BIT(29) /*!< disconnect interrupt flag */
+#define GINTF_IDPSC BIT(28) /*!< id pin status change */
+#define GINTF_PTXFEIF BIT(26) /*!< periodic tx FIFO empty interrupt flag */
+#define GINTF_HCIF BIT(25) /*!< host channels interrupt flag */
+#define GINTF_HPIF BIT(24) /*!< host port interrupt flag */
+#define GINTF_PXNCIF BIT(21) /*!< periodic transfer not complete interrupt flag */
+#define GINTF_ISOONCIF BIT(21) /*!< isochronous OUT transfer not complete interrupt flag */
+#define GINTF_ISOINCIF BIT(20) /*!< isochronous IN transfer not complete interrupt flag */
+#define GINTF_OEPIF BIT(19) /*!< OUT endpoint interrupt flag */
+#define GINTF_IEPIF BIT(18) /*!< IN endpoint interrupt flag */
+#define GINTF_EOPFIF BIT(15) /*!< end of periodic frame interrupt flag */
+#define GINTF_ISOOPDIF BIT(14) /*!< isochronous OUT packet dropped interrupt flag */
+#define GINTF_ENUMF BIT(13) /*!< enumeration finished */
+#define GINTF_RST BIT(12) /*!< USB reset */
+#define GINTF_SP BIT(11) /*!< USB suspend */
+#define GINTF_ESP BIT(10) /*!< early suspend */
+#define GINTF_GONAK BIT(7) /*!< global OUT NAK effective */
+#define GINTF_GNPINAK BIT(6) /*!< global IN non-periodic NAK effective */
+#define GINTF_NPTXFEIF BIT(5) /*!< non-periodic tx FIFO empty interrupt flag */
+#define GINTF_RXFNEIF BIT(4) /*!< rx FIFO non-empty interrupt flag */
+#define GINTF_SOF BIT(3) /*!< start of frame */
+#define GINTF_OTGIF BIT(2) /*!< OTG interrupt flag */
+#define GINTF_MFIF BIT(1) /*!< mode fault interrupt flag */
+#define GINTF_COPM BIT(0) /*!< current operation mode */
+
+/* global interrupt enable register bits definitions */
+#define GINTEN_WKUPIE BIT(31) /*!< wakeup interrupt enable */
+#define GINTEN_SESIE BIT(30) /*!< session interrupt enable */
+#define GINTEN_DISCIE BIT(29) /*!< disconnect interrupt enable */
+#define GINTEN_IDPSCIE BIT(28) /*!< id pin status change interrupt enable */
+#define GINTEN_PTXFEIE BIT(26) /*!< periodic tx FIFO empty interrupt enable */
+#define GINTEN_HCIE BIT(25) /*!< host channels interrupt enable */
+#define GINTEN_HPIE BIT(24) /*!< host port interrupt enable */
+#define GINTEN_PXNCIE BIT(21) /*!< periodic transfer not complete interrupt enable */
+#define GINTEN_ISOONCIE BIT(21) /*!< isochronous OUT transfer not complete interrupt enable */
+#define GINTEN_ISOINCIE BIT(20) /*!< isochronous IN transfer not complete interrupt enable */
+#define GINTEN_OEPIE BIT(19) /*!< OUT endpoints interrupt enable */
+#define GINTEN_IEPIE BIT(18) /*!< IN endpoints interrupt enable */
+#define GINTEN_EOPFIE BIT(15) /*!< end of periodic frame interrupt enable */
+#define GINTEN_ISOOPDIE BIT(14) /*!< isochronous OUT packet dropped interrupt enable */
+#define GINTEN_ENUMFIE BIT(13) /*!< enumeration finish enable */
+#define GINTEN_RSTIE BIT(12) /*!< USB reset interrupt enable */
+#define GINTEN_SPIE BIT(11) /*!< USB suspend interrupt enable */
+#define GINTEN_ESPIE BIT(10) /*!< early suspend interrupt enable */
+#define GINTEN_GONAKIE BIT(7) /*!< global OUT NAK effective interrupt enable */
+#define GINTEN_GNPINAKIE BIT(6) /*!< global non-periodic IN NAK effective interrupt enable */
+#define GINTEN_NPTXFEIE BIT(5) /*!< non-periodic Tx FIFO empty interrupt enable */
+#define GINTEN_RXFNEIE BIT(4) /*!< receive FIFO non-empty interrupt enable */
+#define GINTEN_SOFIE BIT(3) /*!< start of frame interrupt enable */
+#define GINTEN_OTGIE BIT(2) /*!< OTG interrupt enable */
+#define GINTEN_MFIE BIT(1) /*!< mode fault interrupt enable */
+
+/* global receive status read and pop register bits definitions */
+#define GRSTATRP_RPCKST BITS(17, 20) /*!< received packet status */
+#define GRSTATRP_DPID BITS(15, 16) /*!< data PID */
+#define GRSTATRP_BCOUNT BITS(4, 14) /*!< byte count */
+#define GRSTATRP_CNUM BITS(0, 3) /*!< channel number */
+#define GRSTATRP_EPNUM BITS(0, 3) /*!< endpoint number */
+
+/* global receive FIFO length register bits definitions */
+#define GRFLEN_RXFD BITS(0, 15) /*!< rx FIFO depth */
+
+/* host non-periodic transmit FIFO length register bits definitions */
+#define HNPTFLEN_HNPTXFD BITS(16, 31) /*!< non-periodic Tx FIFO depth */
+#define HNPTFLEN_HNPTXRSAR BITS(0, 15) /*!< non-periodic Tx RAM start address */
+
+/* IN endpoint 0 transmit FIFO length register bits definitions */
+#define DIEP0TFLEN_IEP0TXFD BITS(16, 31) /*!< IN Endpoint 0 Tx FIFO depth */
+#define DIEP0TFLEN_IEP0TXRSAR BITS(0, 15) /*!< IN Endpoint 0 TX RAM start address */
+
+/* host non-periodic transmit FIFO/queue status register bits definitions */
+#define HNPTFQSTAT_NPTXRQTOP BITS(24, 30) /*!< top entry of the non-periodic Tx request queue */
+#define HNPTFQSTAT_NPTXRQS BITS(16, 23) /*!< non-periodic Tx request queue space */
+#define HNPTFQSTAT_NPTXFS BITS(0, 15) /*!< non-periodic Tx FIFO space */
+#define HNPTFQSTAT_CNUM BITS(27, 30) /*!< channel number*/
+#define HNPTFQSTAT_EPNUM BITS(27, 30) /*!< endpoint number */
+#define HNPTFQSTAT_TYPE BITS(25, 26) /*!< token type */
+#define HNPTFQSTAT_TMF BIT(24) /*!< terminate flag */
+
+/* global core configuration register bits definitions */
+#define GCCFG_VBUSIG BIT(21) /*!< vbus ignored */
+#define GCCFG_SOFOEN BIT(20) /*!< SOF output enable */
+#define GCCFG_VBUSBCEN BIT(19) /*!< the VBUS B-device comparer enable */
+#define GCCFG_VBUSACEN BIT(18) /*!< the VBUS A-device comparer enable */
+#define GCCFG_PWRON BIT(16) /*!< power on */
+
+/* core ID register bits definitions */
+#define CID_CID BITS(0, 31) /*!< core ID */
+
+/* host periodic transmit FIFO length register bits definitions */
+#define HPTFLEN_HPTXFD BITS(16, 31) /*!< host periodic Tx FIFO depth */
+#define HPTFLEN_HPTXFSAR BITS(0, 15) /*!< host periodic Tx RAM start address */
+
+/* device IN endpoint transmit FIFO length register bits definitions */
+#define DIEPTFLEN_IEPTXFD BITS(16, 31) /*!< IN endpoint Tx FIFO x depth */
+#define DIEPTFLEN_IEPTXRSAR BITS(0, 15) /*!< IN endpoint FIFOx Tx x RAM start address */
+
+/* host control register bits definitions */
+#define HCTL_CLKSEL BITS(0, 1) /*!< clock select for USB clock */
+
+/* host frame interval register bits definitions */
+#define HFT_FRI BITS(0, 15) /*!< frame interval */
+
+/* host frame information remaining register bits definitions */
+#define HFINFR_FRT BITS(16, 31) /*!< frame remaining time */
+#define HFINFR_FRNUM BITS(0, 15) /*!< frame number */
+
+/* host periodic transmit FIFO/queue status register bits definitions */
+#define HPTFQSTAT_PTXREQT BITS(24, 31) /*!< top entry of the periodic Tx request queue */
+#define HPTFQSTAT_PTXREQS BITS(16, 23) /*!< periodic Tx request queue space */
+#define HPTFQSTAT_PTXFS BITS(0, 15) /*!< periodic Tx FIFO space */
+#define HPTFQSTAT_OEFRM BIT(31) /*!< odd/eveb frame */
+#define HPTFQSTAT_CNUM BITS(27, 30) /*!< channel number */
+#define HPTFQSTAT_EPNUM BITS(27, 30) /*!< endpoint number */
+#define HPTFQSTAT_TYPE BITS(25, 26) /*!< token type */
+#define HPTFQSTAT_TMF BIT(24) /*!< terminate flag */
+
+/* host all channels interrupt register bits definitions */
+#define HACHINT_HACHINT BITS(0, 7) /*!< host all channel interrupts */
+
+/* host all channels interrupt enable register bits definitions */
+#define HACHINTEN_CINTEN BITS(0, 7) /*!< channel interrupt enable */
+
+/* host port control and status register bits definitions */
+#define HPCS_PS BITS(17, 18) /*!< port speed */
+#define HPCS_PP BIT(12) /*!< port power */
+#define HPCS_PLST BITS(10, 11) /*!< port line status */
+#define HPCS_PRST BIT(8) /*!< port reset */
+#define HPCS_PSP BIT(7) /*!< port suspend */
+#define HPCS_PREM BIT(6) /*!< port resume */
+#define HPCS_PEDC BIT(3) /*!< port enable/disable change */
+#define HPCS_PE BIT(2) /*!< port enable */
+#define HPCS_PCD BIT(1) /*!< port connect detected */
+#define HPCS_PCST BIT(0) /*!< port connect status */
+
+/* host channel-x control register bits definitions */
+#define HCHCTL_CEN BIT(31) /*!< channel enable */
+#define HCHCTL_CDIS BIT(30) /*!< channel disable */
+#define HCHCTL_ODDFRM BIT(29) /*!< odd frame */
+#define HCHCTL_DAR BITS(22, 28) /*!< device address */
+#define HCHCTL_MPC BITS(20, 21) /*!< multiple packet count */
+#define HCHCTL_EPTYPE BITS(18, 19) /*!< endpoint type */
+#define HCHCTL_LSD BIT(17) /*!< low-speed device */
+#define HCHCTL_EPDIR BIT(15) /*!< endpoint direction */
+#define HCHCTL_EPNUM BITS(11, 14) /*!< endpoint number */
+#define HCHCTL_MPL BITS(0, 10) /*!< maximum packet length */
+
+/* host channel-x interrupt flag register bits definitions */
+#define HCHINTF_DTER BIT(10) /*!< data toggle error */
+#define HCHINTF_REQOVR BIT(9) /*!< request queue overrun */
+#define HCHINTF_BBER BIT(8) /*!< babble error */
+#define HCHINTF_USBER BIT(7) /*!< USB bus Error */
+#define HCHINTF_NYET BIT(6) /*!< NYET */
+#define HCHINTF_ACK BIT(5) /*!< ACK */
+#define HCHINTF_NAK BIT(4) /*!< NAK */
+#define HCHINTF_STALL BIT(3) /*!< STALL */
+#define HCHINTF_CH BIT(1) /*!< channel halted */
+#define HCHINTF_TF BIT(0) /*!< transfer finished */
+
+/* host channel-x interrupt enable register bits definitions */
+#define HCHINTEN_DTERIE BIT(10) /*!< data toggle error interrupt enable */
+#define HCHINTEN_REQOVRIE BIT(9) /*!< request queue overrun interrupt enable */
+#define HCHINTEN_BBERIE BIT(8) /*!< babble error interrupt enable */
+#define HCHINTEN_USBERIE BIT(7) /*!< USB bus error interrupt enable */
+#define HCHINTEN_NYETIE BIT(6) /*!< NYET interrupt enable */
+#define HCHINTEN_ACKIE BIT(5) /*!< ACK interrupt enable */
+#define HCHINTEN_NAKIE BIT(4) /*!< NAK interrupt enable */
+#define HCHINTEN_STALLIE BIT(3) /*!< STALL interrupt enable */
+#define HCHINTEN_CHIE BIT(1) /*!< channel halted interrupt enable */
+#define HCHINTEN_TFIE BIT(0) /*!< transfer finished interrupt enable */
+
+/* host channel-x transfer length register bits definitions */
+#define HCHLEN_DPID BITS(29, 30) /*!< data PID */
+#define HCHLEN_PCNT BITS(19, 28) /*!< packet count */
+#define HCHLEN_TLEN BITS(0, 18) /*!< transfer length */
+
+/* device control and status registers */
+/* device configuration registers bits definitions */
+#define DCFG_EOPFT BITS(11, 12) /*!< end of periodic frame time */
+#define DCFG_DAR BITS(4, 10) /*!< device address */
+#define DCFG_NZLSOH BIT(2) /*!< non-zero-length status OUT handshake */
+#define DCFG_DS BITS(0, 1) /*!< device speed */
+
+/* device control registers bits definitions */
+#define DCTL_POIF BIT(11) /*!< power-on initialization finished */
+#define DCTL_CGONAK BIT(10) /*!< clear global OUT NAK */
+#define DCTL_SGONAK BIT(9) /*!< set global OUT NAK */
+#define DCTL_CGINAK BIT(8) /*!< clear global IN NAK */
+#define DCTL_SGINAK BIT(7) /*!< set global IN NAK */
+#define DCTL_GONS BIT(3) /*!< global OUT NAK status */
+#define DCTL_GINS BIT(2) /*!< global IN NAK status */
+#define DCTL_SD BIT(1) /*!< soft disconnect */
+#define DCTL_RWKUP BIT(0) /*!< remote wakeup */
+
+/* device status registers bits definitions */
+#define DSTAT_FNRSOF BITS(8, 21) /*!< the frame number of the received SOF. */
+#define DSTAT_ES BITS(1, 2) /*!< enumerated speed */
+#define DSTAT_SPST BIT(0) /*!< suspend status */
+
+/* device IN endpoint common interrupt enable registers bits definitions */
+#define DIEPINTEN_TXFEEN BIT(7) /*!< transmit FIFO empty interrupt enable bit */
+#define DIEPINTEN_IEPNEEN BIT(6) /*!< IN endpoint NAK effective interrupt enable bit */
+#define DIEPINTEN_EPTXFUDEN BIT(4) /*!< endpoint Tx FIFO underrun interrupt enable bit */
+#define DIEPINTEN_CITOEN BIT(3) /*!< control In Timeout interrupt enable bit */
+#define DIEPINTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */
+#define DIEPINTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */
+
+/* device OUT endpoint common interrupt enable registers bits definitions */
+#define DOEPINTEN_BTBSTPEN BIT(6) /*!< back-to-back SETUP packets interrupt enable bit */
+#define DOEPINTEN_EPRXFOVREN BIT(4) /*!< endpoint Rx FIFO overrun interrupt enable bit */
+#define DOEPINTEN_STPFEN BIT(3) /*!< SETUP phase finished interrupt enable bit */
+#define DOEPINTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */
+#define DOEPINTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */
+
+/* device all endpoints interrupt registers bits definitions */
+#define DAEPINT_OEPITB BITS(16, 21) /*!< device all OUT endpoint interrupt bits */
+#define DAEPINT_IEPITB BITS(0, 5) /*!< device all IN endpoint interrupt bits */
+
+/* device all endpoints interrupt enable registers bits definitions */
+#define DAEPINTEN_OEPIE BITS(16, 21) /*!< OUT endpoint interrupt enable */
+#define DAEPINTEN_IEPIE BITS(0, 3) /*!< IN endpoint interrupt enable */
+
+/* device Vbus discharge time registers bits definitions */
+#define DVBUSDT_DVBUSDT BITS(0, 15) /*!< device VBUS discharge time */
+
+/* device Vbus pulsing time registers bits definitions */
+#define DVBUSPT_DVBUSPT BITS(0, 11) /*!< device VBUS pulsing time */
+
+/* device IN endpoint FIFO empty interrupt enable register bits definitions */
+#define DIEPFEINTEN_IEPTXFEIE BITS(0, 3) /*!< IN endpoint Tx FIFO empty interrupt enable bits */
+
+/* device endpoint 0 control register bits definitions */
+#define DEP0CTL_EPEN BIT(31) /*!< endpoint enable */
+#define DEP0CTL_EPD BIT(30) /*!< endpoint disable */
+#define DEP0CTL_SNAK BIT(27) /*!< set NAK */
+#define DEP0CTL_CNAK BIT(26) /*!< clear NAK */
+#define DIEP0CTL_TXFNUM BITS(22, 25) /*!< tx FIFO number */
+#define DEP0CTL_STALL BIT(21) /*!< STALL handshake */
+#define DEP0CTL_EPTYPE BITS(18, 19) /*!< endpoint type */
+#define DEP0CTL_NAKS BIT(17) /*!< NAK status */
+#define DEP0CTL_EPACT BIT(15) /*!< endpoint active */
+#define DEP0CTL_MPL BITS(0, 1) /*!< maximum packet length */
+
+/* device endpoint x control register bits definitions */
+#define DEPCTL_EPEN BIT(31) /*!< endpoint enable */
+#define DEPCTL_EPD BIT(30) /*!< endpoint disable */
+#define DEPCTL_SODDFRM BIT(29) /*!< set odd frame */
+#define DEPCTL_SD1PID BIT(29) /*!< set DATA1 PID */
+#define DEPCTL_SEVNFRM BIT(28) /*!< set even frame */
+#define DEPCTL_SD0PID BIT(28) /*!< set DATA0 PID */
+#define DEPCTL_SNAK BIT(27) /*!< set NAK */
+#define DEPCTL_CNAK BIT(26) /*!< clear NAK */
+#define DIEPCTL_TXFNUM BITS(22, 25) /*!< tx FIFO number */
+#define DEPCTL_STALL BIT(21) /*!< STALL handshake */
+#define DEPCTL_EPTYPE BITS(18, 19) /*!< endpoint type */
+#define DEPCTL_NAKS BIT(17) /*!< NAK status */
+#define DEPCTL_EOFRM BIT(16) /*!< even/odd frame */
+#define DEPCTL_DPID BIT(16) /*!< endpoint data PID */
+#define DEPCTL_EPACT BIT(15) /*!< endpoint active */
+#define DEPCTL_MPL BITS(0, 10) /*!< maximum packet length */
+
+/* device IN endpoint-x interrupt flag register bits definitions */
+#define DIEPINTF_TXFE BIT(7) /*!< transmit FIFO empty */
+#define DIEPINTF_IEPNE BIT(6) /*!< IN endpoint NAK effective */
+#define DIEPINTF_EPTXFUD BIT(4) /*!< endpoint Tx FIFO underrun */
+#define DIEPINTF_CITO BIT(3) /*!< control In Timeout interrupt */
+#define DIEPINTF_EPDIS BIT(1) /*!< endpoint disabled */
+#define DIEPINTF_TF BIT(0) /*!< transfer finished */
+
+/* device OUT endpoint-x interrupt flag register bits definitions */
+#define DOEPINTF_BTBSTP BIT(6) /*!< back-to-back SETUP packets */
+#define DOEPINTF_EPRXFOVR BIT(4) /*!< endpoint Rx FIFO overrun */
+#define DOEPINTF_STPF BIT(3) /*!< SETUP phase finished */
+#define DOEPINTF_EPDIS BIT(1) /*!< endpoint disabled */
+#define DOEPINTF_TF BIT(0) /*!< transfer finished */
+
+/* device IN endpoint 0 transfer length register bits definitions */
+#define DIEP0LEN_PCNT BITS(19, 20) /*!< packet count */
+#define DIEP0LEN_TLEN BITS(0, 6) /*!< transfer length */
+
+/* device OUT endpoint 0 transfer length register bits definitions */
+#define DOEP0LEN_STPCNT BITS(29, 30) /*!< SETUP packet count */
+#define DOEP0LEN_PCNT BIT(19) /*!< packet count */
+#define DOEP0LEN_TLEN BITS(0, 6) /*!< transfer length */
+
+/* device OUT endpoint-x transfer length register bits definitions */
+#define DOEPLEN_RXDPID BITS(29, 30) /*!< received data PID */
+#define DOEPLEN_STPCNT BITS(29, 30) /*!< SETUP packet count */
+#define DIEPLEN_MCNT BITS(29, 30) /*!< multi count */
+#define DEPLEN_PCNT BITS(19, 28) /*!< packet count */
+#define DEPLEN_TLEN BITS(0, 18) /*!< transfer length */
+
+/* device IN endpoint-x transmit FIFO status register bits definitions */
+#define DIEPTFSTAT_IEPTFS BITS(0, 15) /*!< IN endpoint¡¯s Tx FIFO space remaining */
+
+/* USB power and clock registers bits definition */
+#define PWRCLKCTL_SHCLK BIT(1) /*!< stop HCLK */
+#define PWRCLKCTL_SUCLK BIT(0) /*!< stop the USB clock */
+
+/* register options defines */
+#define DCFG_DEVSPEED(regval) (DCFG_DS & ((regval) << 0U)) /*!< device speed configuration */
+
+#define USB_SPEED_EXP_HIGH DCFG_DEVSPEED(0U) /*!< device external PHY high speed */
+#define USB_SPEED_EXP_FULL DCFG_DEVSPEED(1U) /*!< device external PHY full speed */
+#define USB_SPEED_INP_FULL DCFG_DEVSPEED(3U) /*!< device internal PHY full speed */
+
+#define GAHBCS_TFEL(regval) (GAHBCS_TXFTH & ((regval) << 7U)) /*!< device speed configuration */
+
+#define TXFIFO_EMPTY_HALF GAHBCS_TFEL(0U) /*!< Tx FIFO half empty */
+#define TXFIFO_EMPTY GAHBCS_TFEL(1U) /*!< Tx FIFO completely empty */
+
+#define GAHBCS_DMAINCR(regval) (GAHBCS_BURST & ((regval) << 1U)) /*!< AHB burst type used by DMA*/
+
+#define DMA_INCR0 GAHBCS_DMAINCR(0U) /*!< single burst type used by DMA*/
+#define DMA_INCR1 GAHBCS_DMAINCR(1U) /*!< 4-beat incrementing burst type used by DMA*/
+#define DMA_INCR4 GAHBCS_DMAINCR(3U) /*!< 8-beat incrementing burst type used by DMA*/
+#define DMA_INCR8 GAHBCS_DMAINCR(5U) /*!< 16-beat incrementing burst type used by DMA*/
+#define DMA_INCR16 GAHBCS_DMAINCR(7U) /*!< 32-beat incrementing burst type used by DMA*/
+
+#define DCFG_PFRI(regval) (DCFG_EOPFT & ((regval) << 11U)) /*!< end of periodic frame time configuration */
+
+#define FRAME_INTERVAL_80 DCFG_PFRI(0U) /*!< 80% of the frame time */
+#define FRAME_INTERVAL_85 DCFG_PFRI(1U) /*!< 85% of the frame time */
+#define FRAME_INTERVAL_90 DCFG_PFRI(2U) /*!< 90% of the frame time */
+#define FRAME_INTERVAL_95 DCFG_PFRI(3U) /*!< 95% of the frame time */
+
+#define DEP0_MPL(regval) (DEP0CTL_MPL & ((regval) << 0U)) /*!< maximum packet length configuration */
+
+#define EP0MPL_64 DEP0_MPL(0U) /*!< maximum packet length 64 bytes */
+#define EP0MPL_32 DEP0_MPL(1U) /*!< maximum packet length 32 bytes */
+#define EP0MPL_16 DEP0_MPL(2U) /*!< maximum packet length 16 bytes */
+#define EP0MPL_8 DEP0_MPL(3U) /*!< maximum packet length 8 bytes */
+
+/* endpoints address */
+
+/* first bit is direction(0 for Rx and 1 for Tx) */
+#define EP0_OUT ((uint8_t)0x00U) /*!< endpoint out 0 */
+#define EP0_IN ((uint8_t)0x80U) /*!< endpoint in 0 */
+#define EP1_OUT ((uint8_t)0x01U) /*!< endpoint out 1 */
+#define EP1_IN ((uint8_t)0x81U) /*!< endpoint in 1 */
+#define EP2_OUT ((uint8_t)0x02U) /*!< endpoint out 2 */
+#define EP2_IN ((uint8_t)0x82U) /*!< endpoint in 2 */
+#define EP3_OUT ((uint8_t)0x03U) /*!< endpoint out 3 */
+#define EP3_IN ((uint8_t)0x83U) /*!< endpoint in 3 */
+
+/* enable global interrupt */
+#define USB_GLOBAL_INT_ENABLE() (USB_GAHBCS |= GAHBCS_GINTEN)
+
+/* disable global interrupt */
+#define USB_GLOBAL_INT_DISABLE() (USB_GAHBCS &= ~GAHBCS_GINTEN)
+
+/* get current operation mode */
+#define USB_CURRENT_MODE_GET() (USB_GINTF & GINTF_COPM)
+
+/* read global interrupt flag */
+#define USB_CORE_INTR_READ(x) \
+do { \
+ uint32_t global_intf = USB_GINTF; \
+ (x) = global_intf & USB_GINTEN; \
+} while(0)
+
+/* read global interrupt flag */
+#define USB_DAOEP_INTR_READ(x) \
+do { \
+ uint32_t dev_all_ep_inten = USB_DAEPINTEN; \
+ uint32_t dev_all_ep_int = USB_DAEPINT; \
+ uint32_t out_ep_intb = DAEPINT_OEPITB; \
+ (x) = (dev_all_ep_inten & dev_all_ep_int & out_ep_intb) >> 16; \
+} while(0)
+
+/* read out endpoint-x interrupt flag */
+#define USB_DOEP_INTR_READ(x, EpID) \
+do { \
+ uint32_t out_epintf = USB_DOEPxINTF(EpID); \
+ (x) = out_epintf & USB_DOEPINTEN; \
+} while(0)
+
+/* read all in endpoint interrupt flag */
+#define USB_DAIEP_INTR_READ(x) \
+do { \
+ uint32_t dev_all_ep_inten = USB_DAEPINTEN; \
+ uint32_t dev_all_ep_int = USB_DAEPINT; \
+ uint32_t in_ep_intb = DAEPINT_IEPITB; \
+ (x) = dev_all_ep_inten & dev_all_ep_int & in_ep_intb; \
+} while(0)
+
+
+/* read in endpoint-x interrupt flag */
+#define USB_DIEP_INTR_READ(x, EpID) \
+do { \
+ uint32_t dev_ep_intf = USB_DIEPxINTF(EpID); \
+ uint32_t dev_ep_fifoempty_intf = (((USB_DIEPFEINTEN >> (EpID)) & 0x1U) << 7U); \
+ uint32_t dev_inep_inten = USB_DIEPINTEN; \
+ (x) = dev_ep_intf & (dev_ep_fifoempty_intf | dev_inep_inten); \
+} while(0)
+
+/* generate remote wakup signal */
+#define USB_REMOTE_WAKEUP_SET() (USB_DCTL |= DCTL_RWKUP)
+
+/* no remote wakup signal generate */
+#define USB_REMOTE_WAKEUP_RESET() (USB_DCTL &= ~DCTL_RWKUP)
+
+/* generate soft disconnect */
+#define USB_SOFT_DISCONNECT_ENABLE() (USB_DCTL |= DCTL_SD)
+
+/* no soft disconnect generate */
+#define USB_SOFT_DISCONNECT_DISABLE() (USB_DCTL &= ~DCTL_SD)
+
+/* set device address */
+#define USB_SET_DEVADDR(DevAddr) (USB_DCFG |= (DevAddr) << 4U)
+
+/* check whether frame is even */
+#define USB_EVEN_FRAME() (!(USB_HFINFR & 0x01U))
+
+/* read port status */
+#define USB_PORT_READ() (USB_HPCS & (~HPCS_PE) & (~HPCS_PCD) & (~HPCS_PEDC))
+
+/* usb clock initialize */
+#define USB_FSLSCLOCK_INIT(ClockFreq) (USB_HCTL &= ~HCTL_CLKSEL | (ClockFreq))
+
+/* get usb current speed */
+#define USB_CURRENT_SPEED_GET() ((USB_HPCS & HPCS_PS) >> 17)
+
+/* get usb current frame */
+#define USB_CURRENT_FRAME_GET() (USB_HFINFR & 0xFFFFU)
+
+#endif /* USB_REGS_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_std.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_std.h
new file mode 100644
index 0000000000000000000000000000000000000000..5871882ed3fb7aaf6c0a6f9ea9c436117aad593c
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usb_std.h
@@ -0,0 +1,212 @@
+/*!
+ \file usb_std.h
+ \brief USB 2.0 standard defines
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USB_STD_H
+#define USB_STD_H
+
+#include "usb_conf.h"
+
+#define USB_DEV_QUALIFIER_DESC_LEN 0x0AU /*!< USB device qualifier descriptor length */
+#define USB_DEV_DESC_LEN 0x12U /*!< USB device descriptor length */
+#define USB_CFG_DESC_LEN 0x09U /*!< USB device configuration descriptor length */
+#define USB_IF_DESC_LEN 0x09U /*!< USB device interface descriptor length */
+#define USB_EP_DESC_LEN 0x07U /*!< USB device endpoint descriptor length */
+#define USB_OTG_DESC_LEN 0x03U /*!< USB device OTG descriptor length */
+
+/* bit 7 of bmRequestType: data phase transfer direction */
+#define USB_DIR_MASK 0x80U /*!< USB transfer direction mask */
+#define USB_DIR_OUT 0x00U /*!< USB transfer OUT direction */
+#define USB_DIR_IN 0x80U /*!< USB transfer IN direction */
+
+/* bit 6..5 of bmRequestType: request type */
+#define USB_STANDARD_REQ 0x00U /*!< USB standard request */
+#define USB_CLASS_REQ 0x20U /*!< USB class request */
+#define USB_VENDOR_REQ 0x40U /*!< USB vebdor request */
+#define USB_REQ_MASK 0x60U /*!< USB request mask */
+
+/* bit 4..0 of bmRequestType: recipient type */
+#define USB_REQTYPE_DEVICE 0x00U /*!< USB device request type */
+#define USB_REQTYPE_INTERFACE 0x01U /*!< USB interface request type*/
+#define USB_REQTYPE_ENDPOINT 0x02U /*!< USB endpoint request type*/
+#define USB_REQTYPE_MASK 0x03U /*!< USB request type mask*/
+
+/* bRequest value */
+#define USBREQ_GET_STATUS 0x00U /*!< USB get status request*/
+#define USBREQ_CLEAR_FEATURE 0x01U /*!< USB clear feature request*/
+#define USBREQ_SET_FEATURE 0x03U /*!< USB set feature request*/
+#define USBREQ_SET_ADDRESS 0x05U /*!< USB set address request*/
+#define USBREQ_GET_DESCRIPTOR 0x06U /*!< USB get descriptor request*/
+#define USBREQ_SET_DESCRIPTOR 0x07U /*!< USB set descriptor request*/
+#define USBREQ_GET_CONFIGURATION 0x08U /*!< USB get configuration request*/
+#define USBREQ_SET_CONFIGURATION 0x09U /*!< USB set configuration request*/
+#define USBREQ_GET_INTERFACE 0x0AU /*!< USB get interface request*/
+#define USBREQ_SET_INTERFACE 0x0BU /*!< USB set interface request*/
+#define USBREQ_SYNCH_FRAME 0x0CU /*!< USB synchronize frame request*/
+
+/* descriptor types of usb specifications */
+#define USB_DESCTYPE_DEVICE 0x01U /*!< USB device descriptor type*/
+#define USB_DESCTYPE_CONFIGURATION 0x02U /*!< USB configuration descriptor type*/
+#define USB_DESCTYPE_STRING 0x03U /*!< USB string descriptor type*/
+#define USB_DESCTYPE_INTERFACE 0x04U /*!< USB interface descriptor type*/
+#define USB_DESCTYPE_ENDPOINT 0x05U /*!< USB endpoint descriptor type*/
+#define USB_DESCTYPE_DEVICE_QUALIFIER 0x06U /*!< USB device qualtfier descriptor type*/
+#define USB_DESCTYPE_OTHER_SPEED_CONFIGURATION 0x07U /*!< USB other speed configuration descriptor type*/
+#define USB_DESCTYPE_INTERFACE_POWER 0x08U /*!< USB interface power descriptor type*/
+
+#define USB_DESCTYPE_HID 0x21U /*!< USB HID descriptor type*/
+#define USB_DESCTYPE_HID_REPORT 0x22U /*!< USB HID report descriptor type*/
+
+#define USB_DEVDESC_SIZE 18U /*!< USB device descriptor size*/
+#define USB_CFGDESC_SIZE 9U /*!< USB configure descriptor size*/
+#define USB_INTDESC_SIZE 9U /*!< USB interface descriptor size*/
+#define USB_EPDESC_SIZE 7U /*!< USB endpoint descriptor size*/
+
+/* descriptor type and descriptor index */
+/* use the following values when USB host need to get descriptor */
+#define USB_DEVDESC ((USB_DESCTYPE_DEVICE << 8U) & 0xFF00U) /*!< USB device operation marco */
+#define USB_CFGDESC ((USB_DESCTYPE_CONFIGURATION << 8U) & 0xFF00U) /*!< USB configuration operation marco */
+#define USB_STRDESC ((USB_DESCTYPE_STRING << 8U) & 0xFF00U) /*!< USB string operation marco */
+#define USB_INTDESC ((USB_DESCTYPE_INTERFACE << 8U) & 0xFF00U) /*!< USB interface operation marco */
+#define USB_EPDESC ((USB_DESCTYPE_INTERFACE << 8U) & 0xFF00U) /*!< USB endpoint operation marco */
+#define USB_DEVQUADESC ((USB_DESCTYPE_DEVICE_QUALIFIER << 8U) & 0xFF00U) /*!< USB device qualifier operation marco */
+#define USB_OSPCFGDESC ((USB_DESCTYPE_OTHER_SPEED_CONFIGURATION << 8U) & 0xFF00U) /*!< USB other speed configuration operation marco */
+#define USB_INTPWRDESC ((USB_DESCTYPE_INTERFACE_POWER << 8U) & 0xFF00U) /*!< USB interface power operation marco */
+#define USB_HIDREPDESC ((USB_DESCTYPE_HID_REPORT << 8U) & 0xFF00U) /*!< USB HID report operation marco */
+#define USB_HIDDESC ((USB_DESCTYPE_HID << 8U) & 0xFF00U) /*!< USB HID operation marco */
+
+#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \
+ (uint16_t)(((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U))
+
+/* supported classes */
+#define USB_MSC_CLASS 0x08U /*!< USB MSC class*/
+#define USB_HID_CLASS 0x03U /*!< USB HID class*/
+
+/* interface descriptor field values for hid boot protocol */
+#define HID_BOOT_CODE 0x01U /*!< USB HID boot code*/
+#define HID_KEYBRD_BOOT_CODE 0x01U /*!< USB HID keyboard boot code*/
+#define HID_MOUSE_BOOT_CODE 0x02U /*!< USB HID mouse boot code*/
+
+/* as per usb specs 9.2.6.4 :standard request with data request timeout: 5sec
+ standard request with no data stage timeout : 50ms */
+#define DATA_STAGE_TIMEOUT 5000U /*!< USB data stage timeout*/
+#define NODATA_STAGE_TIMEOUT 50U /*!< USB no data stage timeout*/
+
+#define USBH_CFG_DESC_SET_SIZE (USB_CFGDESC_SIZE + USB_INTDESC_SIZE \
+ + (USBH_MAX_EP_NUM * USB_EPDESC_SIZE)) /*!< USB host set configuration descriptor size */
+
+#pragma pack(1)
+
+typedef union
+{
+ uint8_t data[8];
+
+ struct _setup_packet_struct
+ {
+ uint8_t bmRequestType; /*!< type of request */
+ uint8_t bRequest; /*!< request of setup packet */
+ uint16_t wValue; /*!< value of setup packet */
+ uint16_t wIndex; /*!< index of setup packet */
+ uint16_t wLength; /*!< length of setup packet */
+ } b;
+}usb_setup_union;
+
+typedef struct
+{
+ uint8_t bLength; /*!< size of the descriptor */
+ uint8_t bDescriptorType; /*!< type of the descriptor */
+} usb_descriptor_header_struct;
+
+typedef struct
+{
+ usb_descriptor_header_struct Header; /*!< descriptor header, including type and size */
+
+ uint16_t bcdUSB; /*!< BCD of the supported USB specification */
+ uint8_t bDeviceClass; /*!< USB device class */
+ uint8_t bDeviceSubClass; /*!< USB device subclass */
+ uint8_t bDeviceProtocol; /*!< USB device protocol */
+ uint8_t bMaxPacketSize0; /*!< size of the control (address 0) endpoint's bank in bytes */
+ uint16_t idVendor; /*!< vendor ID for the USB product */
+ uint16_t idProduct; /*!< unique product ID for the USB product */
+ uint16_t bcdDevice; /*!< product release (version) number */
+ uint8_t iManufacturer; /*!< string index for the manufacturer's name */
+ uint8_t iProduct; /*!< string index for the product name/details */
+ uint8_t iSerialNumber; /*!< string index for the product's globally unique hexadecimal serial number */
+ uint8_t bNumberConfigurations; /*!< total number of configurations supported by the device */
+} usb_descriptor_device_struct;
+
+typedef struct
+{
+ usb_descriptor_header_struct Header; /*!< descriptor header, including type and size */
+
+ uint16_t wTotalLength; /*!< size of the configuration descriptor header,and all sub descriptors inside the configuration */
+ uint8_t bNumInterfaces; /*!< total number of interfaces in the configuration */
+ uint8_t bConfigurationValue; /*!< configuration index of the current configuration */
+ uint8_t iConfiguration; /*!< index of a string descriptor describing the configuration */
+ uint8_t bmAttributes; /*!< configuration attributes */
+ uint8_t bMaxPower; /*!< maximum power consumption of the device while in the current configuration */
+} usb_descriptor_configuration_struct;
+
+typedef struct
+{
+ usb_descriptor_header_struct Header; /*!< descriptor header, including type and size */
+
+ uint8_t bInterfaceNumber; /*!< index of the interface in the current configuration */
+ uint8_t bAlternateSetting; /*!< alternate setting for the interface number */
+ uint8_t bNumEndpoints; /*!< total number of endpoints in the interface */
+ uint8_t bInterfaceClass; /*!< interface class ID */
+ uint8_t bInterfaceSubClass; /*!< interface subclass ID */
+ uint8_t bInterfaceProtocol; /*!< interface protocol ID */
+ uint8_t iInterface; /*!< index of the string descriptor describing the interface */
+} usb_descriptor_interface_struct;
+
+typedef struct
+{
+ usb_descriptor_header_struct Header; /*!< descriptor header, including type and size. */
+
+ uint8_t bEndpointAddress; /*!< logical address of the endpoint */
+ uint8_t bmAttributes; /*!< endpoint attributes */
+ uint16_t wMaxPacketSize; /*!< size of the endpoint bank, in bytes */
+ uint8_t bInterval; /*!< polling interval in milliseconds for the endpoint if it is an INTERRUPT or ISOCHRONOUS type */
+} usb_descriptor_endpoint_struct;
+
+typedef struct
+{
+ usb_descriptor_header_struct Header; /*!< descriptor header, including type and size. */
+ uint16_t wLANGID; /*!< LANGID code */
+}usb_descriptor_language_id_struct;
+
+#pragma pack()
+
+#endif /* USB_STD_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbd_core.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbd_core.h
new file mode 100644
index 0000000000000000000000000000000000000000..91e69eb724fa838b5f31ea0858070dc5b1beaf3d
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbd_core.h
@@ -0,0 +1,77 @@
+/*!
+ \file usbd_core.h
+ \brief USB device mode core driver header file
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USBD_CORE_H
+#define USBD_CORE_H
+
+#include "usbd_conf.h"
+#include "usb_core.h"
+#include "usbd_std.h"
+
+/* device status */
+#define USB_STATUS_DEFAULT 1U /* default status */
+#define USB_STATUS_ADDRESSED 2U /* addressed status */
+#define USB_STATUS_CONFIGURED 3U /* configured status */
+#define USB_STATUS_SUSPENDED 4U /* suspended status */
+
+/* function declarations */
+/* initailizes the USB device-mode handler stack */
+void usbd_init (usb_core_handle_struct *pudev, usb_core_id_enum core_id);
+/* endpoint initialization */
+void usbd_ep_init (usb_core_handle_struct *pudev, const usb_descriptor_endpoint_struct *ep_desc);
+/* endpoint deinitialize */
+void usbd_ep_deinit (usb_core_handle_struct *pudev, uint8_t ep_addr);
+/* endpoint prepare to receive data */
+void usbd_ep_rx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len);
+/* endpoint prepare to transmit data */
+void usbd_ep_tx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len);
+/* transmit data on the control channel */
+usbd_status_enum usbd_ctltx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len);
+/* receive data on the control channel */
+usbd_status_enum usbd_ctlrx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len);
+/* transmit status on the control channel */
+usbd_status_enum usbd_ctlstatus_tx (usb_core_handle_struct *pudev);
+/* receive status on the control channel */
+usbd_status_enum usbd_ctlstatus_rx (usb_core_handle_struct *pudev);
+/* set an endpoint to STALL status */
+void usbd_ep_stall (usb_core_handle_struct *pudev, uint8_t ep_addr);
+/* clear endpoint stalled status */
+void usbd_ep_clear_stall (usb_core_handle_struct *pudev, uint8_t ep_addr);
+/* flushes the FIFOs */
+void usbd_ep_fifo_flush (usb_core_handle_struct *pudev, uint8_t ep_addr);
+/* get the received data length */
+uint16_t usbd_rxcount_get (usb_core_handle_struct *pudev, uint8_t ep_num);
+
+#endif /* USBD_CORE_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbd_int.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbd_int.h
new file mode 100644
index 0000000000000000000000000000000000000000..b2b8d99e88e903411fa60bae7d98609fc575df2d
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbd_int.h
@@ -0,0 +1,53 @@
+/*!
+ \file usbd_int.h
+ \brief USB device mode interrupt handler header file
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USBD_INT_H
+#define USBD_INT_H
+
+#include "usbd_core.h"
+
+typedef struct
+{
+ uint8_t (*SOF) (usb_core_handle_struct *pudev);
+}usbd_int_cb_struct;
+
+extern usbd_int_cb_struct *usbd_int_fops;
+
+/* function declarations */
+/* USB device-mode interrupts global service routine handler */
+uint32_t usbd_isr (usb_core_handle_struct *pudev);
+
+#endif /* USBD_INT_H */
+
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbd_std.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbd_std.h
new file mode 100644
index 0000000000000000000000000000000000000000..d968082a1a34d5048dd45b77ce5073050e5f078f
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbd_std.h
@@ -0,0 +1,94 @@
+/*!
+ \file usbd_std.h
+ \brief USB 2.0 standard defines
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USBD_STD_H
+#define USBD_STD_H
+
+#include "usb_std.h"
+#include "usbd_core.h"
+#include "usbd_conf.h"
+#include
+
+#define USBD_LANGID_STR_IDX 0x00U /*!< USB language ID string index*/
+#define USBD_MFC_STR_IDX 0x01U /*!< USB manufacturer string index*/
+#define USBD_PRODUCT_STR_IDX 0x02U /*!< USB product string index*/
+#define USBD_SERIAL_STR_IDX 0x03U /*!< USB serial string index*/
+#define USBD_CONFIG_STR_IDX 0x04U /*!< USB configuration string index*/
+#define USBD_INTERFACE_STR_IDX 0x05U /*!< USB interface string index*/
+
+#define USB_STATUS_REMOTE_WAKEUP 0x02U /*!< USB remote wakeup status*/
+#define USB_STATUS_SELF_POWERED 0x01U /*!< USB self power status*/
+
+#define USB_FEATURE_ENDP_HALT 0x00U /*!< USB halt endpoint feature*/
+#define USB_FEATURE_REMOTE_WAKEUP 0x01U /*!< USB remote wakeup feature*/
+#define USB_FEATURE_TEST_MODE 0x02U /*!< USB test mode feature*/
+
+#define ENG_LANGID 0x0409U /*!< USB english language id*/
+#define CHN_LANGID 0x0804U /*!< USB chinese language id*/
+
+#define USB_DEVICE_DESC_SIZE 0x12U /*!< USB device descriptor size*/
+
+#define LOWBYTE(x) ((uint8_t)((x) & 0x00FFU)) /*!< USB lowbyte operation marco*/
+#define HIGHBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) /*!< USB highbyte operation marco*/
+
+#define USB_MIN(a, b) (((a) < (b)) ? (a) : (b)) /*!< USB minimum operation marco*/
+
+#define WIDE_STRING(string) _WIDE_STRING(string)
+#define _WIDE_STRING(string) L##string
+
+#define USBD_STRING_DESC(string) \
+ (uint8_t *)&(struct { \
+ uint8_t _len; \
+ uint8_t _type; \
+ wchar_t _data[sizeof(string)]; \
+ }) { \
+ sizeof(WIDE_STRING(string)) + 2U - 2U, \
+ USB_DESCTYPE_STRING, \
+ WIDE_STRING(string) \
+ }
+
+#define IS_NOT_EP0(ep_addr) (((ep_addr) != 0x00U) && ((ep_addr) != 0x80U))
+
+/* function declarations */
+/* USB device setup transaction*/
+usbd_status_enum usbd_setup_transaction (usb_core_handle_struct *pudev);
+/* USB device out transaction*/
+usbd_status_enum usbd_out_transaction (usb_core_handle_struct *pudev, uint8_t endp_num);
+/* USB device in transaction*/
+usbd_status_enum usbd_in_transaction (usb_core_handle_struct *pudev, uint8_t endp_num);
+/* USB device enum error handle*/
+void usbd_enum_error (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+
+#endif /* USBD_STD_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_core.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_core.h
new file mode 100644
index 0000000000000000000000000000000000000000..f2b16fc179202417d7722300e8edfbe14a4a3e09
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_core.h
@@ -0,0 +1,307 @@
+/*!
+ \file usbh_core.h
+ \brief header file for usbh_core.c
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USBH_CORE_H
+#define USBH_CORE_H
+
+#include "usbh_conf.h"
+#include "usb_std.h"
+#include "usb_core.h"
+
+#define MSC_CLASS 0x08 /*!< the MSC class define */
+#define HID_CLASS 0x03 /*!< the HID class define */
+#define MSC_PROTOCOL 0x50 /*!< the MSC protocal define */
+#define CBI_PROTOCOL 0x01 /*!< the CBI protocal define */
+
+#define USBH_DEVICE_ADDRESS_DEFAULT 0U /*!< the default device address define */
+#define USBH_DEVICE_ADDRESS 1U /*!< the device address define */
+#define USBH_MAX_ERROR_COUNT 2U /*!< the max error count define */
+
+#define HOST_USER_SELECT_CONFIGURATION 1U /*!< the user select configuration define */
+#define HOST_USER_CLASS_ACTIVE 2U /*!< the user class active define */
+#define HOST_USER_CLASS_SELECTED 3U /*!< the user class selected define */
+#define HOST_USER_CONNECTION 4U /*!< the user connecttion define */
+#define HOST_USER_DISCONNECTION 5U /*!< the user disconnection define */
+#define HOST_USER_UNRECOVERED_ERROR 6U /*!< the user unrecovered error define */
+
+#define MAX_USBH_STATE_STACK_DEEP 4 /*!< the max state stack deep define */
+#define MAX_USBH_STATE_TABLE_NUM 10U /*!< the max state table number */
+
+#define HOST_FSM_ID 0U /*!< the host state table id */
+#define ENUM_FSM_ID 1U /*!< the enum state table id */
+#define CMD_FSM_ID 2U /*!< the cmd state table id */
+#define CTRL_FSM_ID 3U /*!< the ctrl state table id */
+#define CLASS_REQ_FSM_ID 4U /*!< the class req state table id */
+#define CLASS_FSM_ID 5U /*!< the class state table id */
+
+#define UP_STATE 100U /*!< up state define */
+#define GO_TO_UP_STATE_EVENT 100U /*!< go to up state event define */
+
+#define HOST_HANDLE_TABLE_SIZE 9U /*!< the host handle table size define */
+
+/* the enum of host state */
+typedef enum
+{
+ HOST_IDLE = 0, /* the host idle state definition */
+ HOST_DEV_ATTACHED, /* the host device attached state definition */
+ HOST_DEV_DETACHED, /* the host device detached state definition */
+ HOST_DETECT_DEV_SPEED, /* the host detect device speed state definition */
+ HOST_ENUMERATION, /* the host enumeration state definition */
+ HOST_CLASS_REQUEST, /* the host class request state definition */
+ HOST_CLASS, /* the host class state definition */
+ HOST_USER_INPUT, /* the host user input state definition */
+ HOST_SUSPENDED, /* the host suspended state definition */
+ HOST_ERROR /* the host error state definition */
+}host_state_enum;
+
+/* the enum of host event */
+typedef enum
+{
+ HOST_EVENT_ATTACHED = 0, /* the host attached event */
+ HOST_EVENT_ENUM, /* the host enum event */
+ HOST_EVENT_USER_INPUT, /* the host user input event */
+ HOST_EVENT_CLASS_REQ, /* the host class request event */
+ HOST_EVENT_CLASS, /* the host class event */
+ HOST_EVENT_ERROR, /* the host error event */
+ HOST_EVENT_DEV_DETACHED, /* the host device detached event */
+ HOST_EVENT_IDLE /* the host idle event */
+}host_event_enum;
+
+/* the enum of enum state */
+typedef enum
+{
+ ENUM_IDLE = 0, /* the enum idle state definition */
+ ENUM_SET_ADDR, /* the enum set address state definition */
+ ENUM_GET_FULL_DEV_DESC, /* the enum get full device descripter state definition */
+ ENUM_GET_CFG_DESC, /* the enum get configuration descripter state definition */
+ ENUM_GET_FULL_CFG_DESC, /* the enum get full configuration descripter state definition */
+ ENUM_GET_MFC_STRING_DESC, /* the enum get MFC string descripter state definition */
+ ENUM_GET_PRODUCT_STRING_DESC, /* the enum get product string descripter state definition */
+ ENUM_GET_SERIALNUM_STRING_DESC, /* the enum get serialnum string descripter state definition */
+ ENUM_SET_CONFIGURATION, /* the enum set congiguration state definition */
+ ENUM_DEV_CONFIGURED /* the enum device configuration state definition */
+}enum_state_enum;
+
+/* the enum of ctrl state */
+typedef enum
+{
+ CTRL_IDLE = 0, /* the ctrl idle state definition */
+ CTRL_SETUP, /* the ctrl setup state definition */
+ CTRL_DATA, /* the ctrl data state definition */
+ CTRL_STATUS, /* the ctrl status state definition */
+ CTRL_ERROR, /* the ctrl error state definition */
+ CTRL_STALLED, /* the ctrl stalled state definition */
+ CTRL_COMPLETE /* the ctrl complete state definition */
+}ctrl_state_enum;
+
+/* the enum of host status */
+typedef enum
+{
+ USBH_OK = 0, /* the usbh ok status definition */
+ USBH_BUSY, /* the usbh busy status definition */
+ USBH_FAIL, /* the usbh fail status definition */
+ USBH_NOT_SUPPORTED, /* the usbh not supported status definition */
+ USBH_UNRECOVERED_ERROR, /* the usbh unrecovered error status definition */
+ USBH_SPEED_UNKNOWN_ERROR, /* the usbh speed unknown error status definition */
+ USBH_APPLY_DEINIT /* the usbh apply deinit status definition */
+}usbh_status_enum;
+
+/* the state of user action */
+typedef enum
+{
+ USBH_USER_NO_RESP = 0, /* the user no response */
+ USBH_USER_RESP_OK = 1, /* the user response ok */
+}usbh_user_status_enum;
+
+/* control transfer information */
+typedef struct
+{
+ uint8_t hc_in_num; /* the host in channel number */
+ uint8_t hc_out_num; /* the host out channel number */
+ uint8_t ep0_size; /* the endpoint 0 max packet size */
+ uint8_t error_count; /* the error count */
+ uint16_t length; /* the length */
+ uint16_t timer; /* the timer */
+ uint8_t *buff; /* the buffer */
+ usb_setup_union setup; /* the setup packet */
+}usbh_ctrl_struct;
+
+/* device property */
+typedef struct
+{
+ uint8_t address; /* the device address */
+ uint8_t speed; /* the device speed */
+ usb_descriptor_device_struct dev_desc; /* the device descripter */
+ usb_descriptor_configuration_struct cfg_desc; /* the configuration descripter */
+ usb_descriptor_interface_struct itf_desc[USBH_MAX_INTERFACES_NUM]; /* the interface descripter */
+ usb_descriptor_endpoint_struct ep_desc[USBH_MAX_INTERFACES_NUM][USBH_MAX_EP_NUM]; /* the endpoint descripter */
+}usbh_device_struct;
+
+/* user callbacks */
+typedef struct
+{
+ void (*init) (void); /* the user callback init function */
+ void (*deinit) (void); /* the user callback deinit function */
+ void (*device_connected) (void); /* the user callback device connected function */
+ void (*device_reset) (void); /* the user callback device reset function */
+ void (*device_disconnected) (void); /* the user callback device disconnected function */
+ void (*over_current_detected) (void); /* the user callback over current detected function */
+ void (*device_speed_detected) (uint8_t device_speed); /* the user callback device speed detected function */
+ void (*device_desc_available) (void *devDesc); /* the user callback device descrpiter available function */
+ void (*device_address_set) (void); /* the user callback set device address function */
+
+ void (*configuration_desc_available)(usb_descriptor_configuration_struct *cfg_desc,
+ usb_descriptor_interface_struct *itf_desc,
+ usb_descriptor_endpoint_struct *ep_desc);
+ /* the configuration descripter available function */
+
+ void (*manufacturer_string) (void *mfc_string); /* the user callback manufacturer string function */
+ void (*product_string) (void *prod_string); /* the user callback product string function */
+ void (*serial_num_string) (void *serial_string); /* the user callback serial number string function */
+ void (*enumeration_finish) (void); /* the user callback enumeration finish function */
+ usbh_user_status_enum (*user_input) (void); /* the user callback user input function */
+ int (*user_application) (usb_core_handle_struct *pudev, uint8_t id);
+ /* the user callback user appliction function */
+ void (*device_not_supported) (void); /* the user callback device not supported function */
+ void (*unrecovered_error) (void); /* the user callback unrecovered error function */
+}usbh_user_callback_struct;
+
+/* the backup state struct */
+typedef struct
+{
+ host_state_enum host_backup_state; /* the host backup state */
+ enum_state_enum enum_backup_state; /* the enum backup state */
+ ctrl_state_enum ctrl_backup_state; /* the ctrl backup state */
+ uint8_t class_req_backup_state;/* the class request backup state */
+ uint8_t class_backup_state; /* the class backup state */
+} backup_state_struct;
+
+/* host information */
+typedef struct
+{
+ backup_state_struct usbh_backup_state; /* the usbh backup state variable */
+ usbh_ctrl_struct control; /* the control struct variable */
+ usbh_device_struct device; /* the device struct variable */
+ usbh_user_callback_struct *usr_cb; /* the user callback function */
+ usbh_status_enum (*class_init) (usb_core_handle_struct *pudev, void *phost); /* the class init function */
+ void (*class_deinit) (usb_core_handle_struct *pudev, void *phost); /* the class deinit function */
+}usbh_host_struct;
+
+/* the action function definition */
+typedef usbh_status_enum (*ACT_FUN) (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void* pustate);
+
+/* the state table struct */
+typedef struct
+{
+ uint8_t cur_state; /* the current state */
+ uint8_t cur_event; /* the current event */
+ uint8_t next_state; /* the next state */
+ ACT_FUN event_action_fun; /* the event action function entry */
+} state_table_struct;
+
+/* the state stack struct */
+typedef struct
+{
+ uint8_t state; /* the state in state stack */
+ state_table_struct* table; /* the table in state stack */
+ uint8_t table_size; /* the table size in state stack */
+} usbh_state_stack_struct;
+
+/* the state regist table struct */
+typedef struct
+{
+ uint8_t id; /* the id of the state table */
+ state_table_struct* table; /* the table entry to regist */
+ uint8_t table_size; /* the table size to regist */
+} usbh_state_regist_table_struct;
+
+/* the state handle struct */
+typedef struct
+{
+ uint8_t usbh_current_state; /* current state */
+ uint8_t usbh_current_state_table_size; /* current state table size */
+ state_table_struct* usbh_current_state_table; /* current state table */
+
+ usbh_state_stack_struct stack[MAX_USBH_STATE_STACK_DEEP]; /* the stack of state table */
+ int8_t usbh_current_state_stack_top; /* the current state top */
+
+ usbh_state_regist_table_struct usbh_regist_state_table[MAX_USBH_STATE_TABLE_NUM]; /* the array of regist state table */
+ uint8_t usbh_regist_state_table_num; /* the number of regist state table */
+} usbh_state_handle_struct;
+
+/* function declarations */
+/* the host core driver function */
+usbh_status_enum host_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+/* initialize the host portion of the driver */
+uint32_t hcd_init (usb_core_handle_struct *pudev, usb_core_id_enum core_id);
+/* check if the device is connected */
+uint32_t hcd_is_device_connected (usb_core_handle_struct *pudev);
+/* this function returns the last URBstate */
+urb_state_enum hcd_urb_state_get (usb_core_handle_struct *pudev, uint8_t channel_num);
+/* this function returns the last URBstate */
+uint32_t hcd_xfer_count_get (usb_core_handle_struct *pudev, uint8_t channel_num);
+/* de-initialize host */
+usbh_status_enum usbh_deinit (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct* pustate);
+
+/* the state core driver function */
+/* state core driver init */
+void scd_init (usbh_state_handle_struct* pustate);
+/* state core driver table regist */
+void scd_table_regist (usbh_state_handle_struct* pustate,
+ state_table_struct* pstate_table,
+ uint8_t table_id,
+ uint8_t current_table_size);
+/* state core driver begin */
+void scd_begin (usbh_state_handle_struct* pustate, uint8_t table_id);
+/* state core driver move state */
+void scd_state_move (usbh_state_handle_struct* pustate, uint8_t state);
+/* state core driver event handle */
+usbh_status_enum scd_event_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct* pustate,
+ uint8_t event,
+ uint8_t state);
+/* state core driver table push */
+void scd_table_push (usbh_state_handle_struct* pustate);
+/* state core driver table pop */
+void scd_table_pop (usbh_state_handle_struct* pustate);
+/* the function is only used to state move */
+usbh_status_enum only_state_move (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+/* the function to the up state */
+usbh_status_enum goto_up_state_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+
+#endif /* USBH_CORE_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_ctrl.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_ctrl.h
new file mode 100644
index 0000000000000000000000000000000000000000..19534dc5182147b45ca8b711adbf0dffc2414780
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_ctrl.h
@@ -0,0 +1,69 @@
+/*!
+ \file usbh_ctrl.h
+ \brief header file for usbh_ctrl.c
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USBH_CTRL_H
+#define USBH_CTRL_H
+
+#include "usbh_core.h"
+#include "usbh_usr.h"
+
+#define CTRL_HANDLE_TABLE_SIZE 13U /*!< the ctrl handle table size define */
+
+extern state_table_struct ctrl_handle_table[CTRL_HANDLE_TABLE_SIZE];
+extern uint8_t ctrl_polling_handle_flag;
+
+/* the enum of CTRL event */
+typedef enum
+{
+ CTRL_EVENT_IDLE = 0, /* the ctrl idle event */
+ CTRL_EVENT_SETUP, /* the ctrl setup event */
+ CTRL_EVENT_DATA, /* the ctrl data event */
+ CTRL_EVENT_STATUS, /* the ctrl status event */
+ CTRL_EVENT_COMPLETE, /* the ctrl complete event */
+ CTRL_EVENT_ERROR, /* the ctrl error event */
+ CTRL_EVENT_STALLED, /* the ctrl stalled event */
+}ctrl_event_enum;
+
+/* function declarations */
+/* the polling function of control transfer state handle */
+usbh_status_enum ctrl_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+/* send datas from the host channel */
+usbh_status_enum usbh_xfer (usb_core_handle_struct *pudev, uint8_t *buf, uint8_t hc_num, uint16_t len);
+/* send the setup packet to the device */
+usbh_status_enum usbh_ctltx_setup (usb_core_handle_struct *pudev, uint8_t *buf, uint8_t hc_num);
+/* this function prepare a hc and start a transfer */
+uint32_t hcd_submit_request (usb_core_handle_struct *pudev, uint8_t channel_num);
+
+#endif /* USBH_CTRL_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_hcs.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_hcs.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e566e6ff7f399df9eb4a45f2ef20476bbd3a8ab
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_hcs.h
@@ -0,0 +1,70 @@
+/*!
+ \file usbh_hcs.h
+ \brief header file for usbh_hcs.c
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USBH_HCS_H
+#define USBH_HCS_H
+
+#include "usbh_core.h"
+
+#define HC_MAX 8U
+
+#define HC_OK 0x0000U
+#define HC_USED 0x8000U
+#define HC_ERROR 0xFFFFU
+#define HC_USED_MASK 0x7FFFU
+
+/* function declarations */
+/* allocate a new channel for the pipe */
+uint8_t usbh_channel_alloc (usb_core_handle_struct *pudev, uint8_t ep_addr);
+/* free all usb host channel */
+uint8_t usbh_allchannel_dealloc (usb_core_handle_struct *pudev);
+/* free the usb host channel */
+uint8_t usbh_channel_free (usb_core_handle_struct *pudev, uint8_t index);
+/* open a channel */
+uint8_t usbh_channel_open (usb_core_handle_struct *pudev,
+ uint8_t channel_num,
+ uint8_t dev_addr,
+ uint8_t dev_speed,
+ uint8_t ep_type,
+ uint16_t ep_mps);
+/* modify a channel */
+uint8_t usbh_channel_modify (usb_core_handle_struct *pudev,
+ uint8_t channel_num,
+ uint8_t dev_addr,
+ uint8_t dev_speed,
+ uint8_t ep_type,
+ uint16_t ep_mps);
+
+#endif /* USBH_HCS_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_int.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_int.h
new file mode 100644
index 0000000000000000000000000000000000000000..b5fe3bb951d7d0eed7cb7dca26d92328e8511c23
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_int.h
@@ -0,0 +1,54 @@
+/*!
+ \file usbh_int.h
+ \brief USB host mode interrupt handler header file
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USBH_INT_H
+#define USBH_INT_H
+
+#include "usb_core.h"
+
+typedef struct
+{
+ uint8_t (*sof) (usb_core_handle_struct *pudev);
+ uint8_t (*device_connected) (usb_core_handle_struct *pudev);
+ uint8_t (*device_disconnected) (usb_core_handle_struct *pudev);
+}usbh_hcd_int_cb_struct;
+
+extern usbh_hcd_int_cb_struct *usbh_hcd_int_fops;
+
+/* function declarations */
+/* handle global host interrupt */
+uint32_t usbh_isr (usb_core_handle_struct *pudev);
+
+#endif /* USBH_INT_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_std.h b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_std.h
new file mode 100644
index 0000000000000000000000000000000000000000..48bc65c78519c37bffb6fb43a23d2383725cda49
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Include/usbh_std.h
@@ -0,0 +1,98 @@
+/*!
+ \file usbh_std.h
+ \brief header file for usbh_std.c
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 USBH_STD_H
+#define USBH_STD_H
+
+#include "usbh_core.h"
+#include "usbh_usr.h"
+
+/* standard feature selector for clear feature command */
+#define FEATURE_SELECTOR_ENDPOINT 0x00U
+#define FEATURE_SELECTOR_DEVICE 0x01U
+
+#define USBH_SETUP_PACKET_SIZE 8U /* setup packet size */
+#define ENUM_HANDLE_TABLE_SIZE 10U /* enumerate handle table size */
+
+extern uint8_t usbh_cfg_desc[512];
+extern uint8_t enum_polling_handle_flag;
+extern state_table_struct enum_handle_table[ENUM_HANDLE_TABLE_SIZE];
+
+typedef enum
+{
+ ENUN_EVENT_IDLE = 0, /* the enum idle event */
+ ENUM_EVENT_SET_ADDR, /* the enum set address event */
+ ENUN_EVENT_GET_FULL_DEV_DESC, /* the enum get full device descripter event */
+ ENUN_EVENT_GET_CFG_DESC, /* the enum get congiguration descripter event */
+ ENUN_EVENT_GET_FULL_CFG_DESC, /* the enum get full configuration descripter event */
+ ENUN_EVENT_GET_MFC_STRING_DESC, /* the enum get MFC string descripter event */
+ ENUN_EVENT_GET_PRODUCT_STRING_DESC, /* the enum get product string event */
+ ENUN_EVENT_GET_SERIALNUM_STRING_DESC, /* the enum get serialnum string event */
+ ENUN_EVENT_SET_CONFIGURATION, /* the enum set configuration event */
+ ENUN_EVENT_DEV_CONFIGURED /* the enum device configured event */
+}enum_event_enum;
+
+/* function declarations */
+/* the polling function of enumeration state */
+usbh_status_enum enum_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+/* get descriptor in usb host enumeration stage */
+void usbh_enum_desc_get (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ uint8_t *buf,
+ uint8_t req_type,
+ uint16_t value_idx,
+ uint16_t len);
+/* set address in usb host enumeration stage */
+void usbh_enum_addr_set (usb_core_handle_struct *pudev, usbh_host_struct *puhost, uint8_t device_address);
+/* set configuration in usb host enumeration stage */
+void usbh_enum_cfg_set (usb_core_handle_struct *pudev, usbh_host_struct *puhost, uint16_t cfg_idx);
+/* parse the device descriptor */
+void usbh_device_desc_parse (usb_descriptor_device_struct *dev_desc, uint8_t *buf, uint16_t len);
+/* parse the configuration descriptor */
+void usbh_cfg_desc_parse (usb_descriptor_configuration_struct *cfg_desc,
+ usb_descriptor_interface_struct *itf_desc,
+ usb_descriptor_endpoint_struct ep_desc[][USBH_MAX_EP_NUM],
+ uint8_t *buf,
+ uint16_t len);
+/* parse the interface descriptor */
+void usbh_interface_desc_parse (usb_descriptor_interface_struct *itf_desc, uint8_t *buf);
+/* parse the endpoint descriptor */
+void usbh_endpoint_desc_parse (usb_descriptor_endpoint_struct *ep_desc, uint8_t *buf);
+/* parse the string descriptor */
+void usbh_string_desc_parse (uint8_t *psrc, uint8_t *pdest, uint16_t len);
+/* get the next descriptor header */
+usb_descriptor_header_struct *usbh_next_desc_get (uint8_t *pbuf, uint16_t *ptr);
+
+#endif /* USBH_STD_H */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/system_gd32f3x0.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/system_gd32f3x0.c
new file mode 100644
index 0000000000000000000000000000000000000000..0ebd5ddea2dcc8fe1a151a0bf02b999a79d593bb
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/system_gd32f3x0.c
@@ -0,0 +1,665 @@
+/*!
+ \file system_gd32f3x0.c
+ \brief CMSIS Cortex-M4 Device Peripheral Access Layer Source File for
+ GD32F3x0 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 "gd32f3x0.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 */
+
+/* select a system clock by uncommenting the following line */
+#if defined (GD32F330)
+//#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 __SYSTEM_CLOCK_84M_PLL_HXTAL (uint32_t)(84000000)
+//#define __SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2 (uint32_t)(84000000)
+#endif /* GD32F330 */
+
+#if defined (GD32F350)
+//#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 __SYSTEM_CLOCK_84M_PLL_HXTAL (uint32_t)(84000000)
+//#define __SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2 (uint32_t)(84000000)
+//#define __SYSTEM_CLOCK_96M_PLL_HXTAL (uint32_t)(96000000)
+#define __SYSTEM_CLOCK_96M_PLL_IRC8M_DIV2 (uint32_t)(96000000)
+//#define __SYSTEM_CLOCK_108M_PLL_HXTAL (uint32_t)(108000000)
+//#define __SYSTEM_CLOCK_108M_PLL_IRC8M_DIV2 (uint32_t)(108000000)
+#endif /* GD32F350 */
+
+#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);
+
+#elif defined (__SYSTEM_CLOCK_84M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_84M_PLL_HXTAL;
+static void system_clock_84m_hxtal(void);
+
+#elif defined (__SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2;
+static void system_clock_84m_irc8m(void);
+
+#elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_96M_PLL_HXTAL;
+static void system_clock_96m_hxtal(void);
+
+#elif defined (__SYSTEM_CLOCK_96M_PLL_IRC8M_DIV2)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_96M_PLL_IRC8M_DIV2;
+static void system_clock_96m_irc8m(void);
+
+#elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_HXTAL;
+static void system_clock_108m_hxtal(void);
+
+#elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M_DIV2)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_IRC8M_DIV2;
+static void system_clock_108m_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);
+#if (defined(GD32F350))
+ RCU_CFG0 &= ~(RCU_CFG0_USBFSPSC);
+ RCU_CFG2 &= ~(RCU_CFG2_CECSEL | RCU_CFG2_USBFSPSC2);
+#endif /* GD32F350 */
+ RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS);
+ RCU_CFG1 &= ~(RCU_CFG1_PREDV | RCU_CFG1_PLLMF5 | RCU_CFG1_PLLPRESEL);
+ RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_ADCSEL);
+ RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV;
+ RCU_CFG2 &= ~RCU_CFG2_ADCPSC2;
+ RCU_CTL1 &= ~RCU_CTL1_IRC28MEN;
+ RCU_ADDCTL &= ~RCU_ADDCTL_IRC48MEN;
+ RCU_INT = 0x00000000U;
+ RCU_ADDINT = 0x00000000U;
+ /* configure system clock */
+ system_clock_config();
+}
+
+/*!
+ \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_84M_PLL_HXTAL)
+ system_clock_84m_hxtal();
+#elif defined (__SYSTEM_CLOCK_84M_PLL_IRC8M_DIV2)
+ system_clock_84m_irc8m();
+#elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL)
+ system_clock_96m_hxtal();
+#elif defined (__SYSTEM_CLOCK_96M_PLL_IRC8M_DIV2)
+ system_clock_96m_irc8m();
+#elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
+ system_clock_108m_hxtal();
+#elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M_DIV2)
+ system_clock_108m_irc8m();
+#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)){
+ return;
+ }
+
+ /* 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)){
+ return;
+ }
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* PLL = HXTAL * 9 = 72 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV);
+ RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | 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)
+{
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+ /* 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)){
+ }
+}
+
+#elif defined (__SYSTEM_CLOCK_84M_PLL_HXTAL)
+/*!
+ \brief configure the system clock to 84M by PLL which selects HXTAL as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_84m_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)){
+ return;
+ }
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* PLL = HXTAL /2 * 21 = 84 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV);
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PLLMF5);
+ RCU_CFG1 |= RCU_PLL_PREDV2;
+ RCU_CFG0 |= (RCU_CFG0_PLLSEL | RCU_PLL_MUL21);
+
+ /* 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_84M_PLL_IRC8M_DIV2)
+/*!
+ \brief configure the system clock to 84M by PLL which selects IRC8M/2 as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_84m_irc8m(void)
+{
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+ /* PLL = (IRC8M/2) * 21 = 84 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF);
+ RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL21);
+
+ /* 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_96M_PLL_HXTAL)
+/*!
+ \brief configure the system clock to 96M by PLL which selects HXTAL as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_96m_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)){
+ return;
+ }
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* PLL = HXTAL /2 * 24 = 96 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV);
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PLLMF5);
+ RCU_CFG1 |= RCU_PLL_PREDV2;
+ RCU_CFG0 |= (RCU_CFG0_PLLSEL | RCU_PLL_MUL24);
+
+ /* 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_96M_PLL_IRC8M_DIV2)
+/*!
+ \brief configure the system clock to 96M by PLL which selects IRC8M/2 as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_96m_irc8m(void)
+{
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+ /* PLL = (IRC8M/2) * 24 = 96 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF);
+ RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL24);
+
+ /* 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_108M_PLL_HXTAL)
+/*!
+ \brief configure the system clock to 84M by PLL which selects HXTAL as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_108m_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)){
+ return;
+ }
+ /* HXTAL is stable */
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+
+ /* PLL = HXTAL /2 * 27 = 108 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV);
+ RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PLLMF5);
+ RCU_CFG1 |= RCU_PLL_PREDV2;
+ RCU_CFG0 |= (RCU_CFG0_PLLSEL | RCU_PLL_MUL27);
+
+ /* 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_108M_PLL_IRC8M_DIV2)
+/*!
+ \brief configure the system clock to 108M by PLL which selects IRC8M/2 as its clock source
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+static void system_clock_108m_irc8m(void)
+{
+ /* AHB = SYSCLK */
+ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+ /* APB2 = AHB/2 */
+ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
+ /* APB1 = AHB/2 */
+ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
+ /* PLL = (IRC8M/2) * 27 = 108 MHz */
+ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF);
+ RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL27);
+
+ /* 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, pllmf5 = 0U, pllsel = 0U, pllpresel = 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);
+ pllmf5 = GET_BITS(RCU_CFG1, 31, 31);
+ /* high 16 bits */
+ if(1U == pllmf4){
+ pllmf += 17U;
+ }else{
+ pllmf += 2U;
+ }
+ if(1U == pllmf5){
+ pllmf += 31U;
+ }
+ /* 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);
+ if(0U == pllpresel){
+ SystemCoreClock = (HXTAL_VALUE / prediv) * pllmf;
+ }else{
+ SystemCoreClock = (IRC48M_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;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usb_core.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usb_core.c
new file mode 100644
index 0000000000000000000000000000000000000000..336645e746b5bb11618b58046936a97d7c34757c
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usb_core.c
@@ -0,0 +1,959 @@
+/*!
+ \file usb_core.c
+ \brief USB core driver which can operate in host-mode and device-mode
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "usb_core.h"
+
+static void usb_commonint_enable (usb_core_handle_struct *pudev);
+static usb_status_enum usb_core_reset (usb_core_handle_struct *pudev);
+
+/*!
+ \brief enable the commmon interrupts which are used in both device and host modes
+ \param[in] pudev: pointer to selected usb device
+ \param[out] none
+ \retval none
+*/
+static void usb_commonint_enable (usb_core_handle_struct *pudev)
+{
+#ifndef USE_OTG_MODE
+
+ /* clear any pending USB interrupts */
+ USB_GOTGINTF = 0xFFFFFFFFU;
+
+#endif /* USE_OTG_MODE */
+
+ /* enable the usb wakeup and suspend interrupts */
+ USB_GINTEN = GINTEN_WKUPIE | GINTEN_SPIE;
+
+#ifdef USE_OTG_MODE
+
+ /* enable the OTG interrupts, session interrrupts and connector ID pin interrupt */
+ USB_GINTEN |= GINTEN_OTGIE | GINTEN_SESIE | GINTEN_CIDPSCIE;
+
+#endif /* USE_OTG_MODE */
+}
+
+/*!
+ \brief soft reset of the OTG_FS core
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval operation status
+*/
+static usb_status_enum usb_core_reset (usb_core_handle_struct *pudev)
+{
+ uint32_t count = 0U;
+
+ /* enable core soft reset */
+ USB_GRSTCTL |= GRSTCTL_CSRST;
+
+ /* wait for the core to be soft reset */
+ do {
+ if (++count > 200000U) {
+ break;
+ }
+ } while (1U == (USB_GRSTCTL & GRSTCTL_CSRST));
+
+ /* wait for addtional 3 PHY clocks */
+ if (NULL != pudev->udelay) {
+ pudev->udelay(3U);
+ }
+
+ return USB_OK;
+}
+
+/*!
+ \brief write a packet into the Tx FIFO associated with the endpoint
+ \param[in] src: pointer to source buffer
+ \param[in] chep_num: channel or endpoint identifier which is in (0..3)
+ \param[in] len: packet length
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_fifo_write (uint8_t *src, uint8_t chep_num, uint16_t len)
+{
+ uint32_t count32b = 0U, i = 0U;
+ __IO uint32_t *fifo = USB_FIFO(chep_num);
+
+ count32b = (len + 3U) / 4U;
+
+ for (i = 0U; i < count32b; i++) {
+ *fifo = *((__packed uint32_t *)src);
+
+ src += 4U;
+ }
+
+ return USB_OK;
+}
+
+/*!
+ \brief read a packet from the Rx FIFO associated with the endpoint
+ \param[in] dest: pointer to destination buffer
+ \param[in] len: packet length
+ \param[out] none
+ \retval void type pointer
+*/
+void *usb_fifo_read (uint8_t *dest, uint16_t len)
+{
+ uint32_t i = 0U;
+ uint32_t count32b = (len + 3U) / 4U;
+
+ __IO uint32_t *fifo = USB_FIFO(0U);
+
+ for (i = 0U; i < count32b; i++) {
+ *(__packed uint32_t *)dest = *fifo;
+
+ dest += 4U;
+ }
+
+ return ((void *)dest);
+}
+
+/*!
+ \brief initialize core parameters
+ \param[in] pudev: pointer to usb device
+ \param[in] core_id: USB core id
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_core_select (usb_core_handle_struct *pudev, usb_core_id_enum core_id)
+{
+ /* at startup the core is in FS mode */
+ pudev->cfg.core_speed = USB_CORE_SPEED_FULL;
+ pudev->cfg.max_packet_size = USBFS_MAX_PACKET_SIZE;
+
+ /* initialize the core parameters */
+ if (USB_FS_CORE_ID == core_id) {
+
+ pudev->cfg.core_id = USB_FS_CORE_ID;
+
+ /* set the host channel numbers */
+ pudev->cfg.host_channel_num = USBFS_MAX_HOST_CHANNELCOUNT;
+
+ /* set the device endpoint numbers */
+ pudev->cfg.dev_endp_num = USBFS_MAX_DEV_EPCOUNT;
+
+ /* fifo size is in terms of DWORD */
+ pudev->cfg.max_fifo_size = USBFS_MAX_FIFO_WORDLEN;
+
+ /* OTG_FS core use embedded physical layer */
+ pudev->cfg.phy_interface = USB_CORE_EMBEDDED_PHY;
+
+ #ifdef USBFS_SOF_OUTPUT_ENABLED
+ pudev->cfg.sof_output = 1U;
+ #endif /* USBFS_SOF_OUTPUT_ENABLED */
+
+ #ifdef USBFS_LOW_PWR_MGMT_SUPPORT
+ pudev->cfg.low_power = 1U;
+ #endif /* USBFS_LOW_PWR_MGMT_SUPPORT */
+ }
+
+ return USB_OK;
+}
+
+/*!
+ \brief initializes the USB controller registers and
+ prepares the core device mode or host mode operation
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_core_init (usb_core_handle_struct *pudev)
+{
+ /* soft reset the core */
+ usb_core_reset(pudev);
+
+ /* active the transceiver and enable vbus sensing */
+ USB_GCCFG |= GCCFG_PWRON | GCCFG_VBUSACEN | GCCFG_VBUSBCEN;
+
+ /* set Tx FIFO empty level to half empty mode */
+ USB_GAHBCS &= ~GAHBCS_TXFTH | TXFIFO_EMPTY_HALF;
+
+#ifndef VBUS_SENSING_ENABLED
+ USB_GCCFG |= GCCFG_VBUSIG;
+#endif /* VBUS_SENSING_ENABLED */
+
+ if(pudev->cfg.sof_output){
+ USB_GCCFG |= GCCFG_SOFOEN;
+ }
+
+ if (NULL != pudev->mdelay) {
+ pudev->mdelay(20U);
+ }
+
+
+#ifdef USE_OTG_MODE
+ /* enable OTG features */
+ USB_GUSBCS |= GUSBCS_HNPCAP | GUSBCS_SRPCAP;
+ USB_OTG_EnableCommonInt(pudev);
+
+#endif /* USE_OTG_MODE */
+
+ return USB_OK;
+}
+
+/*!
+ \brief flush a Tx FIFO or all Tx FIFOs
+ \param[in] pudev: pointer to usb device
+ \param[in] fifo_num: FIFO number which is in (0..3)
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_txfifo_flush (usb_core_handle_struct *pudev, uint8_t fifo_num)
+{
+ uint32_t count = 0U;
+
+ USB_GRSTCTL &= ~GRSTCTL_TXFNUM;
+ USB_GRSTCTL = ((uint32_t)fifo_num << 6U) | GRSTCTL_TXFF;
+
+ /* wait for Tx FIFO flush bit is set */
+ do {
+ if (++count > 200000U) {
+ break;
+ }
+ } while (USB_GRSTCTL & GRSTCTL_TXFF);
+
+ /* wait for 3 PHY clocks */
+ if (NULL != pudev->udelay) {
+ pudev->udelay(3U);
+ }
+
+ return USB_OK;
+}
+
+/*!
+ \brief flush the entire Rx FIFO
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_rxfifo_flush (usb_core_handle_struct *pudev)
+{
+ uint32_t count = 0U;
+
+ USB_GRSTCTL = GRSTCTL_RXFF;
+
+ /* wait for Rx FIFO flush bit is set */
+ do {
+ if (++count > 200000U) {
+ break;
+ }
+ } while (USB_GRSTCTL & GRSTCTL_RXFF);
+
+ /* wait for 3 PHY clocks */
+ if (NULL != pudev->udelay) {
+ pudev->udelay(3U);
+ }
+
+ return USB_OK;
+}
+
+/*!
+ \brief set operation mode (host or device)
+ \param[in] pudev: pointer to usb device
+ \param[in] mode: operation mode which need to set
+ \arg HOST_MODE
+ \arg DEVICE_MODE
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_mode_set (usb_core_handle_struct *pudev, uint8_t mode)
+{
+ if (HOST_MODE == mode) {
+ USB_GUSBCS &= ~GUSBCS_FDM;
+ USB_GUSBCS |= GUSBCS_FHM;
+ } else if (DEVICE_MODE == mode) {
+ USB_GUSBCS &= ~GUSBCS_FHM;
+ USB_GUSBCS |= GUSBCS_FDM;
+ } else {
+ /* no operation */
+ }
+
+ if (NULL != pudev->mdelay) {
+ pudev->mdelay(50U);
+ }
+
+ return USB_OK;
+}
+
+#ifdef USE_HOST_MODE
+
+/*!
+ \brief initializes USB core for host mode
+ \param[in] pudev: pointer to selected usb host
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_hostcore_init (usb_core_handle_struct *pudev)
+{
+ uint32_t i = 0U;
+ __IO uint32_t nptxfifolen = 0U;
+ __IO uint32_t ptxfifolen = 0U;
+
+#ifdef USE_OTG_MODE
+ __IO uint32_t otgctl = 0;
+#endif /* USE_OTG_MODE */
+
+ /* restart the PHY clock */
+ USB_PWRCLKCTL = 0U;
+
+ /* initialize host configuration register */
+ if (USB_CORE_ULPI_PHY == pudev->cfg.phy_interface) {
+ USB_FSLSCLOCK_INIT(HCTLR_30_60_MHZ);
+ } else {
+ USB_FSLSCLOCK_INIT(HCTLR_48_MHZ);
+ }
+
+ /* configure data FIFO sizes */
+ if (USB_FS_CORE_ID == pudev->cfg.core_id) {
+ /* set Rx FIFO size */
+ USB_GRFLEN = USBFS_RX_FIFO_SIZE;
+
+ /* set non-periodic Tx FIFO size and address */
+ nptxfifolen &= ~HNPTFLEN_HNPTXRSAR;
+ nptxfifolen |= USBFS_RX_FIFO_SIZE;
+ nptxfifolen &= ~HNPTFLEN_HNPTXFD;
+ nptxfifolen |= USBFS_HTX_NPFIFO_SIZE << 16;
+ USB_HNPTFLEN = nptxfifolen;
+
+ /* set periodic Tx FIFO size and address */
+ ptxfifolen &= ~HPTFLEN_HPTXFSAR;
+ ptxfifolen |= USBFS_RX_FIFO_SIZE + USBFS_HTX_PFIFO_SIZE;
+ ptxfifolen &= ~HPTFLEN_HPTXFD;
+ ptxfifolen |= USBFS_HTX_PFIFO_SIZE << 16;
+ USB_HPTFLEN = ptxfifolen;
+ }
+
+#ifdef USE_OTG_MODE
+
+ /* clear Host Set HNP Enable bit in the USB OTG Control Register */
+ otgctl |= GOTGCS_HHNPEN;
+ USB_GOTGCS &= ~otgctl;
+ USB_GOTGCS |= 0;
+
+#endif /* USE_OTG_MODE */
+
+ /* make sure the FIFOs are flushed */
+
+ /* flush all Tx FIFOs in device or host mode */
+ usb_txfifo_flush(pudev, 0x10U);
+
+ /* flush the entire Rx FIFO */
+ usb_rxfifo_flush(pudev);
+
+ /* clear all pending host channel interrupts */
+ USB_HACHINTEN &= ~HACHINTEN_CINTEN;
+
+ for (i = 0U; i < pudev->cfg.host_channel_num; i++) {
+ USB_HCHxINTEN(i) = 0U;
+ USB_HCHxINTF(i) = 0xFFFFFFFFU;
+ }
+
+#ifndef USE_OTG_MODE
+ usb_vbus_drive(pudev, 1U);
+#endif /* USE_OTG_MODE */
+
+ usb_hostint_enable(pudev);
+
+ return USB_OK;
+}
+
+/*!
+ \brief control the VBUS to power
+ \param[in] pudev: pointer to selected usb host
+ \param[in] state: VBUS state
+ \param[out] none
+ \retval none
+*/
+void usb_vbus_drive (usb_core_handle_struct *pudev, uint8_t state)
+{
+ __IO uint32_t host_port = 0U;
+
+ /* enable or disable the external charge pump */
+ if ((void *)0 != pudev->host.vbus_drive) {
+ pudev->host.vbus_drive(pudev, state);
+ }
+
+ /* turn on the host port power. */
+ host_port = USB_PORT_READ();
+
+ if ((0U == (host_port & HPCS_PP)) && (1U == state)) {
+ host_port |= HPCS_PP;
+ } else if ((1U == (host_port & HPCS_PP)) && (0U == state)) {
+ host_port &= ~HPCS_PP;
+ } else {
+ /* no operation */
+ }
+
+ USB_HPCS = host_port;
+
+ if (NULL != pudev->mdelay) {
+ pudev->mdelay(200U);
+ }
+}
+
+/*!
+ \brief enables the host mode interrupts
+ \param[in] pudev: pointer to selected usb host
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_hostint_enable (usb_core_handle_struct *pudev)
+{
+ uint32_t gintf = 0U;
+
+ /* disable all interrupts */
+ USB_GINTEN = 0U;
+
+ /* clear any pending interrupts */
+ USB_GINTF = 0xFFFFFFFFU;
+
+ /* enable the common interrupts */
+ usb_commonint_enable(pudev);
+
+ gintf |= GINTF_RXFNEIF;
+
+ /* enable host_mode-related interrupts */
+ gintf |= GINTF_HPIF | GINTF_HCIF | GINTF_DISCIF | GINTF_SOF | GINTF_ISOONCIF;
+
+ USB_GINTEN &= ~gintf;
+ USB_GINTEN |= gintf;
+
+ return USB_OK;
+}
+
+/*!
+ \brief reset host port
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval operation status
+*/
+uint32_t usb_port_reset (usb_core_handle_struct *pudev)
+{
+ USB_HPCS = USB_PORT_READ() | HPCS_PRST;
+
+ if (NULL != pudev->mdelay) {
+ pudev->mdelay(100U);
+ }
+
+ USB_HPCS &= ~HPCS_PRST;
+
+ if (NULL != pudev->mdelay) {
+ pudev->mdelay(20U);
+ }
+
+ return USB_OK;
+}
+
+/*!
+ \brief initialize host channel
+ \param[in] pudev: pointer to usb device
+ \param[in] hc_num: host channel number which is in (0..7)
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_hostchannel_init(usb_core_handle_struct *pudev, uint8_t hc_num)
+{
+ uint8_t is_low_speed = 0U;
+ __IO uint32_t chinten = 0U;
+ __IO uint32_t chctl = 0U;
+
+ usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num];
+
+ /* clear old interrupt conditions for this host channel */
+ USB_HCHxINTF((uint16_t)hc_num) = 0xFFFFFFFFU;
+
+ /* enable channel interrupts required for this transfer */
+ switch (puhc->endp_type) {
+ case USB_EPTYPE_CTRL:
+ case USB_EPTYPE_BULK:
+ chinten |= HCHINTEN_TFIE | HCHINTEN_STALLIE | HCHINTEN_USBERIE \
+ | HCHINTEN_DTERIE | HCHINTEN_NAKIE;
+
+ if (puhc->endp_in) {
+ chinten |= HCHINTEN_BBERIE;
+ } else {
+ chinten |= HCHINTEN_NYETIE;
+ }
+ break;
+
+ case USB_EPTYPE_INTR:
+ chinten |= HCHINTEN_TFIE | HCHINTEN_STALLIE | HCHINTEN_USBERIE | HCHINTEN_DTERIE \
+ | HCHINTEN_NAKIE | HCHINTEN_REQOVRIE;
+
+ if (puhc->endp_in) {
+ chinten |= HCHINTEN_BBERIE;
+ }
+ break;
+
+ case USB_EPTYPE_ISOC:
+ chinten |= HCHINTEN_TFIE | HCHINTEN_REQOVRIE | HCHINTEN_ACKIE;
+
+ if (puhc->endp_in) {
+ chinten |= HCHINTEN_USBERIE | HCHINTEN_BBERIE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ USB_HCHxINTEN((uint16_t)hc_num) = chinten;
+
+ /* enable the top level host channel interrupt */
+ USB_HACHINTEN |= 1U << hc_num;
+
+ /* make sure host channel interrupts are enabled */
+ USB_GINTEN |= GINTEN_HCIE;
+
+ /* program the hcctlr register */
+ chctl = 0U;
+
+ if (HPRT_PRTSPD_LOW_SPEED == puhc->dev_speed) {
+ is_low_speed = 1U;
+ }
+
+ chctl |= (uint32_t)puhc->dev_addr << 22U;
+ chctl |= (uint32_t)puhc->endp_type << 18U;
+ chctl |= (uint32_t)puhc->endp_id << 11U;
+ chctl |= (uint32_t)puhc->endp_in << 15U;
+ chctl |= (uint32_t)is_low_speed << 17U;
+ chctl |= puhc->endp_mps;
+
+ if (HCCHAR_INTR == puhc->endp_type) {
+ chctl |= HCHCTL_ODDFRM;
+ }
+
+ USB_HCHxCTL((uint16_t)hc_num) = chctl;
+
+ return USB_OK;
+}
+
+/*!
+ \brief prepare host channel for transferring packets
+ \param[in] pudev: pointer to usb device
+ \param[in] hc_num: host channel number which is in (0..7)
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_hostchannel_startxfer(usb_core_handle_struct *pudev, uint8_t hc_num)
+{
+ uint16_t dword_len = 0U;
+ uint16_t packet_num = 0U;
+
+ __IO uint32_t chxlen = 0U;
+ __IO uint32_t chctl = 0U;
+
+ usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num];
+
+ /* compute the expected number of packets associated to the transfer */
+ if (puhc->xfer_len > 0U) {
+ packet_num = ((uint16_t)puhc->xfer_len + puhc->endp_mps - 1U) / puhc->endp_mps;
+
+ if (packet_num > HC_MAX_PACKET_COUNT) {
+ packet_num = HC_MAX_PACKET_COUNT;
+ puhc->xfer_len = (uint32_t)(packet_num) * (uint32_t)(puhc->endp_mps);
+ }
+ } else {
+ packet_num = 1U;
+ }
+
+ if (puhc->endp_in) {
+ puhc->xfer_len = (uint32_t)(packet_num) * (uint32_t)(puhc->endp_mps);
+ }
+
+ /* initialize the host channel length register */
+ chxlen &= ~HCHLEN_TLEN;
+ chxlen |= puhc->xfer_len;
+ chxlen &= ~HCHLEN_PCNT;
+ chxlen |= (uint32_t)packet_num << 19;
+ chxlen &= ~HCHLEN_DPID;
+ chxlen |= (uint32_t)(puhc->DPID) << 29;
+ USB_HCHxLEN((uint16_t)hc_num) = (uint32_t)chxlen;
+
+ /* set host channel enable */
+ chctl = USB_HCHxCTL((uint16_t)hc_num);
+
+ if (1 == USB_EVEN_FRAME()) {
+ chctl |= HCHCTL_ODDFRM;
+ } else {
+ chctl &= ~HCHCTL_ODDFRM;
+ }
+
+ chctl |= HCHCTL_CEN;
+ chctl &= ~HCHCTL_CDIS;
+ USB_HCHxCTL((uint16_t)hc_num) = chctl;
+
+ if ((0U == puhc->endp_in) && (puhc->xfer_len > 0U)) {
+ dword_len = (uint16_t)(puhc->xfer_len + 3U) / 4U;
+
+ switch (puhc->endp_type) {
+ /* non-periodic transfer */
+ case USB_EPTYPE_CTRL:
+ case USB_EPTYPE_BULK:
+ /* check if there is enough space in fifo space */
+ if (dword_len > (USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS)) {
+ /* need to process data in non-periodic transfer fifo empty interrupt */
+ USB_GINTEN |= GINTEN_NPTXFEIE;
+ }
+ break;
+
+ /* periodic transfer */
+ case USB_EPTYPE_INTR:
+ case USB_EPTYPE_ISOC:
+ /* check if there is enough space in FIFO space */
+ if (dword_len > (USB_HPTFQSTAT & HPTFQSTAT_PTXFS)) {
+ /* need to process data in periodic transfer fifo empty interrupt */
+ USB_GINTEN |= GINTEN_PTXFEIE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* write packet into the Tx FIFO. */
+ usb_fifo_write(puhc->xfer_buff, hc_num, (uint16_t)puhc->xfer_len);
+ }
+
+ return USB_OK;
+}
+
+/*!
+ \brief halt channel
+ \param[in] pudev: pointer to usb device
+ \param[in] hc_num: host channel number which is in (0..7)
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_hostchannel_halt(usb_core_handle_struct *pudev, uint8_t hc_num)
+{
+ uint8_t endp_type = 0U;
+ __IO uint32_t chctl = USB_HCHxCTL((uint16_t)hc_num);
+
+ chctl |= HCHCTL_CEN | HCHCTL_CDIS;
+
+ endp_type = (uint8_t)((chctl & HCHCTL_EPTYPE) >> 18U);
+
+ /* check for space in the request queue to issue the halt. */
+ if ((HCCHAR_CTRL == endp_type) || (HCCHAR_BULK == endp_type)) {
+ if (0U == (USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS)) {
+ chctl &= ~HCHCTL_CEN;
+ }
+ } else {
+ if (0U == (USB_HPTFQSTAT & HPTFQSTAT_PTXFS)) {
+ chctl &= ~HCHCTL_CEN;
+ }
+ }
+
+ USB_HCHxCTL((uint16_t)hc_num) = chctl;
+
+ return USB_OK;
+}
+
+/*!
+ \brief stop the USB host and clean up fifos
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void usb_host_stop(usb_core_handle_struct *pudev)
+{
+ uint32_t i;
+
+ /* disable all host channel interrupt */
+ USB_HACHINTEN = 0U;
+ USB_HACHINT = 0xFFFFFFFFU;
+
+ /* flush out any leftover queued requests */
+ for (i = 0U; i < pudev->cfg.host_channel_num; i++) {
+ USB_HCHxCTL(i) |= HCHCTL_CEN | HCHCTL_CDIS | HCHCTL_EPDIR;
+ }
+
+ /* flush the FIFO */
+ usb_rxfifo_flush(pudev);
+ usb_txfifo_flush(pudev, 0x10U);
+}
+
+#endif /* USE_HOST_MODE */
+
+
+#ifdef USE_DEVICE_MODE
+
+/* USB endpoint Tx FIFO size */
+static uint16_t USBFS_TX_FIFO_SIZE[USBFS_MAX_DEV_EPCOUNT] =
+{
+ (uint16_t)TX0_FIFO_FS_SIZE,
+ (uint16_t)TX1_FIFO_FS_SIZE,
+ (uint16_t)TX2_FIFO_FS_SIZE,
+ (uint16_t)TX3_FIFO_FS_SIZE
+};
+
+static usb_status_enum usb_devint_enable(usb_core_handle_struct *pudev);
+
+/*!
+ \brief initialize USB core registers for device mode
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval operation status
+*/
+usb_status_enum usb_devcore_init (usb_core_handle_struct *pudev)
+{
+ uint32_t i, ram_address = 0U;
+ __IO uint32_t devinep0intf = USB_DIEP0TFLEN;
+ __IO uint32_t devinepintf = 0U;
+
+ /* restart the Phy Clock (Maybe don't need to...) */
+ USB_PWRCLKCTL = 0U;
+
+ /* config periodic frmae interval to default */
+ USB_DCFG &= ~DCFG_EOPFT;
+ USB_DCFG |= FRAME_INTERVAL_80;
+
+ if (USB_FS_CORE_ID == pudev->cfg.core_id) {
+ /* set full speed PHY */
+ USB_DCFG &= ~DCFG_DS;
+ USB_DCFG |= USB_SPEED_INP_FULL;
+
+ /* set Rx FIFO size */
+ USB_GRFLEN &= ~GRFLEN_RXFD;
+ USB_GRFLEN |= (uint32_t)RX_FIFO_FS_SIZE;
+
+ /* set endpoint 0 Tx FIFO length and RAM address */
+ devinep0intf &= ~DIEP0TFLEN_IEP0TXFD;
+ devinep0intf |= (uint32_t)TX0_FIFO_FS_SIZE << 16;
+ devinep0intf &= ~DIEP0TFLEN_IEP0TXRSAR;
+ devinep0intf |= (uint32_t)RX_FIFO_FS_SIZE;
+
+ USB_DIEP0TFLEN = devinep0intf;
+
+ ram_address = (uint32_t)RX_FIFO_FS_SIZE;
+
+ /* set endpoint 1 to 3's Tx FIFO length and RAM address */
+ for (i = 1U; i < USBFS_MAX_DEV_EPCOUNT; i++) {
+ ram_address += USBFS_TX_FIFO_SIZE[i - 1U];
+
+ devinepintf &= ~DIEPTFLEN_IEPTXFD;
+ devinepintf |= (uint32_t)USBFS_TX_FIFO_SIZE[i] << 16U;
+ devinepintf &= ~DIEPTFLEN_IEPTXRSAR;
+ devinepintf |= ram_address;
+
+ USB_DIEPxTFLEN(i) = devinepintf;
+ }
+ }
+
+ /* make sure all FIFOs are flushed */
+
+ /* flush all Tx FIFOs */
+ usb_txfifo_flush(pudev, 0x10U);
+
+ /* flush entire Rx FIFO */
+ usb_rxfifo_flush(pudev);
+
+ /* clear all pending device interrupts */
+ USB_DIEPINTEN = 0U;
+ USB_DOEPINTEN = 0U;
+ USB_DAEPINT = 0xFFFFFFFFU;
+ USB_DAEPINTEN = 0U;
+
+ /* configure all IN/OUT endpoints */
+ for (i = 0U; i < pudev->cfg.dev_endp_num; i++) {
+ if (USB_DIEPxCTL(i) & DEPCTL_EPEN) {
+ USB_DIEPxCTL(i) |= DEPCTL_EPD | DEPCTL_SNAK;
+ } else {
+ USB_DIEPxCTL(i) = 0U;
+ }
+
+ if (USB_DOEPxCTL(i) & DEPCTL_EPEN) {
+ USB_DOEPxCTL(i) |= DEPCTL_EPD | DEPCTL_SNAK;
+ } else {
+ USB_DOEPxCTL(i) = 0U;
+ }
+
+ /* set IN/OUT endpoint transfer length to 0 */
+ USB_DIEPxLEN(i) = 0U;
+ USB_DOEPxLEN(i) = 0U;
+
+ /* clear all pending IN/OUT endpoints interrupts */
+ USB_DIEPxINTF(i) = 0xFFU;
+ USB_DOEPxINTF(i) = 0xFFU;
+ }
+
+ usb_devint_enable(pudev);
+
+ return USB_OK;
+}
+
+/*!
+ \brief enable the device mode interrupts
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval status
+*/
+static usb_status_enum usb_devint_enable(usb_core_handle_struct *pudev)
+{
+ uint32_t int_mask = 0U;
+
+ /* disable all interrupts */
+ USB_GINTEN = 0U;
+
+ /* clear any pending interrupts */
+ USB_GINTF = 0xBFFFFFFFU;
+
+ /* enable the common interrupts */
+ usb_commonint_enable(pudev);
+
+ int_mask = GINTEN_RXFNEIE;
+
+ /* enable device_mode-related interrupts */
+ int_mask |= GINTEN_SPIE | GINTEN_RSTIE | GINTEN_ENUMFIE \
+ | GINTEN_IEPIE | GINTEN_OEPIE | GINTEN_SOFIE | GINTEN_ISOONCIE \
+ | GINTEN_ISOINCIE;
+
+#ifdef VBUS_SENSING_ENABLED
+ int_mask |= GINTEN_SESIE | GINTEN_OTGIE;
+#endif /* VBUS_SENSING_ENABLED */
+
+ USB_GINTEN &= ~int_mask;
+ USB_GINTEN |= int_mask;
+
+ return USB_OK;
+}
+
+/*!
+ \brief configures endpoint 0 to receive SETUP packets
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval none
+*/
+void usb_ep0_startout(usb_core_handle_struct *pudev)
+{
+ __IO uint32_t ep0len = 0U;
+
+ /* set OUT endpoint 0 receive length to 24 bytes */
+ ep0len &= ~DOEP0LEN_TLEN;
+ ep0len |= 8U * 3U;
+
+ /* set OUT endpoint 0 receive length to 1 packet */
+ ep0len &= ~DOEP0LEN_PCNT;
+ ep0len |= 1U << 19;
+
+ /* set SETUP packet count to 3 */
+ ep0len &= ~DOEP0LEN_STPCNT;
+ ep0len |= 3U << 29;
+
+ USB_DOEPxLEN(0U) = ep0len;
+}
+
+/*!
+ \brief active remote wakeup signalling
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval none
+*/
+void usb_remotewakeup_active(usb_core_handle_struct *pudev)
+{
+ __IO uint32_t power_clock;
+
+ if (pudev->dev.remote_wakeup) {
+ if (1U == (USB_DSTAT & DSTAT_SPST)) {
+ if (pudev->cfg.low_power) {
+ /* ungate USB core clock */
+ power_clock = USB_PWRCLKCTL;
+ power_clock &= ~PWRCLKCTL_SHCLK;
+ power_clock &= ~PWRCLKCTL_SUCLK;
+
+ USB_PWRCLKCTL = power_clock;
+ }
+
+ /* active remote wakeup signaling */
+ USB_DCTL |= DCTL_RWKUP;
+
+ if (pudev->mdelay != (void *)0) {
+ pudev->mdelay(5U);
+ }
+
+ USB_DCTL &= ~DCTL_RWKUP;
+ }
+ }
+}
+
+/*!
+ \brief active USB core clock
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval none
+*/
+void usb_clock_ungate(usb_core_handle_struct *pudev)
+{
+ if (pudev->cfg.low_power) {
+ __IO uint32_t power_clock;
+
+ if (1U == (USB_DSTAT & DSTAT_SPST)) {
+ /* un-gate USB core clock */
+ power_clock = USB_PWRCLKCTL;
+ power_clock &= ~PWRCLKCTL_SHCLK;
+ power_clock &= ~PWRCLKCTL_SUCLK;
+
+ USB_PWRCLKCTL = power_clock;
+ }
+ }
+}
+
+/*!
+ \brief stop the device and clean up fifos
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval none
+*/
+void usb_device_stop (usb_core_handle_struct *pudev)
+{
+ uint32_t i;
+
+ pudev->dev.status = 1U;
+
+ for (i = 0U; i < pudev->cfg.dev_endp_num; i++) {
+ USB_DIEPxINTF(i) = 0xFFU;
+ USB_DOEPxINTF(i) = 0xFFU;
+ }
+
+ USB_DIEPINTEN = 0U;
+ USB_DOEPINTEN = 0U;
+ USB_DAEPINTEN = 0U;
+ USB_DAEPINT = 0xFFFFFFFFU;
+
+ /* flush the FIFO */
+ usb_rxfifo_flush(pudev);
+ usb_txfifo_flush(pudev, 0x10U);
+}
+#endif /* USE_DEVICE_MODE */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbd_core.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbd_core.c
new file mode 100644
index 0000000000000000000000000000000000000000..0bf5841e15c62fc93aeaa4e974d36fb6a20a0886
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbd_core.c
@@ -0,0 +1,500 @@
+/*!
+ \file usbd_core.c
+ \brief USB device mode core driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "usbd_core.h"
+#include "usbd_std.h"
+
+/*!
+ \brief initailizes the USB device-mode handler stack
+ \param[in] pudev: pointer to usb device instance
+ \param[in] core_id: USB core ID
+ \param[out] none
+ \retval none
+*/
+void usbd_init (usb_core_handle_struct *pudev, usb_core_id_enum core_id)
+{
+ /* select USB core */
+ usb_core_select (pudev, core_id);
+
+ pudev->dev.status = USB_STATUS_DEFAULT;
+
+ /* disable USB global interrupt */
+ USB_GLOBAL_INT_DISABLE();
+
+ /* init the core (common init.) */
+ usb_core_init(pudev);
+
+ /* force device mode*/
+ usb_mode_set(pudev, DEVICE_MODE);
+
+ /* set device disconnect */
+ USB_SOFT_DISCONNECT_ENABLE();
+
+ if ((void *)0 != pudev->mdelay) {
+ pudev->mdelay(3U);
+ }
+
+ /* init device */
+ usb_devcore_init(pudev);
+
+ /* set device Connect */
+ USB_SOFT_DISCONNECT_DISABLE();
+
+ if ((void *)0 != pudev->mdelay) {
+ pudev->mdelay(3U);
+ }
+
+ /* enable USB global interrupt */
+ USB_GLOBAL_INT_ENABLE();
+}
+
+/*!
+ \brief endpoint initialization
+ \param[in] pudev: pointer to usb device instance
+ \param[in] ep_desc: pointer to usb endpoint descriptor
+ \param[out] none
+ \retval none
+*/
+void usbd_ep_init (usb_core_handle_struct *pudev, const usb_descriptor_endpoint_struct *ep_desc)
+{
+ usb_ep_struct *ep;
+ usb_dir_enum ep_dir;
+
+ uint32_t devepinten = 0U;
+ uint32_t devepctl = 0U;
+
+ uint8_t ep_num = ep_desc->bEndpointAddress & 0x7FU;
+ uint8_t ep_type = ep_desc->bmAttributes & USB_EPTYPE_MASK;
+ uint16_t ep_mps = ep_desc->wMaxPacketSize;
+
+ if (ep_desc->bEndpointAddress >> 7) {
+ ep = &pudev->dev.in_ep[ep_num];
+
+ devepinten |= 1U << ep_num;
+ devepctl = USB_DIEPxCTL((uint16_t)ep_num);
+
+ ep_dir = USB_TX;
+ } else {
+ ep = &pudev->dev.out_ep[ep_num];
+
+ devepinten |= (1U << ep_num) << 16;
+ devepctl = USB_DOEPxCTL((uint16_t)ep_num);
+
+ ep_dir = USB_RX;
+ }
+
+ /* if the endpoint is not active, need change the endpoint control register */
+ if (!(devepctl & DEPCTL_EPACT)) {
+ devepctl &= ~DEPCTL_MPL;
+ devepctl |= ep_mps;
+
+ devepctl &= ~DEPCTL_EPTYPE;
+ devepctl |= (uint32_t)ep_type << 18;
+
+ if (USB_TX == ep_dir) {
+ devepctl &= ~DIEPCTL_TXFNUM;
+ devepctl |= (uint32_t)ep_num << 22;
+ }
+
+ devepctl |= DEPCTL_SD0PID;
+ devepctl |= DEPCTL_EPACT;
+ }
+
+ if (USB_TX == ep_dir) {
+ USB_DIEPxCTL((uint16_t)ep_num) = devepctl;
+ } else if (USB_RX == ep_dir) {
+ USB_DOEPxCTL((uint16_t)ep_num) = devepctl;
+ } else {
+ /* no operation */
+ }
+
+ ep->endp_mps = ep_mps;
+ ep->endp_type = ep_type;
+
+ /* enable the interrupts for this endpoint */
+ USB_DAEPINTEN |= devepinten;
+}
+
+/*!
+ \brief endpoint deinitialize
+ \param[in] pudev: pointer to usb device instance
+ \param[in] ep_addr: endpoint address
+ \param[out] none
+ \retval none
+*/
+void usbd_ep_deinit (usb_core_handle_struct *pudev, uint8_t ep_addr)
+{
+ uint32_t devepinten = 0U;
+ uint8_t ep_num = ep_addr & 0x7FU;
+
+ if (ep_addr >> 7) {
+ devepinten |= 1U << ep_num;
+
+ USB_DIEPxCTL((uint16_t)ep_num) &= ~DEPCTL_EPACT;
+ } else {
+ devepinten |= (1U << ep_num) << 16U;
+
+ USB_DOEPxCTL((uint16_t)ep_num) &= ~DEPCTL_EPACT;
+ }
+
+ /* disable the interrupts for this endpoint */
+ USB_DAEPINTEN &= ~devepinten;
+}
+
+/*!
+ \brief endpoint prepare to receive data
+ \param[in] pudev: pointer to usb device instance
+ \param[in] ep_addr: endpoint address
+ \param[in] pbuf: pointer to buffer
+ \param[in] buf_len: buffer length
+ \param[out] none
+ \retval none
+*/
+void usbd_ep_rx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len)
+{
+ usb_ep_struct *ep;
+ uint8_t ep_num = ep_addr & 0x7FU;
+ uint32_t devepctl = 0U, devepxlen = 0U;
+
+ ep = &pudev->dev.out_ep[ep_num];
+
+ /* setup and start the Xfer */
+ ep->xfer_buff = pbuf;
+ ep->xfer_len = buf_len;
+ ep->xfer_count = 0U;
+
+ devepctl = USB_DOEPxCTL((uint16_t)ep_num);
+ devepxlen = USB_DOEPxLEN((uint16_t)ep_num);
+
+ devepxlen &= ~DEPLEN_TLEN;
+ devepxlen &= ~DEPLEN_PCNT;
+
+ /* zero length packet */
+ if (0U == ep->xfer_len) {
+ /* set the transfer length to max packet size */
+ devepxlen |= ep->endp_mps;
+
+ /* set the transfer packet count to 1 */
+ devepxlen |= 1U << 19U;
+ } else {
+
+ if (0U == ep_num) {
+ /* set the transfer length to max packet size */
+ devepxlen |= ep->endp_mps;
+
+ /* set the transfer packet count to 1 */
+ devepxlen |= 1U << 19U;
+ } else {
+ /* configure the transfer size and packet count as follows:
+ * pktcnt = N
+ * xfersize = N * maxpacket
+ */
+ devepxlen |= ((ep->xfer_len + ep->endp_mps - 1U) / ep->endp_mps) << 19U;
+ devepxlen |= ((devepxlen & DEPLEN_PCNT) >> 19U) * ep->endp_mps;
+ }
+ }
+
+ USB_DOEPxLEN((uint16_t)ep_num) = devepxlen;
+
+ if (USB_EPTYPE_ISOC == ep->endp_type) {
+ if (ep->endp_frame) {
+ devepctl |= DEPCTL_SODDFRM;
+ } else {
+ devepctl |= DEPCTL_SEVNFRM;
+ }
+ }
+
+ /* enable the endpoint and clear the NAK */
+ devepctl |= DEPCTL_EPEN | DEPCTL_CNAK;
+
+ USB_DOEPxCTL((uint16_t)ep_num) = devepctl;
+}
+
+/*!
+ \brief endpoint prepare to transmit data
+ \param[in] pudev: pointer to usb device instance
+ \param[in] ep_addr: endpoint address
+ \param[in] pbuf: pointer to buffer
+ \param[in] len: buffer length
+ \param[out] none
+ \retval none
+*/
+void usbd_ep_tx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
+{
+ usb_ep_struct *ep;
+ uint8_t ep_num = ep_addr & 0x7FU;
+ __IO uint32_t devepctl = 0U;
+ __IO uint32_t deveplen = 0U;
+
+ ep = &pudev->dev.in_ep[ep_num];
+
+ /* setup and start the transfer */
+ ep->xfer_buff = pbuf;
+ ep->xfer_len = buf_len;
+ ep->xfer_count = 0U;
+
+ devepctl = USB_DIEPxCTL((uint16_t)ep_num);
+ deveplen = USB_DIEPxLEN((uint16_t)ep_num);
+
+ /* clear transfer length to 0 */
+ deveplen &= ~DEPLEN_TLEN;
+
+ /* clear transfer packet to 0 */
+ deveplen &= ~DEPLEN_PCNT;
+
+ /* zero length packet */
+ if (0U == ep->xfer_len) {
+ /* set transfer packet count to 1 */
+ deveplen |= 1U << 19U;
+ } else {
+ if (0U == ep_num) {
+ if (ep->xfer_len > ep->endp_mps) {
+ ep->xfer_len = ep->endp_mps;
+ }
+
+ deveplen |= 1U << 19U;
+ } else {
+ deveplen |= ((ep->xfer_len - 1U + ep->endp_mps) / ep->endp_mps) << 19U;
+ }
+
+ /* configure the transfer size and packet count as follows:
+ * xfersize = N * maxpacket + short_packet
+ * pktcnt = N + (short_packet exist ? 1 : 0)
+ */
+ deveplen |= ep->xfer_len;
+
+ if (USB_EPTYPE_ISOC == ep->endp_type) {
+ deveplen |= DIEPLEN_MCNT & (1U << 29U);
+ }
+ }
+
+ USB_DIEPxLEN((uint16_t)ep_num) = deveplen;
+
+ if (USB_EPTYPE_ISOC == ep->endp_type) {
+ if (0U == (((USB_DSTAT & DSTAT_FNRSOF) >> 8U) & 0x1U)) {
+ devepctl |= DEPCTL_SODDFRM;
+ } else {
+ devepctl |= DEPCTL_SEVNFRM;
+ }
+ }
+
+ /* enable the endpoint and clear the NAK */
+ devepctl |= DEPCTL_EPEN | DEPCTL_CNAK;
+
+ USB_DIEPxCTL((uint16_t)ep_num) = devepctl;
+
+ if (USB_EPTYPE_ISOC != ep->endp_type) {
+ /* enable the Tx FIFO empty interrupt for this endpoint */
+ if (ep->xfer_len > 0U) {
+ USB_DIEPFEINTEN |= 1U << ep_num;
+ }
+ } else {
+ usb_fifo_write(ep->xfer_buff, ep_num, (uint16_t)ep->xfer_len);
+ }
+}
+
+/*!
+ \brief transmit data on the control channel
+ \param[in] pudev: pointer to usb device instance
+ \param[in] pbuf: pointer to buffer
+ \param[in] len: buffer length
+ \param[out] none
+ \retval usb device operation status
+*/
+usbd_status_enum usbd_ctltx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len)
+{
+ usbd_status_enum ret = USBD_OK;
+
+ pudev->dev.sum_len = len;
+ pudev->dev.remain_len = len;
+ pudev->dev.ctl_status = USB_CTRL_DATA_IN;
+
+ usbd_ep_tx (pudev, 0U, pbuf, (uint32_t)len);
+
+ return ret;
+}
+
+/*!
+ \brief receive data on the control channel
+ \param[in] pudev: pointer to usb device instance
+ \param[in] pbuf: pointer to buffer
+ \param[in] len: buffer length
+ \param[out] none
+ \retval usb device operation status
+*/
+usbd_status_enum usbd_ctlrx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len)
+{
+ pudev->dev.sum_len = len;
+ pudev->dev.remain_len = len;
+ pudev->dev.ctl_status = USB_CTRL_DATA_OUT;
+
+ usbd_ep_rx (pudev, 0U, pbuf, len);
+
+ return USBD_OK;
+}
+
+/*!
+ \brief transmit status on the control channel
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval usb device operation status
+*/
+usbd_status_enum usbd_ctlstatus_tx (usb_core_handle_struct *pudev)
+{
+ pudev->dev.ctl_status = USB_CTRL_STATUS_IN;
+
+ usbd_ep_tx (pudev, 0U, NULL, 0U);
+
+ usb_ep0_startout(pudev);
+
+ return USBD_OK;
+}
+
+/*!
+ \brief receive status on the control channel
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval usb device operation status
+*/
+usbd_status_enum usbd_ctlstatus_rx (usb_core_handle_struct *pudev)
+{
+ pudev->dev.ctl_status = USB_CTRL_STATUS_OUT;
+
+ usbd_ep_rx (pudev, 0U, NULL, 0U);
+
+ usb_ep0_startout(pudev);
+
+ return USBD_OK;
+}
+
+/*!
+ \brief set an endpoint to STALL status
+ \param[in] pudev: pointer to usb device instance
+ \param[in] ep_addr: endpoint address
+ \param[out] none
+ \retval none
+*/
+void usbd_ep_stall (usb_core_handle_struct *pudev, uint8_t ep_addr)
+{
+ uint8_t ep_num = ep_addr & 0x7FU;
+ __IO uint32_t devepctl = 0U;
+
+ if (ep_addr >> 7U) {
+ devepctl = USB_DIEPxCTL((uint16_t)ep_num);
+
+ /* set the endpoint disable bit */
+ if (devepctl & DEPCTL_EPEN) {
+ devepctl |= DEPCTL_EPD;
+ }
+
+ /* set the endpoint stall bit */
+ devepctl |= DEPCTL_STALL;
+
+ USB_DIEPxCTL((uint16_t)ep_num) = devepctl;
+ } else {
+ /* set the endpoint stall bit */
+ USB_DOEPxCTL((uint16_t)ep_num) |= DEPCTL_STALL;
+ }
+}
+
+/*!
+ \brief clear endpoint stalled status
+ \param[in] pudev: pointer to usb device instance
+ \param[in] ep_addr: endpoint address
+ \param[out] none
+ \retval none
+*/
+void usbd_ep_clear_stall (usb_core_handle_struct *pudev, uint8_t ep_addr)
+{
+ usb_ep_struct *ep;
+ uint8_t ep_num = ep_addr & 0x7FU;
+ __IO uint32_t devepctl = 0U;
+
+ if(ep_addr >> 7){
+ ep = &pudev->dev.in_ep[ep_num];
+
+ devepctl = USB_DIEPxCTL((uint16_t)ep_num);
+
+ /* clear the IN endpoint stall bits */
+ devepctl &= ~DEPCTL_STALL;
+
+ if ((USB_EPTYPE_INTR == ep->endp_type) || (USB_EPTYPE_BULK == ep->endp_type)) {
+ devepctl |= DEPCTL_SEVNFRM;
+ }
+
+ USB_DIEPxCTL((uint16_t)ep_num) = devepctl;
+ } else {
+ ep = &pudev->dev.out_ep[ep_num];
+
+ devepctl = USB_DOEPxCTL((uint16_t)ep_num);
+
+ /* clear the OUT endpoint stall bits */
+ devepctl &= ~DEPCTL_STALL;
+
+ if ((USB_EPTYPE_INTR == ep->endp_type) || (USB_EPTYPE_BULK == ep->endp_type)) {
+ devepctl |= DEPCTL_SEVNFRM;
+ }
+
+ USB_DOEPxCTL((uint16_t)ep_num) = devepctl;
+ }
+}
+
+/*!
+ \brief flushes the FIFOs
+ \param[in] pudev: pointer to usb device instance
+ \param[in] ep_addr: endpoint address
+ \param[out] none
+ \retval none
+*/
+void usbd_ep_fifo_flush (usb_core_handle_struct *pudev, uint8_t ep_addr)
+{
+ if (ep_addr >> 7) {
+ usb_txfifo_flush(pudev, ep_addr & 0x7FU);
+ } else {
+ usb_rxfifo_flush(pudev);
+ }
+}
+
+/*!
+ \brief get the received data length
+ \param[in] pudev: pointer to usb device instance
+ \param[in] ep_num: endpoint identifier which is in (0..3)
+ \param[out] none
+ \retval received data length
+*/
+uint16_t usbd_rxcount_get (usb_core_handle_struct *pudev, uint8_t ep_num)
+{
+ return (uint16_t)pudev->dev.out_ep[ep_num].xfer_count;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbd_int.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbd_int.c
new file mode 100644
index 0000000000000000000000000000000000000000..970cf812ad9df832741aea82e3422f899169a8c5
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbd_int.c
@@ -0,0 +1,662 @@
+/*!
+ \file usbd_int.c
+ \brief USB device mode interrupt routines
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "usbd_int.h"
+#include "usbd_std.h"
+
+/* interrupt handlers */
+static uint32_t usbd_intf_outep (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_inep (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_earlysuspend (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_suspend (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_resume (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_sof (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_rxfifo (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_reset (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_enumfinish (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_isoinincomplete (usb_core_handle_struct *pudev);
+static uint32_t usbd_intf_isooutincomplete (usb_core_handle_struct *pudev);
+
+static uint32_t usbd_emptytxfifo_write (usb_core_handle_struct *pudev, uint8_t ep_num);
+
+#ifdef VBUS_SENSING_ENABLED
+
+ static uint32_t usbd_intf_otg (usb_core_handle_struct *pudev);
+ static uint32_t usbd_intf_sessionrequest (usb_core_handle_struct *pudev);
+
+#endif /* VBUS_SENSING_ENABLED */
+
+static usb_speed_enum USB_SPEED[4] = {
+ [DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ] = USB_SPEED_HIGH,
+ [DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ] = USB_SPEED_FULL,
+ [DSTAT_ENUMSPD_FS_PHY_48MHZ] = USB_SPEED_FULL,
+ [DSTAT_ENUMSPD_LS_PHY_6MHZ] = USB_SPEED_LOW
+};
+
+static const uint8_t EP0_MAXLEN[4] = {
+ [DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ] = EP0MPL_64,
+ [DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ] = EP0MPL_64,
+ [DSTAT_ENUMSPD_FS_PHY_48MHZ] = EP0MPL_64,
+ [DSTAT_ENUMSPD_LS_PHY_6MHZ] = EP0MPL_8
+};
+
+/*!
+ \brief USB device-mode interrupts global service routine handler
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+uint32_t usbd_isr (usb_core_handle_struct *pudev)
+{
+ uint32_t retval = 0U;
+ uint32_t int_status = 0U, gintf = USB_GINTF, ginten = USB_GINTEN;
+
+ /* ensure the core is in device mode */
+ if (DEVICE_MODE == USB_CURRENT_MODE_GET()) {
+ int_status = gintf & ginten;
+
+ /* there are no interrupts, avoid spurious interrupt */
+ if (!int_status) {
+ return 0U;
+ }
+
+ /* OUT endpoints interrupts */
+ if (int_status & GINTF_OEPIF) {
+ retval |= usbd_intf_outep(pudev);
+ }
+
+ /* IN endpoints interrupts */
+ if (int_status & GINTF_IEPIF) {
+ retval |= usbd_intf_inep(pudev);
+ }
+
+ /* mode mismatch interrupt */
+ if (int_status & GINTF_MFIF) {
+ /* clear interrupt */
+ USB_GINTF = GINTF_MFIF;
+ }
+
+ /* early suspend interrupt */
+ if (int_status & GINTF_ESP) {
+ retval |= usbd_intf_earlysuspend(pudev);
+ }
+
+ /* suspend interrupt */
+ if (int_status & GINTF_SP) {
+ retval |= usbd_intf_suspend(pudev);
+ }
+
+ /* wakeup interrupt */
+ if (int_status & GINTF_WKUPIF) {
+ retval |= usbd_intf_resume(pudev);
+ }
+
+ /* start of frame interrupt */
+ if (int_status & GINTF_SOF) {
+ retval |= usbd_intf_sof(pudev);
+ }
+
+ /* reveive fifo not empty interrupt */
+ if (int_status & GINTF_RXFNEIF) {
+ retval |= usbd_intf_rxfifo(pudev);
+ }
+
+ /* USB reset interrupt */
+ if (int_status & GINTF_RST) {
+ retval |= usbd_intf_reset(pudev);
+ }
+
+ /* enumeration has been finished interrupt */
+ if (int_status & GINTF_ENUMF) {
+ retval |= usbd_intf_enumfinish(pudev);
+ }
+
+ /* incomplete synchronization in transfer interrupt*/
+ if (int_status & GINTF_ISOINCIF) {
+ retval |= usbd_intf_isoinincomplete(pudev);
+ }
+
+ /* incomplete synchronization out transfer interrupt*/
+ if (int_status & GINTF_ISOONCIF) {
+ retval |= usbd_intf_isooutincomplete(pudev);
+ }
+
+#ifdef VBUS_SENSING_ENABLED
+
+ /* session request interrupt */
+ if (int_status & GINTF_SESIF) {
+ retval |= usbd_intf_sessionrequest(pudev);
+ }
+
+ /* OTG mode interrupt */
+ if (int_status & GINTF_OTGIF) {
+ retval |= usbd_intf_otg(pudev);
+ }
+#endif /* VBUS_SENSING_ENABLED */
+ }
+
+ return retval;
+}
+
+/*!
+ \brief indicates that an OUT endpoint has a pending interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbd_intf_outep (usb_core_handle_struct *pudev)
+{
+ uint8_t endp_num = 0U;
+ uint32_t endp_intr = 0U;
+
+ __IO uint32_t out_endp_intr = 0U;
+
+ /* read in the device interrupt bits */
+ USB_DAOEP_INTR_READ(endp_intr);
+
+ while (endp_intr) {
+ if (endp_intr & 0x1U) {
+ USB_DOEP_INTR_READ(out_endp_intr, (uint16_t)endp_num);
+
+ /* transfer complete interrupt */
+ if (out_endp_intr & DOEPINTF_TF) {
+ USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_TF;
+
+ /* data receive is completed */
+ usbd_out_transaction(pudev, endp_num);
+ }
+
+ /* endpoint disable interrupt */
+ if (out_endp_intr & DOEPINTF_EPDIS) {
+ USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_EPDIS;
+ }
+
+ /* setup phase finished interrupt (just for control endpoints) */
+ if (out_endp_intr & DOEPINTF_STPF) {
+ /* setup phase is completed */
+ usbd_setup_transaction(pudev);
+
+ USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_STPF;
+ }
+
+ /* back to back setup packets received */
+ if (out_endp_intr & DOEPINTF_BTBSTP) {
+ USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_BTBSTP;
+ }
+ }
+
+ endp_num ++;
+ endp_intr >>= 1;
+ }
+
+ return 1U;
+}
+
+/*!
+ \brief indicates that an IN endpoint has a pending interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbd_intf_inep(usb_core_handle_struct *pudev)
+{
+ uint8_t endp_num = 0U;
+ uint32_t endp_intr = 0U;
+
+ __IO uint32_t in_endp_intr = 0U;
+
+ /* get all in endpoints which have interrupts */
+ USB_DAIEP_INTR_READ(endp_intr);
+
+ while (endp_intr) {
+ if (endp_intr & 0x1U) {
+ USB_DIEP_INTR_READ(in_endp_intr, (uint16_t)endp_num);
+
+ if (in_endp_intr & DIEPINTF_TF) {
+ /* disable the fifo empty interrupt for the endpoint */
+ USB_DIEPFEINTEN &= ~(0x1U << endp_num);
+
+ USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_TF;
+
+ /* data transmittion is completed */
+ usbd_in_transaction(pudev, endp_num);
+ }
+
+ if (in_endp_intr & DIEPINTF_CITO) {
+ USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_CITO;
+ }
+
+ if (in_endp_intr & DIEPINTF_IEPNE) {
+ USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_IEPNE;
+ }
+
+ if (in_endp_intr & DIEPINTF_EPDIS) {
+ USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_EPDIS;
+ }
+
+ if (in_endp_intr & DIEPINTF_TXFE) {
+ usbd_emptytxfifo_write(pudev, endp_num);
+ USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_TXFE;
+ }
+ }
+
+ endp_num ++;
+ endp_intr >>= 1;
+ }
+
+ return 1U;
+}
+
+/*!
+ \brief indicates that early SUSPEND state has been detected on the USB
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbd_intf_earlysuspend (usb_core_handle_struct *pudev)
+{
+ USB_GINTEN &= ~GINTEN_ESPIE;
+ USB_GINTF = GINTF_ESP;
+
+ return 1U;
+}
+
+/*!
+ \brief indicates that SUSPEND state has been detected on the USB
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbd_intf_suspend(usb_core_handle_struct *pudev)
+{
+ __IO uint8_t low_power = pudev->cfg.low_power;
+ __IO uint8_t suspend = (uint8_t)(USB_DSTAT & DSTAT_SPST);
+ __IO uint8_t is_configured = (pudev->dev.status == USB_STATUS_CONFIGURED)? 1U : 0U;
+
+ pudev->dev.prev_status = pudev->dev.status;
+ pudev->dev.status = USB_STATUS_SUSPENDED;
+
+ if (low_power && suspend && is_configured) {
+ /* switch-off the otg clocks */
+ USB_PWRCLKCTL |= PWRCLKCTL_SUCLK | PWRCLKCTL_SHCLK;
+
+ /* enter DEEP_SLEEP mode with LDO in low power mode */
+ pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD);
+ }
+
+ /* clear interrupt */
+ USB_GINTF = GINTF_SP;
+
+ return 1U;
+}
+
+/*!
+ \brief indicates that the USB controller has detected a resume or remote Wake-up sequence
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbd_intf_resume (usb_core_handle_struct *pudev)
+{
+ pudev->dev.status = pudev->dev.prev_status;
+ pudev->dev.status = USB_STATUS_CONFIGURED;
+
+ /* clear interrupt */
+ USB_GINTF = GINTF_WKUPIF;
+
+ return 1U;
+}
+
+/*!
+ \brief handle the SOF interrupts
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbd_intf_sof(usb_core_handle_struct *pudev)
+{
+ if (NULL != usbd_int_fops) {
+ usbd_int_fops->SOF(pudev);
+ }
+
+ USB_GINTF = GINTF_SOF;
+
+ return 1U;
+}
+
+/*!
+ \brief handle the Rx status queue level interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbd_intf_rxfifo (usb_core_handle_struct *pudev)
+{
+ usb_ep_struct *ep;
+ uint8_t data_pid = 0U, endp_num = 0U;
+ uint32_t bcount = 0U, packet_num = 0U;
+
+ /* get the status from the top of the fifo (must be read to a variable) */
+ __IO uint32_t rx_status = USB_GRSTATP;
+
+ /* disable the rx fifo non-empty interrupt */
+ USB_GINTEN &= ~GINTEN_RXFNEIE;
+
+ endp_num = (uint8_t)(rx_status & GRSTATRP_EPNUM);
+ bcount = (rx_status & GRSTATRP_BCOUNT) >> 4U;
+ data_pid = (uint8_t)((rx_status & GRSTATRP_DPID) >> 15U);
+
+ /* ensure no-DMA mode can work */
+ packet_num = USB_DOEPxLEN((uint16_t)endp_num) & DEPLEN_PCNT;
+ if ((1U == endp_num) && (0U == packet_num)) {
+ uint32_t devepctl = USB_DOEPxCTL((uint16_t)endp_num);
+
+ devepctl |= DEPCTL_SNAK;
+ devepctl &= ~DEPCTL_EPEN;
+ devepctl &= ~DEPCTL_EPD;
+
+ USB_DOEPxCTL((uint16_t)endp_num) = devepctl;
+ }
+
+ ep = &pudev->dev.out_ep[endp_num];
+
+ switch ((rx_status & GRSTATRP_RPCKST) >> 17U) {
+ case RXSTAT_GOUT_NAK:
+ break;
+ case RXSTAT_DATA_UPDT:
+ if (bcount > 0U) {
+ usb_fifo_read(ep->xfer_buff, (uint16_t)bcount);
+ ep->xfer_buff += bcount;
+ ep->xfer_count += bcount;
+ }
+ break;
+ case RXSTAT_XFER_COMP:
+ break;
+ case RXSTAT_SETUP_COMP:
+ break;
+ case RXSTAT_SETUP_UPDT:
+ if ((0U == endp_num) && (8U == bcount) && (DPID_DATA0 == data_pid)) {
+ /* copy the setup packet received in fifo into the setup buffer in ram */
+ usb_fifo_read(pudev->dev.setup_packet, 8U);
+
+ ep->xfer_count += bcount;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* enable the Rx fifo non-empty interrupt */
+ USB_GINTEN |= GINTEN_RXFNEIE;
+
+ return 1U;
+}
+
+/*!
+ \brief handle USB reset interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval status
+*/
+static uint32_t usbd_intf_reset(usb_core_handle_struct *pudev)
+{
+ uint8_t i = 0U;
+ usb_ep_struct *ep;
+
+ /* clear the remote wakeup signaling */
+ USB_DCTL &= ~DCTL_RWKUP;
+
+ /* flush the tx fifo */
+ usb_txfifo_flush(pudev, 0U);
+
+ for (i = 0U; i < pudev->cfg.dev_endp_num; i++) {
+ USB_DIEPxINTF((uint16_t)i) = 0xFFU;
+ USB_DOEPxINTF((uint16_t)i) = 0xFFU;
+ }
+
+ /* clear all pending device endpoint interrupts */
+ USB_DAEPINT = 0xFFFFFFFFU;
+
+ /* enable endpoint 0 interrupts */
+ USB_DAEPINTEN &= ~DAEPINTEN_OEPIE;
+ USB_DAEPINTEN &= ~DAEPINTEN_IEPIE;
+ USB_DAEPINTEN = (1U << 16) | 1U;
+
+ /* enable out endpoint interrupts */
+ USB_DOEPINTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN | DOEPINTEN_EPDISEN;
+
+ /* enable in endpoint interrupts */
+ USB_DIEPINTEN = DIEPINTEN_TFEN | DIEPINTEN_CITOEN | DIEPINTEN_EPDISEN;
+
+ /* reset device address */
+ USB_DCFG &= ~DCFG_DAR;
+ USB_DCFG |= 0U << 4U;
+
+ /* configure endpoint 0 to receive setup packets */
+ usb_ep0_startout(pudev);
+
+ /* clear usb reset interrupt */
+ USB_GINTF = GINTF_RST;
+
+ /* open EP0 IN */
+ ep = &pudev->dev.in_ep[0];
+
+ USB_DIEPxCTL(0U) &= ~DEP0CTL_MPL;
+ USB_DIEPxCTL(0U) &= ~DEPCTL_EPTYPE;
+ USB_DIEPxCTL(0U) &= ~DIEPCTL_TXFNUM;
+
+ if (!(USB_DIEPxCTL(0U) & DEP0CTL_EPACT)) {
+ USB_DIEPxCTL(0U) |= USB_MAX_EP0_SIZE;
+ USB_DIEPxCTL(0U) |= (USB_EPTYPE_CTRL << 18U);
+ USB_DIEPxCTL(0U) |= DEP0CTL_EPACT;
+ }
+
+ ep->endp_mps = USB_MAX_EP0_SIZE;
+ ep->endp_type = USB_EPTYPE_CTRL;
+
+ /* open EP0 OUT */
+ ep = &pudev->dev.out_ep[0];
+
+ USB_DOEPxCTL(0U) &= ~DEP0CTL_MPL;
+ USB_DOEPxCTL(0U) &= ~DEPCTL_EPTYPE;
+
+ if (!(USB_DOEPxCTL(0U) & DEP0CTL_EPACT)) {
+ USB_DOEPxCTL(0U) |= USB_MAX_EP0_SIZE;
+ USB_DOEPxCTL(0U) |= (USB_EPTYPE_CTRL << 18U);
+ USB_DOEPxCTL(0U) |= DEP0CTL_EPACT;
+ }
+
+ ep->endp_mps = USB_MAX_EP0_SIZE;
+ ep->endp_type = USB_EPTYPE_CTRL;
+
+ pudev->dev.status = USB_STATUS_DEFAULT;
+
+ return 1U;
+}
+
+/*!
+ \brief handle enumeration finish interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval status
+*/
+static uint32_t usbd_intf_enumfinish(usb_core_handle_struct *pudev)
+{
+ uint8_t enum_speed = (uint8_t)((USB_DSTAT & DSTAT_ES) >> 1U);
+
+ /* set the max packet size of devie in endpoint based on the enumeration speed */
+ USB_DIEPxCTL(0U) |= EP0_MAXLEN[enum_speed];
+
+ /* clear global IN NAK */
+ USB_DCTL &= ~DCTL_CGINAK;
+ USB_DCTL |= DCTL_CGINAK;
+
+ /* set USB turn-around time based on device speed and PHY interface */
+ if (USB_SPEED_HIGH == USB_SPEED[enum_speed]) {
+ pudev->cfg.core_speed = USB_CORE_SPEED_HIGH;
+ pudev->cfg.max_packet_size = USBHS_MAX_PACKET_SIZE;
+
+ USB_GUSBCS &= ~GUSBCS_UTT;
+ USB_GUSBCS |= 0x09U << 10;
+ } else {
+ pudev->cfg.core_speed = USB_CORE_SPEED_FULL;
+ pudev->cfg.max_packet_size = USBFS_MAX_PACKET_SIZE;
+
+ USB_GUSBCS &= ~GUSBCS_UTT;
+ USB_GUSBCS |= 0x05U << 10;
+ }
+
+ /* clear interrupt */
+ USB_GINTF = GINTF_ENUMF;
+
+ return 1U;
+}
+
+/*!
+ \brief handle the ISO IN incomplete interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval status
+*/
+static uint32_t usbd_intf_isoinincomplete(usb_core_handle_struct *pudev)
+{
+// USBD_DCD_INT_fops->IsoINIncomplete (pudev);
+
+ /* clear interrupt */
+ USB_GINTF = GINTF_ISOINCIF;
+
+ return 1U;
+}
+
+/*!
+ \brief handle the ISO OUT incomplete interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval status
+*/
+static uint32_t usbd_intf_isooutincomplete(usb_core_handle_struct *pudev)
+{
+// USBD_DCD_INT_fops->IsoOUTIncomplete (pudev);
+
+ /* clear interrupt */
+ USB_GINTF = GINTF_ISOONCIF;
+
+ return 1U;
+}
+
+/*!
+ \brief check FIFO for the next packet to be loaded
+ \param[in] pudev: pointer to usb device instance
+ \param[in] ep_id: endpoint identifier which is in (0..3)
+ \param[out] none
+ \retval status
+*/
+static uint32_t usbd_emptytxfifo_write(usb_core_handle_struct *pudev, uint8_t ep_num)
+{
+ uint32_t len = 0U, word_len = 0U, fifo_empty_mask = 0U;
+ usb_ep_struct *ep;
+
+ ep = &pudev->dev.in_ep[ep_num];
+ len = ep->xfer_len - ep->xfer_count;
+
+ if (len > ep->endp_mps) {
+ len = ep->endp_mps;
+ }
+
+ word_len = (len + 3U) / 4U;
+
+ while (((USB_DIEPxTFSTAT((uint16_t)ep_num) & DIEPTFSTAT_IEPTFS) > word_len) &&
+ (ep->xfer_count < ep->xfer_len)) {
+ /* write the FIFO */
+ len = ep->xfer_len - ep->xfer_count;
+
+ if (len > ep->endp_mps) {
+ len = ep->endp_mps;
+ }
+
+ word_len = (len + 3U) / 4U;
+
+ usb_fifo_write (ep->xfer_buff, ep_num, (uint16_t)len);
+
+ ep->xfer_buff += len;
+ ep->xfer_count += len;
+
+ if(ep->xfer_len == ep->xfer_count) {
+ fifo_empty_mask = 0x1U << ep_num;
+ USB_DIEPFEINTEN &= ~fifo_empty_mask;
+ }
+ }
+
+ return 1U;
+}
+
+#ifdef VBUS_SENSING_ENABLED
+
+/*!
+ \brief indicates that the USB_OTG controller has detected a connection
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval status
+*/
+static uint32_t usbd_intf_sessionrequest(usb_core_handle_struct *pudev)
+{
+ pudev->dev.connection_status = 1U;
+
+ /* clear the interrupt bit */
+ USB_GINTF = GINTF_SESIF;
+
+ return 1;
+}
+
+/*!
+ \brief indicates that the USB_OTG controller has detected an OTG event
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval status
+*/
+static uint32_t usbd_intf_otg(usb_core_handle_struct *pudev)
+{
+ if (USB_GOTGINTF & GOTGINTF_SESEND) {
+ pudev->dev.class_deinit(pudev, 0);
+ pudev->dev.connection_status = 0;
+ }
+
+ /* clear OTG interrupt */
+ USB_GOTGINTF |= GOTGINTF_SESEND;
+
+ return 1;
+}
+
+#endif /* VBUS_SENSING_ENABLED */
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbd_std.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbd_std.c
new file mode 100644
index 0000000000000000000000000000000000000000..9bdba6a2c0b305a65297c0b913f08e3c79315a7b
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbd_std.c
@@ -0,0 +1,718 @@
+/*!
+ \file usbd_std.c
+ \brief USB 2.0 standard handler driver
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "usbd_std.h"
+#include "usb_core.h"
+
+static usbd_status_enum usbd_standard_request (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static usbd_status_enum usbd_device_class_request (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static usbd_status_enum usbd_vendor_request (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+
+static void usbd_setup_request_parse(usb_core_handle_struct *pudev, usb_device_req_struct *req);
+
+static void usbd_getdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_setaddress (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_setconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_getconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_getstatus (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_setfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_clrfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_reserved (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_setdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_getinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_setinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+static void usbd_synchframe (usb_core_handle_struct *pudev, usb_device_req_struct *req);
+
+static uint8_t* usbd_device_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen);
+static uint8_t* usbd_configuration_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen);
+static uint8_t* usbd_string_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen);
+
+static void (*StandardDeviceRequest[])(usb_core_handle_struct *pudev, usb_device_req_struct *req) =
+{
+ usbd_getstatus,
+ usbd_clrfeature,
+ usbd_reserved,
+ usbd_setfeature,
+ usbd_reserved,
+ usbd_setaddress,
+ usbd_getdescriptor,
+ usbd_setdescriptor,
+ usbd_getconfig,
+ usbd_setconfig,
+ usbd_getinterface,
+ usbd_setinterface,
+ usbd_synchframe,
+};
+
+/* get standard descriptor handler */
+static uint8_t* (*standard_descriptor_get[])(usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) =
+{
+ usbd_device_descriptor_get,
+ usbd_configuration_descriptor_get,
+ usbd_string_descriptor_get
+};
+
+/*!
+ \brief USB setup stage processing
+ \param[in] pudev: pointer to USB device instance
+ \param[out] none
+ \retval USB device operation status
+*/
+usbd_status_enum usbd_setup_transaction(usb_core_handle_struct *pudev)
+{
+ usb_device_req_struct req;
+
+ usbd_setup_request_parse(pudev, &req);
+
+ switch (req.bmRequestType & USB_REQ_MASK) {
+ /* standard device request */
+ case USB_STANDARD_REQ:
+ usbd_standard_request(pudev, &req);
+ break;
+ /* device class request */
+ case USB_CLASS_REQ:
+ usbd_device_class_request(pudev, &req);
+ break;
+ /* vendor defined request */
+ case USB_VENDOR_REQ:
+ usbd_vendor_request(pudev, &req);
+ break;
+ default:
+ usbd_ep_stall(pudev, req.bmRequestType & 0x80U);
+ break;
+ }
+
+ return USBD_OK;
+}
+
+/*!
+ \brief data out stage processing
+ \param[in] pudev: pointer to USB device instance
+ \param[in] ep_id: endpoint identifier(0..7)
+ \param[out] none
+ \retval USB device operation status
+*/
+usbd_status_enum usbd_out_transaction (usb_core_handle_struct *pudev, uint8_t endp_num)
+{
+ usb_ep_struct *ep;
+
+ if (0U == endp_num) {
+ ep = &pudev->dev.out_ep[0];
+
+ if (USB_CTRL_DATA_OUT == pudev->dev.ctl_status) {
+ if (pudev->dev.remain_len > ep->endp_mps) {
+ pudev->dev.remain_len -= ep->endp_mps;
+
+ usbd_ep_rx (pudev,
+ 0U,
+ ep->xfer_buff,
+ (uint16_t)USB_MIN(pudev->dev.remain_len, ep->endp_mps));
+ } else {
+ if (USB_STATUS_CONFIGURED == pudev->dev.status) {
+ pudev->dev.class_data_handler(pudev, USB_RX, 0U);
+ }
+
+ usbd_ctlstatus_tx(pudev);
+ }
+ }
+ } else if (USB_STATUS_CONFIGURED == pudev->dev.status) {
+ pudev->dev.class_data_handler(pudev, USB_RX, endp_num);
+ } else {
+ /* no operation */
+ }
+
+ return USBD_OK;
+}
+
+/*!
+ \brief data in stage processing
+ \param[in] pudev: pointer to USB device instance
+ \param[in] ep_id: endpoint identifier(0..7)
+ \param[out] none
+ \retval USB device operation status
+*/
+usbd_status_enum usbd_in_transaction (usb_core_handle_struct *pudev, uint8_t endp_num)
+{
+ usb_ep_struct *ep;
+
+ if (0U == endp_num) {
+ ep = &pudev->dev.in_ep[0];
+
+ if (USB_CTRL_DATA_IN == pudev->dev.ctl_status) {
+ if (pudev->dev.remain_len > ep->endp_mps) {
+ pudev->dev.remain_len -= ep->endp_mps;
+
+ usbd_ep_tx (pudev, 0U, ep->xfer_buff, pudev->dev.remain_len);
+
+ usbd_ep_rx (pudev, 0U, NULL, 0U);
+ } else {
+ /* last packet is MPS multiple, so send ZLP packet */
+ if ((pudev->dev.sum_len % ep->endp_mps == 0U) &&
+ (pudev->dev.sum_len >= ep->endp_mps) &&
+ (pudev->dev.sum_len < pudev->dev.ctl_len)) {
+ usbd_ep_tx (pudev, 0U, NULL, 0U);
+ pudev->dev.ctl_len = 0U;
+
+ usbd_ep_rx (pudev, 0U, NULL, 0U);
+ } else {
+ if (USB_STATUS_CONFIGURED == pudev->dev.status) {
+ pudev->dev.class_data_handler(pudev, USB_TX, 0U);
+ }
+
+ usbd_ctlstatus_rx(pudev);
+ }
+ }
+ }
+ } else if (USB_STATUS_CONFIGURED == pudev->dev.status) {
+ pudev->dev.class_data_handler(pudev, USB_TX, endp_num);
+ } else {
+ /* no operation */
+ }
+
+ return USBD_OK;
+}
+
+/*!
+ \brief handle USB standard device request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval USB device operation status
+*/
+static usbd_status_enum usbd_standard_request (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ /* call device request handle function */
+ (*StandardDeviceRequest[req->bRequest])(pudev, req);
+
+ return USBD_OK;
+}
+
+/*!
+ \brief handle USB device class request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device class request
+ \param[out] none
+ \retval USB device operation status
+*/
+static usbd_status_enum usbd_device_class_request (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ usbd_status_enum ret = USBD_OK;
+
+ switch (pudev->dev.status) {
+ case USB_STATUS_CONFIGURED:
+ if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
+ ret = (usbd_status_enum)(pudev->dev.class_req_handler(pudev, req));
+
+ if ((0U == req->wLength) && (USBD_OK == ret)) {
+ /* no data stage */
+ usbd_ctlstatus_tx(pudev);
+ }
+ } else {
+ usbd_enum_error(pudev, req);
+ }
+ break;
+
+ default:
+ usbd_enum_error(pudev, req);
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ \brief handle USB vendor request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB vendor request
+ \param[out] none
+ \retval USB device operation status
+*/
+static usbd_status_enum usbd_vendor_request (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ /* added by user... */
+
+ return USBD_OK;
+}
+
+/*!
+ \brief no operation, just for reserved
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_reserved (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ /* no operation... */
+}
+
+/*!
+ \brief get the device descriptor
+ \brief[in] index: no use
+ \param[in] none
+ \param[out] pLen: data length pointer
+ \retval descriptor buffer pointer
+*/
+static uint8_t* usbd_device_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
+{
+ *pLen = pudev->dev.dev_desc[0];
+
+ return pudev->dev.dev_desc;
+}
+
+/*!
+ \brief get the configuration descriptor
+ \brief[in] index: no use
+ \param[in] none
+ \param[out] pLen: data length pointer
+ \retval descriptor buffer pointer
+*/
+static uint8_t* usbd_configuration_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
+{
+ *pLen = pudev->dev.config_desc[2];
+
+ return pudev->dev.config_desc;
+}
+
+/*!
+ \brief get string descriptor
+ \param[in] index: string descriptor index
+ \param[in] pLen: pointer to string length
+ \param[out] none
+ \retval none
+*/
+static uint8_t* usbd_string_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen)
+{
+ uint8_t *desc = pudev->dev.strings[index];
+
+ *pLen = desc[0];
+
+ return desc;
+}
+
+/*!
+ \brief handle Get_Status request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_getstatus (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+}
+
+/*!
+ \brief handle USB Clear_Feature request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_clrfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ uint8_t ep_addr = 0U;
+
+ switch (req->bmRequestType & USB_REQTYPE_MASK) {
+ case USB_REQTYPE_DEVICE:
+ switch (pudev->dev.status) {
+ case USB_STATUS_ADDRESSED:
+ case USB_STATUS_CONFIGURED:
+ if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
+ pudev->dev.remote_wakeup = 0U;
+ pudev->dev.class_req_handler(pudev, req);
+
+ usbd_ctlstatus_tx(pudev);
+ }
+ break;
+
+ default:
+ usbd_enum_error(pudev, req);
+ break;
+ }
+ break;
+ case USB_REQTYPE_INTERFACE:
+ switch (pudev->dev.status) {
+ case USB_STATUS_ADDRESSED:
+ usbd_enum_error(pudev, req);
+ break;
+ case USB_STATUS_CONFIGURED:
+ if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
+ /* no operation */
+ } else {
+ usbd_enum_error(pudev, req);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case USB_REQTYPE_ENDPOINT:
+ ep_addr = LOWBYTE(req->wIndex);
+
+ switch (pudev->dev.status) {
+ case USB_STATUS_ADDRESSED:
+ if (IS_NOT_EP0(ep_addr)) {
+ usbd_ep_stall(pudev, ep_addr);
+ }
+ break;
+ case USB_STATUS_CONFIGURED:
+ if (USB_FEATURE_ENDP_HALT == req->wValue) {
+ if (IS_NOT_EP0(ep_addr)) {
+ usbd_ep_clear_stall(pudev, ep_addr);
+
+ pudev->dev.class_req_handler(pudev, req);
+ }
+ }
+ usbd_ctlstatus_tx(pudev);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ usbd_enum_error(pudev, req);
+ break;
+ }
+}
+
+/*!
+ \brief handle USB Set_Feature request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_setfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ uint8_t ep_addr = 0U;
+ __IO uint32_t DctlrStatus;
+
+ switch (req->bmRequestType & USB_REQ_MASK) {
+ case USB_REQTYPE_DEVICE:
+ switch (pudev->dev.status) {
+ case USB_STATUS_ADDRESSED:
+ case USB_STATUS_CONFIGURED:
+ if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
+ pudev->dev.remote_wakeup = 1U;
+ pudev->dev.class_req_handler(pudev, req);
+
+ usbd_ctlstatus_tx(pudev);
+ } else if ((req->wValue == USB_FEATURE_TEST_MODE) &&
+ (0U == (req->wIndex & 0xFFU))) {
+ DctlrStatus = USB_DCTL;
+
+ usbd_ctlstatus_tx(pudev);
+ } else {
+ /* no operation */
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case USB_REQTYPE_INTERFACE:
+ switch (pudev->dev.status) {
+ case USB_STATUS_ADDRESSED:
+ usbd_enum_error(pudev, req);
+ break;
+ case USB_STATUS_CONFIGURED:
+ if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
+ /* no operation */
+ } else {
+ usbd_enum_error(pudev, req);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case USB_REQTYPE_ENDPOINT:
+ switch (pudev->dev.status) {
+ case USB_STATUS_ADDRESSED:
+ if (IS_NOT_EP0(ep_addr)) {
+ usbd_ep_stall(pudev, ep_addr);
+ }
+ break;
+ case USB_STATUS_CONFIGURED:
+ if (USB_FEATURE_ENDP_HALT == req->wValue) {
+ if (IS_NOT_EP0(ep_addr)) {
+ usbd_ep_stall(pudev, ep_addr);
+ }
+ }
+ pudev->dev.class_req_handler(pudev, req);
+
+ usbd_ctlstatus_tx(pudev);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ usbd_enum_error(pudev, req);
+ break;
+ }
+}
+
+/*!
+ \brief handle USB Set_Address request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_setaddress (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ uint8_t DevAddr;
+
+ if ((0U == req->wIndex) && (0U == req->wLength)) {
+ DevAddr = (uint8_t)(req->wValue) & 0x7FU;
+
+ if (USB_STATUS_CONFIGURED == pudev->dev.status) {
+ usbd_enum_error(pudev, req);
+ } else {
+ USB_SET_DEVADDR((uint32_t)DevAddr);
+
+ usbd_ctlstatus_tx(pudev);
+
+ if (0U != DevAddr) {
+ pudev->dev.status = USB_STATUS_ADDRESSED;
+ } else {
+ pudev->dev.status = USB_STATUS_DEFAULT;
+ }
+ }
+ } else {
+ usbd_enum_error(pudev, req);
+ }
+}
+
+/*!
+ \brief handle USB Get_Descriptor request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_getdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ if (USB_REQTYPE_DEVICE == (req->bmRequestType & USB_REQTYPE_MASK)) {
+ uint8_t desc_type = (uint8_t)(req->wValue >> 8);
+ uint8_t desc_index = (uint8_t)(req->wValue) & 0xFFU;
+
+ if ((desc_type <= 0x03U) && (desc_index <= 0x05U)) {
+ uint16_t len;
+ uint8_t *pbuf;
+
+ /* call corresponding descriptor get function */
+ pbuf = standard_descriptor_get[desc_type - 1U](pudev, desc_index, &len);
+
+ if ((0U != len) && (0U != req->wLength)) {
+ len = USB_MIN(len, req->wLength);
+
+ if ((1U == desc_type) && (64U == req->wLength)) {
+ len = 8U;
+ }
+
+ usbd_ctltx(pudev, pbuf, len);
+ }
+ } else {
+ usbd_enum_error(pudev, req);
+ }
+ } else if (USB_REQTYPE_INTERFACE == (req->bmRequestType & USB_REQTYPE_MASK)) {
+ pudev->dev.class_req_handler(pudev, req);
+ } else {
+ /* no operation */
+ }
+}
+
+/*!
+ \brief handle USB Set_Descriptor request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_setdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ /* no handle... */
+}
+
+/*!
+ \brief handle USB Get_Configuration request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_getconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ uint32_t USBD_default_config = 0U;
+
+ if (1U != req->wLength) {
+ usbd_enum_error(pudev, req);
+ } else {
+ switch (pudev->dev.status) {
+ case USB_STATUS_ADDRESSED:
+ usbd_ctltx(pudev, (uint8_t *)&USBD_default_config, 1U);
+ break;
+ case USB_STATUS_CONFIGURED:
+ usbd_ctltx(pudev, &pudev->dev.config_num, 1U);
+ break;
+ default:
+ usbd_enum_error(pudev, req);
+ break;
+ }
+ }
+}
+
+/*!
+ \brief handle USB Set_Configuration request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_setconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ static uint8_t cfgidx;
+
+ cfgidx = (uint8_t)(req->wValue);
+
+ if (cfgidx > USBD_CFG_MAX_NUM) {
+ usbd_enum_error(pudev, req);
+ } else {
+ switch (pudev->dev.status) {
+ case USB_STATUS_ADDRESSED:
+ if (cfgidx) {
+ pudev->dev.config_num = cfgidx;
+ pudev->dev.status = USB_STATUS_CONFIGURED;
+ pudev->dev.class_init(pudev, cfgidx);
+ }
+
+ usbd_ctlstatus_tx(pudev);
+ break;
+ case USB_STATUS_CONFIGURED:
+ if (0U == cfgidx) {
+ pudev->dev.status = USB_STATUS_ADDRESSED;
+ pudev->dev.config_num = cfgidx;
+ pudev->dev.class_deinit(pudev, cfgidx);
+ } else if (cfgidx != pudev->dev.config_num) {
+ /* clear old configuration */
+ pudev->dev.class_deinit(pudev, pudev->dev.config_num);
+
+ /* set new configuration */
+ pudev->dev.config_num = cfgidx;
+ pudev->dev.class_init(pudev, cfgidx);
+ } else {
+ /* no operation */
+ }
+
+ usbd_ctlstatus_tx(pudev);
+ break;
+ default:
+ usbd_enum_error(pudev, req);
+ break;
+ }
+ }
+}
+
+/*!
+ \brief handle USB Get_Interface request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_getinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ pudev->dev.class_req_handler(pudev, req);
+}
+
+/*!
+ \brief handle USB Set_Interface request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_setinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ pudev->dev.class_req_handler(pudev, req);
+}
+
+/*!
+ \brief handle USB SynchFrame request
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_synchframe (usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ /* no handle... */
+}
+
+/*!
+ \brief decode setup data packet
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+static void usbd_setup_request_parse(usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ uint8_t *psetup = pudev->dev.setup_packet;
+
+ req->bmRequestType = *psetup;
+ req->bRequest = *(uint8_t *)(psetup + 1U);
+ req->wValue = SWAPBYTE (psetup + 2U);
+ req->wIndex = SWAPBYTE (psetup + 4U);
+ req->wLength = SWAPBYTE (psetup + 6U);
+
+ pudev->dev.ctl_len = req->wLength;
+}
+
+/*!
+ \brief handle USB low level error event
+ \param[in] pudev: pointer to USB device instance
+ \param[in] req: pointer to USB device request
+ \param[out] none
+ \retval none
+*/
+void usbd_enum_error(usb_core_handle_struct *pudev, usb_device_req_struct *req)
+{
+ usbd_ep_stall(pudev, 0x80U);
+ usbd_ep_stall(pudev, 0x00U);
+ usb_ep0_startout(pudev);
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_core.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_core.c
new file mode 100644
index 0000000000000000000000000000000000000000..d717e87b217537cacb16ccb220d59bd8ea8581fd
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_core.c
@@ -0,0 +1,734 @@
+/*!
+ \file usbh_core.c
+ \brief this file implements the functions for the core state machine process
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "usbh_hcs.h"
+#include "usbh_core.h"
+#include "usbh_int.h"
+#include "stdio.h"
+#include "usbh_std.h"
+#include "usbh_ctrl.h"
+#include "usb_core.h"
+
+extern class_polling_fun_cb_struct class_polling_cb;
+
+uint8_t usbh_sof (usb_core_handle_struct *pudev);
+uint8_t usbh_connected (usb_core_handle_struct *pudev);
+uint8_t usbh_disconnected (usb_core_handle_struct *pudev);
+
+usbh_hcd_int_cb_struct usbh_hcd_int_cb =
+{
+ usbh_sof,
+ usbh_connected,
+ usbh_disconnected,
+};
+
+usbh_hcd_int_cb_struct *usbh_hcd_int_fops = &usbh_hcd_int_cb;
+extern usbh_state_handle_struct usbh_state_core;
+
+static void host_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_dev_attached_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_dev_detached_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_detect_dev_speed_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_enum_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_class_request_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_class_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_user_input_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_suspended_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void host_error_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+
+static usbh_status_enum class_req_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+static usbh_status_enum class_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
+
+/* the host state handle function array */
+void (*host_state_handle[]) (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate) =
+{
+ host_idle_handle,
+ host_dev_attached_handle,
+ host_dev_detached_handle,
+ host_detect_dev_speed_handle,
+ host_enum_handle,
+ host_class_request_handle,
+ host_class_handle,
+ host_user_input_handle,
+ host_suspended_handle,
+ host_error_handle,
+};
+
+/* the host state handle table */
+state_table_struct host_handle_table[HOST_HANDLE_TABLE_SIZE] =
+{
+ /* the current state the current event the next state the event function */
+ {HOST_IDLE, HOST_EVENT_ATTACHED, HOST_DEV_ATTACHED, only_state_move },
+ {HOST_DEV_ATTACHED, HOST_EVENT_ENUM, HOST_ENUMERATION, only_state_move },
+ {HOST_ENUMERATION, HOST_EVENT_USER_INPUT, HOST_USER_INPUT, only_state_move },
+ {HOST_USER_INPUT, HOST_EVENT_CLASS_REQ, HOST_CLASS_REQUEST, only_state_move },
+ {HOST_CLASS_REQUEST, HOST_EVENT_CLASS, HOST_CLASS, only_state_move },
+ {HOST_CLASS, HOST_EVENT_ERROR, HOST_ERROR, only_state_move },
+ {HOST_ERROR, HOST_EVENT_IDLE, HOST_IDLE, only_state_move },
+ {HOST_DEV_DETACHED, HOST_EVENT_IDLE, HOST_IDLE, only_state_move },
+ {HOST_CLASS_REQUEST, HOST_EVENT_ERROR, HOST_ERROR, only_state_move },
+};
+
+/*!
+ \brief the polling function of HOST state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+usbh_status_enum host_state_polling_fun (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ void *pustate)
+{
+ usbh_state_handle_struct *p_state = (usbh_state_handle_struct *)pustate;
+
+ scd_begin(p_state, HOST_FSM_ID);
+
+ if (-1 == p_state->usbh_current_state_stack_top) {
+ uint8_t cur_state = p_state->usbh_current_state;
+
+ if ((0U == hcd_is_device_connected(pudev)) && (HOST_IDLE != cur_state)) {
+ if (HOST_DEV_DETACHED != cur_state) {
+ p_state->usbh_current_state = HOST_DEV_DETACHED;
+ cur_state = HOST_DEV_DETACHED;
+ }
+ }
+
+ host_state_handle[cur_state](pudev, puhost, p_state);
+ } else {
+ uint8_t stack0_state = p_state->stack[0].state;
+
+ if ((0U == hcd_is_device_connected(pudev)) && (HOST_IDLE != stack0_state)) {
+ if (HOST_DEV_DETACHED != stack0_state) {
+ p_state->stack[0].state = HOST_DEV_DETACHED;
+ stack0_state = HOST_DEV_DETACHED;
+ p_state->usbh_current_state = HOST_DEV_DETACHED;
+ }
+ }
+
+ host_state_handle[stack0_state](pudev, puhost, p_state);
+ }
+
+ return USBH_OK;
+}
+
+/*!
+ \brief the handle function of HOST_IDLE state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void host_idle_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ if (hcd_is_device_connected(pudev)) {
+ scd_event_handle(pudev, puhost, pustate, HOST_EVENT_ATTACHED, pustate->usbh_current_state);
+
+ if ((void *)0 != pudev->mdelay) {
+ pudev->mdelay(100U);
+ }
+ }
+}
+
+/*!
+ \brief the handle function of HOST_DEV_ATTACHED state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void host_dev_attached_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usr_cb->device_connected();
+ puhost->control.hc_out_num = usbh_channel_alloc(pudev, 0x00U);
+ puhost->control.hc_in_num = usbh_channel_alloc(pudev, 0x80U);
+
+ /* reset usb device */
+ if (0U == usb_port_reset(pudev)) {
+ puhost->usr_cb->device_reset();
+
+ /* wait for USB USBH_ISR_PrtEnDisableChange()
+ * host is now ready to start the enumeration
+ */
+ puhost->device.speed = (uint8_t)USB_CURRENT_SPEED_GET();
+ puhost->usr_cb->device_speed_detected(puhost->device.speed);
+
+ /* open IN control pipes */
+ usbh_channel_open (pudev,
+ puhost->control.hc_in_num,
+ puhost->device.address,
+ puhost->device.speed,
+ USB_EPTYPE_CTRL,
+ (uint16_t)puhost->control.ep0_size);
+
+ /* open OUT control pipes */
+ usbh_channel_open (pudev,
+ puhost->control.hc_out_num,
+ puhost->device.address,
+ puhost->device.speed,
+ USB_EPTYPE_CTRL,
+ (uint16_t)puhost->control.ep0_size);
+
+ scd_event_handle(pudev, puhost, pustate, HOST_EVENT_ENUM, pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of HOST_ENUMERATION state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void host_enum_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ if (USBH_OK == enum_state_polling_fun(pudev, puhost, pustate)) {
+ puhost->usr_cb->enumeration_finish();
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ HOST_EVENT_USER_INPUT,
+ pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of HOST_USER_INPUT state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void host_user_input_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ if (USBH_USER_RESP_OK == puhost->usr_cb->user_input()) {
+ if (USBH_OK == (puhost->class_init(pudev, puhost))) {
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ HOST_EVENT_CLASS_REQ,
+ pustate->usbh_current_state);
+ }
+ }
+}
+
+/*!
+ \brief the handle function of HOST_CLASS_REQUEST state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void host_class_request_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ if (USBH_OK == class_req_state_polling_fun(pudev, puhost, pustate)) {
+ scd_event_handle(pudev, puhost, pustate, HOST_EVENT_CLASS, pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of HOST_CLASS state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void host_class_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ class_state_polling_fun(pudev, puhost, pustate);
+}
+
+/*!
+ \brief the handle function of HOST_SUSPENDED state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void host_suspended_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ /* no operation */
+}
+
+/*!
+ \brief the handle function of HOST_ERROR state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void host_error_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ /* re-initilaize host for new enumeration */
+ usbh_deinit (pudev, puhost,&usbh_state_core);
+ puhost->usr_cb->deinit();
+ puhost->class_deinit(pudev, &puhost->device);
+ scd_event_handle(pudev, puhost, pustate, HOST_EVENT_IDLE, pustate->usbh_current_state);
+}
+
+/*!
+ \brief the handle function of HOST_DEV_DETACHED state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void host_dev_detached_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ /* manage user disconnect operations*/
+ puhost->usr_cb->device_disconnected();
+
+ /* re-initilaize host for new enumeration */
+ usbh_deinit(pudev, puhost,&usbh_state_core);
+ puhost->usr_cb->deinit();
+ puhost->class_deinit(pudev, &puhost->device);
+ usbh_allchannel_dealloc(pudev);
+ scd_event_handle(pudev, puhost, pustate, HOST_EVENT_IDLE, pustate->usbh_current_state);
+}
+
+/*!
+ \brief the handle function of HOST_DETECT_DEV_SPEED state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void host_detect_dev_speed_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ /* no operation */
+}
+
+/*!
+ \brief usb connect callback function from the interrupt.
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval operation status
+*/
+uint8_t usbh_connected (usb_core_handle_struct *pudev)
+{
+ pudev->host.connect_status = 1U;
+
+ return 0U;
+}
+
+/*!
+ \brief usb disconnect callback function from the interrupt.
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval operation status
+*/
+uint8_t usbh_disconnected (usb_core_handle_struct *pudev)
+{
+ pudev->host.connect_status = 0U;
+
+ return 0U;
+}
+
+/*!
+ \brief usb sof callback function from the interrupt.
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval operation status
+*/
+uint8_t usbh_sof (usb_core_handle_struct *pudev)
+{
+ /* this callback could be used to implement a scheduler process */
+ return 0U;
+}
+
+/*!
+ \brief initialize the host portion of the driver.
+ \param[in] pudev: pointer to usb device
+ \param[in] core_id: usb otg core identifier(high-speed or full-speed)
+ \param[out] none
+ \retval operation status
+*/
+uint32_t hcd_init(usb_core_handle_struct *pudev, usb_core_id_enum core_id)
+{
+ pudev->host.connect_status = 0U;
+
+ pudev->host.host_channel[0].endp_mps = 8U;
+
+ usb_core_select(pudev, core_id);
+
+#ifndef DUAL_ROLE_MODE_ENABLED
+
+ USB_GLOBAL_INT_DISABLE();
+
+ usb_core_init(pudev);
+
+ /* force host mode*/
+ usb_mode_set(pudev, HOST_MODE);
+
+ usb_hostcore_init(pudev);
+
+ USB_GLOBAL_INT_ENABLE();
+
+#endif
+
+ return 0U;
+}
+
+/*!
+ \brief check if the device is connected.
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval device connection status. 1 -> connected and 0 -> disconnected
+*/
+uint32_t hcd_is_device_connected(usb_core_handle_struct *pudev)
+{
+ return (uint32_t)(pudev->host.connect_status);
+}
+
+/*!
+ \brief this function returns the last URBstate
+ \param[in] pudev: pointer to usb device
+ \param[in] channel_num: host channel number which is in (0..7)
+ \param[out] none
+ \retval urb_state_enum
+*/
+urb_state_enum hcd_urb_state_get (usb_core_handle_struct *pudev, uint8_t channel_num)
+{
+ return pudev->host.host_channel[channel_num].urb_state;
+}
+
+/*!
+ \brief this function returns the last URBstate
+ \param[in] pudev: pointer to usb device
+ \param[in] channel_num: host channel number which is in (0..7)
+ \param[out] none
+ \retval No. of data bytes transferred
+*/
+uint32_t hcd_xfer_count_get (usb_core_handle_struct *pudev, uint8_t channel_num)
+{
+ return pudev->host.host_channel[channel_num].xfer_count;
+}
+
+/*!
+ \brief de-initialize host
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[out] none
+ \retval host status
+*/
+usbh_status_enum usbh_deinit(usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct* pustate)
+{
+ /* software init */
+
+ puhost->control.ep0_size = USB_MAX_EP0_SIZE;
+
+ puhost->device.address = USBH_DEVICE_ADDRESS_DEFAULT;
+ puhost->device.speed = HPRT_PRTSPD_FULL_SPEED;
+
+ usbh_channel_free(pudev, puhost->control.hc_in_num);
+ usbh_channel_free(pudev, puhost->control.hc_out_num);
+
+ scd_init(pustate);
+ scd_table_regist(pustate, host_handle_table, HOST_FSM_ID, HOST_HANDLE_TABLE_SIZE);
+ scd_table_regist(pustate, enum_handle_table, ENUM_FSM_ID, ENUM_HANDLE_TABLE_SIZE);
+ scd_table_regist(pustate, ctrl_handle_table, CTRL_FSM_ID, CTRL_HANDLE_TABLE_SIZE);
+
+ scd_begin(pustate,HOST_FSM_ID);
+ scd_state_move(pustate, HOST_IDLE);
+
+ return USBH_OK;
+}
+
+/*!
+ \brief state core driver init
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+void scd_init(usbh_state_handle_struct* pustate)
+{
+ /* init the state core */
+ pustate->usbh_current_state = 0U;
+ pustate->usbh_current_state_table = NULL;
+ pustate->usbh_current_state_table_size = 0U;
+
+ pustate->usbh_current_state_stack_top = -1;
+ pustate->stack->state = 0U;
+ pustate->stack->table_size = 0U;
+ pustate->stack->table = NULL;
+
+ pustate->usbh_regist_state_table_num = 0U;
+ pustate->usbh_regist_state_table->table = NULL;
+ pustate->usbh_regist_state_table->table_size = 0U;
+ pustate->usbh_regist_state_table->id = 0U;
+
+ /* init the control and the enumeration polling handle flag */
+ ctrl_polling_handle_flag = 0U;
+ enum_polling_handle_flag = 0U;
+}
+
+/*!
+ \brief state core driver table regist
+ \param[in] pustate: pointer to usb state driver
+ \param[in] pstate_table: pointer to the table to regist
+ \param[in] table_id: the id of the table to regist
+ \param[in] current_table_size: the size of the current table to regist
+ \param[out] none
+ \retval none
+*/
+void scd_table_regist (usbh_state_handle_struct* pustate,
+ state_table_struct* pstate_table,
+ uint8_t table_id,
+ uint8_t current_table_size)
+{
+ usbh_state_regist_table_struct *cur_state_reg_table;
+
+ cur_state_reg_table = &pustate->usbh_regist_state_table[pustate->usbh_regist_state_table_num];
+
+ cur_state_reg_table->id = table_id;
+ cur_state_reg_table->table = pstate_table;
+ cur_state_reg_table->table_size = current_table_size;
+
+ pustate->usbh_regist_state_table_num++;
+}
+
+/*!
+ \brief state core driver begin
+ \param[in] pustate: pointer to usb state driver
+ \param[in] table_id: the id of the table to begin
+ \param[out] none
+ \retval none
+*/
+void scd_begin(usbh_state_handle_struct* pustate, uint8_t table_id)
+{
+ uint8_t i = 0U, table_num = pustate->usbh_regist_state_table_num;
+ usbh_state_regist_table_struct *cur_state_reg_table;
+
+ for (i = 0U; i < table_num; i++) {
+ cur_state_reg_table = &pustate->usbh_regist_state_table[i];
+
+ if (table_id == cur_state_reg_table->id) {
+ pustate->usbh_current_state_table = cur_state_reg_table->table;
+ pustate->usbh_current_state_table_size = cur_state_reg_table->table_size;
+ break;
+ }
+ }
+}
+
+/*!
+ \brief state core driver move state
+ \param[in] pustate: pointer to usb state driver
+ \param[in] state: the state to move
+ \param[out] none
+ \retval none
+*/
+void scd_state_move(usbh_state_handle_struct* pustate, uint8_t state)
+{
+ pustate->usbh_current_state = state;
+}
+
+/*!
+ \brief state core driver event handle
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[in] event: the current event
+ \param[in] state: the current state
+ \param[out] none
+ \retval host status
+*/
+usbh_status_enum scd_event_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct* pustate,
+ uint8_t event,
+ uint8_t state)
+{
+ uint8_t i = 0U;
+ ACT_FUN event_act_fun = NULL;
+ state_table_struct *backup_state_t = pustate->usbh_current_state_table;
+ state_table_struct *executive_state_table = pustate->usbh_current_state_table;
+
+ /* look up the table to find the action function */
+ for (i = 0U; i < pustate->usbh_current_state_table_size; i++) {
+ if (state == executive_state_table->cur_state) {
+ if (event == executive_state_table->cur_event) {
+ state = executive_state_table->next_state;
+ event_act_fun = executive_state_table->event_action_fun;
+ break;
+ } else {
+ executive_state_table++;
+ }
+ } else {
+ executive_state_table++;
+ }
+ }
+
+ pustate->usbh_current_state_table = backup_state_t;
+
+ /* if the action function is not NULL, execute the action function */
+ if (event_act_fun) {
+ if (event_act_fun == &only_state_move) {
+ pustate->usbh_current_state = state;
+ } else {
+ return event_act_fun(pudev, puhost, pustate);
+ }
+ }
+
+ return USBH_BUSY;
+}
+
+/*!
+ \brief state core driver table push
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+void scd_table_push(usbh_state_handle_struct* pustate)
+{
+ usbh_state_stack_struct *top_state_element;
+
+ if (pustate->usbh_current_state_stack_top < MAX_USBH_STATE_STACK_DEEP) {
+ pustate->usbh_current_state_stack_top++;
+
+ top_state_element = &pustate->stack[pustate->usbh_current_state_stack_top];
+
+ /* put the current state table into the state stack */
+ top_state_element->state = pustate->usbh_current_state;
+ top_state_element->table = pustate->usbh_current_state_table;
+ top_state_element->table_size = pustate->usbh_current_state_table_size;
+ }
+}
+
+/*!
+ \brief state core driver table pop
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+void scd_table_pop (usbh_state_handle_struct* pustate)
+{
+ usbh_state_stack_struct *top_state_element;
+
+ top_state_element = &pustate->stack[pustate->usbh_current_state_stack_top];
+
+ if (pustate->usbh_current_state_stack_top > -1) {
+ /* get the current state table from the state stack */
+ pustate->usbh_current_state = top_state_element->state;
+ pustate->usbh_current_state_table = top_state_element->table;
+ pustate->usbh_current_state_table_size = top_state_element->table_size;
+ pustate->usbh_current_state_stack_top--;
+ }
+}
+/*!
+ \brief the polling function of class req state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval host status
+*/
+static usbh_status_enum class_req_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
+{
+ return class_polling_cb.class_req_polling(pudev, puhost, pustate);
+}
+
+/*!
+ \brief the polling function of class state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval host status
+*/
+static usbh_status_enum class_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
+{
+ return class_polling_cb.class_polling(pudev, puhost, pustate);
+}
+
+/*!
+ \brief the function is only used to state move
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+usbh_status_enum only_state_move (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
+{
+ return USBH_OK;
+}
+
+/*!
+ \brief the function to the up state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+usbh_status_enum goto_up_state_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
+{
+ scd_table_pop((usbh_state_handle_struct *)pustate);
+
+ return USBH_OK;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_ctrl.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_ctrl.c
new file mode 100644
index 0000000000000000000000000000000000000000..c40df945f30b2dfc088ce0d5f070e25c54651c8e
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_ctrl.c
@@ -0,0 +1,636 @@
+/*!
+ \file usbh_ctrl.c
+ \brief this file implements the functions for the control transmit process
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "usbh_core.h"
+#include "usbh_std.h"
+#include "usbh_ctrl.h"
+
+uint8_t ctrl_polling_handle_flag = 0U;
+uint8_t ctrl_setup_wait_flag = 0U;
+uint8_t ctrl_data_wait_flag = 0U;
+uint8_t ctrl_status_wait_flag = 0U;
+
+static uint16_t timeout = 0U;
+
+static void ctrl_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_setup_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_data_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_status_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_error_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_stalled_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void ctrl_complete_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+
+/* the ctrl state handle function array */
+void (*ctrl_state_handle[]) (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate) =
+{
+ ctrl_idle_handle,
+ ctrl_setup_handle,
+ ctrl_data_handle,
+ ctrl_status_handle,
+ ctrl_error_handle,
+ ctrl_stalled_handle,
+ ctrl_complete_handle,
+};
+
+/* the ctrl state handle table */
+state_table_struct ctrl_handle_table[CTRL_HANDLE_TABLE_SIZE] =
+{
+ /* the current state the current event the next state the event function */
+ {CTRL_IDLE, CTRL_EVENT_SETUP, CTRL_SETUP, only_state_move },
+ {CTRL_SETUP, CTRL_EVENT_DATA, CTRL_DATA, only_state_move },
+ {CTRL_SETUP, CTRL_EVENT_STATUS, CTRL_STATUS, only_state_move },
+ {CTRL_SETUP, CTRL_EVENT_ERROR, CTRL_ERROR, only_state_move },
+ {CTRL_DATA, CTRL_EVENT_STATUS, CTRL_STATUS, only_state_move },
+ {CTRL_DATA, CTRL_EVENT_ERROR, CTRL_ERROR, only_state_move },
+ {CTRL_DATA, CTRL_EVENT_STALLED, CTRL_STALLED, only_state_move },
+ {CTRL_STATUS, CTRL_EVENT_COMPLETE, CTRL_COMPLETE, only_state_move },
+ {CTRL_STATUS, CTRL_EVENT_ERROR, CTRL_ERROR, only_state_move },
+ {CTRL_STATUS, CTRL_EVENT_STALLED, CTRL_STALLED, only_state_move },
+ {CTRL_ERROR, GO_TO_UP_STATE_EVENT, UP_STATE, goto_up_state_fun },
+ {CTRL_STALLED, GO_TO_UP_STATE_EVENT, UP_STATE, goto_up_state_fun },
+ {CTRL_COMPLETE, GO_TO_UP_STATE_EVENT, UP_STATE, goto_up_state_fun },
+};
+
+/*!
+ \brief the polling function of CTRL state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+usbh_status_enum ctrl_state_polling_fun (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ void *pustate)
+{
+ usbh_status_enum exe_state = USBH_BUSY;
+ usbh_state_handle_struct *p_state;
+
+ p_state = (usbh_state_handle_struct *)pustate;
+
+ /* if first enter this function, begin the ctrl state */
+ if (0U == ctrl_polling_handle_flag) {
+ ctrl_polling_handle_flag = 1U;
+ scd_table_push(p_state);
+ scd_state_move(p_state, CTRL_IDLE);
+ }
+
+ /* base on the current state to handle the ctrl state */
+ scd_begin(p_state, CTRL_FSM_ID);
+ ctrl_state_handle[p_state->usbh_current_state](pudev, puhost, p_state);
+
+ /* determine the control transfer whether to complete */
+ switch (puhost->usbh_backup_state.ctrl_backup_state) {
+ case CTRL_COMPLETE:
+ ctrl_polling_handle_flag = 0U;
+ puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE;
+ exe_state = USBH_OK;
+ break;
+ case CTRL_STALLED:
+ ctrl_polling_handle_flag = 0U;
+ puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE;
+ exe_state = USBH_NOT_SUPPORTED;
+ break;
+ case CTRL_ERROR:
+ ctrl_polling_handle_flag = 0U;
+ puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE;
+ exe_state = USBH_FAIL;
+ break;
+ default:
+ exe_state = USBH_BUSY;
+ break;
+ }
+
+ return exe_state;
+}
+
+/*!
+ \brief the handle function of CTRL_IDLE state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void ctrl_idle_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE;
+ scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_SETUP, pustate->usbh_current_state);
+}
+
+/*!
+ \brief the handle function of CTRL_SETUP state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void ctrl_setup_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ urb_state_enum urb_status = URB_IDLE;
+ puhost->usbh_backup_state.ctrl_backup_state = CTRL_SETUP;
+
+ if (0U == ctrl_setup_wait_flag) {
+ ctrl_setup_wait_flag = 1U;
+
+ /* send a setup packet */
+ usbh_ctltx_setup (pudev,
+ puhost->control.setup.data,
+ puhost->control.hc_out_num);
+ } else {
+ urb_status = hcd_urb_state_get(pudev, puhost->control.hc_out_num);
+
+ /* case setup packet sent successfully */
+ if (URB_DONE == urb_status) {
+ /* check if there is a data stage */
+ if (0U != puhost->control.setup.b.wLength) {
+ ctrl_setup_wait_flag = 0U;
+ timeout = DATA_STAGE_TIMEOUT;
+ scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_DATA, pustate->usbh_current_state);
+ /* no data stage */
+ } else {
+ timeout = NODATA_STAGE_TIMEOUT;
+ ctrl_setup_wait_flag = 0U;
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_STATUS,
+ pustate->usbh_current_state);
+ }
+
+ /* set the delay timer to enable timeout for data stage completion */
+ puhost->control.timer = (uint16_t)USB_CURRENT_FRAME_GET();
+ } else if (URB_ERROR == urb_status) {
+ ctrl_setup_wait_flag = 0U;
+ scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_ERROR, pustate->usbh_current_state);
+ } else {
+ /* no operation */
+ }
+ }
+}
+
+/*!
+ \brief the handle function of CTRL_DATA state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void ctrl_data_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ uint8_t direction;
+ urb_state_enum urb_status = URB_IDLE;
+ puhost->usbh_backup_state.ctrl_backup_state = CTRL_DATA;
+
+ direction = (puhost->control.setup.b.bmRequestType & USB_DIR_MASK);
+
+ if (USB_DIR_IN == direction) {
+ if (0U == ctrl_data_wait_flag) {
+ ctrl_data_wait_flag = 1U;
+
+ /* issue an IN token */
+ usbh_xfer(pudev,
+ puhost->control.buff,
+ puhost->control.hc_in_num,
+ puhost->control.length);
+ } else {
+ urb_status = hcd_urb_state_get(pudev, puhost->control.hc_in_num);
+
+ /* check is data packet transfered successfully */
+ switch (urb_status) {
+ case URB_DONE:
+ ctrl_data_wait_flag = 0U;
+
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_STATUS,
+ pustate->usbh_current_state);
+ break;
+ case URB_STALL:
+ ctrl_data_wait_flag = 0U;
+
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_STALLED,
+ pustate->usbh_current_state);
+ break;
+ case URB_ERROR:
+ ctrl_data_wait_flag = 0U;
+
+ /* device error */
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_ERROR,
+ pustate->usbh_current_state);
+ break;
+ default:
+ if (((uint16_t)USB_CURRENT_FRAME_GET() - puhost->control.timer) > timeout) {
+ ctrl_data_wait_flag = 0U;
+
+ /* timeout for IN transfer */
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_ERROR,
+ pustate->usbh_current_state);
+ }
+ break;
+ }
+ }
+ } else {
+ if (0U == ctrl_data_wait_flag) {
+ ctrl_data_wait_flag = 1U;
+
+ /* start DATA out transfer (only one DATA packet)*/
+ pudev->host.host_channel[puhost->control.hc_out_num].data_tg_out = 1U;
+
+ usbh_xfer(pudev,
+ puhost->control.buff,
+ puhost->control.hc_out_num,
+ puhost->control.length);
+ } else {
+ urb_status = hcd_urb_state_get(pudev, puhost->control.hc_out_num);
+
+ switch (urb_status) {
+ case URB_DONE:
+ ctrl_data_wait_flag = 0U;
+
+ /* if the setup pkt is sent successful, then change the state */
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_STATUS,
+ pustate->usbh_current_state);
+ break;
+ case URB_STALL:
+ ctrl_data_wait_flag = 0U;
+
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_STALLED,
+ pustate->usbh_current_state);
+ break;
+ case URB_NOTREADY:
+ /* nack received from device */
+ ctrl_data_wait_flag = 0U;
+ break;
+ case URB_ERROR:
+ ctrl_data_wait_flag = 0U;
+
+ /* device error */
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_ERROR,
+ pustate->usbh_current_state);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+/*!
+ \brief the handle function of CTRL_STATUS state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void ctrl_status_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ uint8_t direction;
+ urb_state_enum urb_status = URB_IDLE;
+
+ puhost->usbh_backup_state.ctrl_backup_state = CTRL_STATUS;
+
+ /* get the transfer direction in the data state, but the transfer direction in the status state is opposite */
+ direction = (puhost->control.setup.b.bmRequestType & USB_DIR_MASK);
+
+ if (USB_DIR_OUT == direction) {
+ /* handle status in */
+ if (0U == ctrl_status_wait_flag) {
+ ctrl_status_wait_flag = 1U;
+ usbh_xfer (pudev, 0U, puhost->control.hc_in_num, 0U);
+ } else {
+ urb_status = hcd_urb_state_get(pudev, puhost->control.hc_in_num);
+
+ switch (urb_status) {
+ case URB_DONE:
+ ctrl_status_wait_flag = 0U;
+
+ /* handle URB_DONE status */
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_COMPLETE,
+ pustate->usbh_current_state);
+ break;
+ case URB_ERROR:
+ ctrl_status_wait_flag = 0U;
+
+ /* handle URB_STALL status*/
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_ERROR,
+ pustate->usbh_current_state);
+ break;
+ case URB_STALL:
+ ctrl_status_wait_flag = 0U;
+
+ /* handle URB_STALL status */
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_STALLED,
+ pustate->usbh_current_state);
+ break;
+ default:
+ if (((uint16_t)USB_CURRENT_FRAME_GET() - puhost->control.timer) > timeout) {
+ ctrl_status_wait_flag = 0U;
+
+ /* handle timeout */
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_ERROR,
+ pustate->usbh_current_state);
+ }
+ break;
+ }
+ }
+ } else {
+ /* handle status out */
+ if (0U == ctrl_status_wait_flag) {
+ ctrl_status_wait_flag = 1U;
+ pudev->host.host_channel[puhost->control.hc_out_num].data_tg_out ^= 1U;
+ usbh_xfer (pudev, 0U, puhost->control.hc_out_num, 0U);
+ } else {
+ urb_status = hcd_urb_state_get(pudev, puhost->control.hc_out_num);
+
+ switch (urb_status) {
+ case URB_DONE:
+ ctrl_status_wait_flag = 0U;
+
+ /* handle URB_DONE status */
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_COMPLETE,
+ pustate->usbh_current_state);
+ break;
+ case URB_NOTREADY:
+ /* handle URB_NOTREADY status */
+ ctrl_status_wait_flag = 0U;
+ break;
+ case URB_ERROR:
+ ctrl_status_wait_flag = 0U;
+
+ /* handle URB_ERROR status */
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ CTRL_EVENT_ERROR,
+ pustate->usbh_current_state);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+/*!
+ \brief the handle function of CTRL_ERROR state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void ctrl_error_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.ctrl_backup_state = CTRL_ERROR;
+
+ if (++puhost->control.error_count <= USBH_MAX_ERROR_COUNT) {
+ /* do the transmission again, starting from SETUP Packet */
+ scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_SETUP, pustate->usbh_current_state);
+ } else {
+ scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of CTRL_STALLED state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void ctrl_stalled_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.ctrl_backup_state = CTRL_STALLED;
+ scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state);
+}
+
+/*!
+ \brief the handle function of CTRL_COMPLETE state
+ \param[in] pudev: pointer to usb device
+ \param[in] puhost: pointer to usb host
+ \param[in] pustate: pointer to usb state driver
+ \param[out] none
+ \retval none
+*/
+static void ctrl_complete_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.ctrl_backup_state = CTRL_COMPLETE;
+ scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state);
+}
+
+/*!
+ \brief send datas from the host channel
+ \param[in] pudev: pointer to usb device
+ \param[in] buf: data buffer address to send datas
+ \param[in] hc_num: the number of the host channel
+ \param[in] len: length of the send data
+ \param[out] none
+ \retval host operation status
+*/
+usbh_status_enum usbh_xfer (usb_core_handle_struct *pudev,
+ uint8_t *buf,
+ uint8_t hc_num,
+ uint16_t len)
+{
+ usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num];
+
+ puhc->xfer_buff = buf;
+ puhc->xfer_len = len;
+
+ switch (puhc->endp_type) {
+ case USB_EPTYPE_CTRL:
+ if (0U == puhc->endp_in) {
+ if (0U == len) {
+ /* for status out stage, length = 0, status out pid = 1 */
+ puhc->data_tg_out = 1U;
+ }
+
+ /* set the data toggle bit as per the flag */
+ if (0U == puhc->data_tg_out) {
+ /* put the pid 0 */
+ puhc->DPID = HC_PID_DATA0;
+ } else {
+ /* put the pid 1 */
+ puhc->DPID = HC_PID_DATA1;
+ }
+ } else {
+ puhc->DPID = HC_PID_DATA1;
+ }
+ break;
+
+ case USB_EPTYPE_ISOC:
+ puhc->DPID = HC_PID_DATA0;
+ break;
+
+ case USB_EPTYPE_BULK:
+ if (0U == puhc->endp_in) {
+ /* set the data toggle bit as per the flag */
+ if (0U == puhc->data_tg_out) {
+ /* put the pid 0 */
+ puhc->DPID = HC_PID_DATA0;
+ } else {
+ /* put the pid 1 */
+ puhc->DPID = HC_PID_DATA1;
+ }
+ } else {
+ if (0U == puhc->data_tg_in) {
+ puhc->DPID = HC_PID_DATA0;
+ } else {
+ puhc->DPID = HC_PID_DATA1;
+ }
+ }
+ break;
+
+ case USB_EPTYPE_INTR:
+ if (0U == puhc->endp_in) {
+ if (0U == puhc->data_tg_out) {
+ puhc->DPID = HC_PID_DATA0;
+ } else {
+ puhc->DPID = HC_PID_DATA1;
+ }
+
+ /* toggle data pid */
+ puhc->data_tg_out ^= 1U;
+ } else {
+ if (0U == puhc->data_tg_in) {
+ puhc->DPID = HC_PID_DATA0;
+ } else {
+ puhc->DPID = HC_PID_DATA1;
+ }
+
+ /* toggle data pid */
+ puhc->data_tg_in ^= 1U;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ hcd_submit_request (pudev, hc_num);
+
+ return USBH_OK;
+}
+
+/*!
+ \brief send the setup packet to the device
+ \param[in] pudev: pointer to usb device
+ \param[in] buf: buffer pointer from which the data will be send to device
+ \param[in] hc_num: host channel number
+ \param[out] none
+ \retval host operation status
+*/
+usbh_status_enum usbh_ctltx_setup (usb_core_handle_struct *pudev, uint8_t *buf, uint8_t hc_num)
+{
+ usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num];
+
+ puhc->DPID = HC_PID_SETUP;
+ puhc->xfer_buff = buf;
+ puhc->xfer_len = USBH_SETUP_PACKET_SIZE;
+
+ return (usbh_status_enum)hcd_submit_request (pudev, hc_num);
+}
+
+/*!
+ \brief this function prepare a hc and start a transfer
+ \param[in] pudev: pointer to usb device
+ \param[in] channel_num: host channel number which is in (0..7)
+ \param[out] none
+ \retval host operation status
+*/
+uint32_t hcd_submit_request (usb_core_handle_struct *pudev, uint8_t channel_num)
+{
+ usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
+
+ puhc->urb_state = URB_IDLE;
+ puhc->xfer_count = 0U;
+
+ return (uint32_t)usb_hostchannel_startxfer(pudev, channel_num);
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_hcs.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_hcs.c
new file mode 100644
index 0000000000000000000000000000000000000000..801cb5069e290ea7f84e55a8492466b10e61c4cd
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_hcs.c
@@ -0,0 +1,182 @@
+/*!
+ \file usbh_hcs.c
+ \brief this file implements functions for opening and closing host channels
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "usbh_hcs.h"
+
+static uint16_t usbh_freechannel_get (usb_core_handle_struct *pudev);
+
+/*!
+ \brief open a channel
+ \param[in] pudev: pointer to usb device
+ \param[in] channel_num: host channel number which is in (0..7)
+ \param[in] dev_addr: USB device address allocated to attached device
+ \param[in] dev_speed: USB device speed (Full speed/Low speed)
+ \param[in] ep_type: endpoint type (bulk/int/ctl)
+ \param[in] ep_mps: max packet size
+ \param[out] none
+ \retval operation status
+*/
+uint8_t usbh_channel_open (usb_core_handle_struct *pudev,
+ uint8_t channel_num,
+ uint8_t dev_addr,
+ uint8_t dev_speed,
+ uint8_t ep_type,
+ uint16_t ep_mps)
+{
+ usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
+ uint16_t channel_info = puhc->info;
+
+ puhc->endp_id = (uint8_t)channel_info & 0x7FU;
+ puhc->endp_in = (uint8_t)(channel_info & 0x80U) >> 7;
+ puhc->endp_type = ep_type;
+ puhc->endp_mps = ep_mps;
+ puhc->dev_addr = dev_addr;
+ puhc->dev_speed = dev_speed;
+
+ puhc->data_tg_in = 0U;
+ puhc->data_tg_out = 0U;
+
+ usb_hostchannel_init(pudev, channel_num);
+
+ return (uint8_t)HC_OK;
+}
+
+/*!
+ \brief modify a channel
+ \param[in] pudev: pointer to usb device
+ \param[in] channel_num: host channel number which is in (0..7)
+ \param[in] dev_addr: USB Device address allocated to attached device
+ \param[in] dev_speed: USB device speed (Full speed/Low speed)
+ \param[in] ep_type: endpoint type (bulk/int/ctl)
+ \param[in] ep_mps: max packet size
+ \param[out] none
+ \retval operation status
+*/
+uint8_t usbh_channel_modify (usb_core_handle_struct *pudev,
+ uint8_t channel_num,
+ uint8_t dev_addr,
+ uint8_t dev_speed,
+ uint8_t ep_type,
+ uint16_t ep_mps)
+{
+ usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
+
+ if (0U != dev_addr) {
+ puhc->dev_addr = dev_addr;
+ }
+
+ if ((puhc->endp_mps != ep_mps) && (0U != ep_mps)) {
+ puhc->endp_mps = ep_mps;
+ }
+
+ if ((puhc->dev_speed != dev_speed) && (0U != dev_speed)) {
+ puhc->dev_speed = dev_speed;
+ }
+
+ usb_hostchannel_init(pudev, channel_num);
+
+ return (uint8_t)HC_OK;
+}
+
+/*!
+ \brief allocate a new channel for the pipe
+ \param[in] pudev: pointer to usb device
+ \param[in] ep_addr: endpoint for which the channel to be allocated
+ \param[out] none
+ \retval host channel number
+*/
+uint8_t usbh_channel_alloc (usb_core_handle_struct *pudev, uint8_t ep_addr)
+{
+ uint16_t hc_num = usbh_freechannel_get(pudev);
+
+ if ((uint16_t)HC_ERROR != hc_num) {
+ pudev->host.host_channel[hc_num].info = HC_USED | ep_addr;
+ }
+
+ return (uint8_t)hc_num;
+}
+
+/*!
+ \brief free the usb host channel
+ \param[in] pudev: pointer to usb device
+ \param[in] index: channel number to be freed which is in (0..7)
+ \param[out] none
+ \retval host operation status
+*/
+uint8_t usbh_channel_free (usb_core_handle_struct *pudev, uint8_t index)
+{
+ if (index < HC_MAX) {
+ pudev->host.host_channel[index].info &= HC_USED_MASK;
+ }
+
+ return USBH_OK;
+}
+
+/*!
+ \brief free all usb host channel
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval host operation status
+*/
+uint8_t usbh_allchannel_dealloc (usb_core_handle_struct *pudev)
+{
+ uint8_t index;
+
+ for (index = 2U; index < HC_MAX; index ++) {
+ pudev->host.host_channel[index].info = 0U;
+ }
+
+ return USBH_OK;
+}
+
+/*!
+ \brief get a free channel number for allocation to a device endpoint
+ \param[in] pudev: pointer to usb device
+ \param[out] none
+ \retval free channel number
+*/
+static uint16_t usbh_freechannel_get (usb_core_handle_struct *pudev)
+{
+ uint8_t index = 0U;
+
+ for (index = 0U; index < HC_MAX; index++) {
+ if (0U == (pudev->host.host_channel[index].info & HC_USED)) {
+ return (uint16_t)index;
+ }
+ }
+
+ return HC_ERROR;
+}
+
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_int.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_int.c
new file mode 100644
index 0000000000000000000000000000000000000000..0d7c8c043a25a2d2b1ed17fc876d50309effb40c
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_int.c
@@ -0,0 +1,609 @@
+/*!
+ \file usbh_int.c
+ \brief USB host mode interrupt handler file
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "usb_core.h"
+#include "usb_defines.h"
+#include "usbh_int.h"
+
+static uint32_t usbh_intf_sof (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_port (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_hc (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_hc_in (usb_core_handle_struct *pudev, uint8_t channel_num);
+static uint32_t usbh_intf_hc_out (usb_core_handle_struct *pudev, uint8_t channel_num);
+static uint32_t usbh_intf_rxfifo_noempty (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_nptxfifo_empty (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_ptxfifo_empty (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_disconnect (usb_core_handle_struct *pudev);
+static uint32_t usbh_intf_iso_incomplete_xfer (usb_core_handle_struct *pudev);
+
+/*!
+ \brief handle global host interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+uint32_t usbh_isr (usb_core_handle_struct *pudev)
+{
+ uint32_t retval = 0U;
+ uint32_t int_flag = 0U;
+
+ /* check if host mode */
+ if (USB_CURRENT_MODE_GET() == HOST_MODE) {
+ USB_CORE_INTR_READ(int_flag);
+
+ if (!int_flag) {
+ return 0U;
+ }
+
+ /* start of frame interrupt handle */
+ if (int_flag & GINTF_SOF) {
+ retval |= usbh_intf_sof (pudev);
+ }
+
+ /* Rx FIFO non-empty interrupt handle */
+ if (int_flag & GINTF_RXFNEIF) {
+ retval |= usbh_intf_rxfifo_noempty (pudev);
+ }
+
+ /* Non-Periodic Tx FIFO empty interrupt hanlde */
+ if (int_flag & GINTF_NPTXFEIF) {
+ retval |= usbh_intf_nptxfifo_empty (pudev);
+ }
+
+ /* periodic Tx FIFO empty interrupt handle */
+ if (int_flag & GINTF_PTXFEIF) {
+ retval |= usbh_intf_ptxfifo_empty (pudev);
+ }
+
+ /* host channels interrupt handle */
+ if (int_flag & GINTF_HCIF) {
+ retval |= usbh_intf_hc (pudev);
+ }
+
+ /* host port interrupt handle */
+ if (int_flag & GINTF_HPIF) {
+ retval |= usbh_intf_port (pudev);
+ }
+
+ /* disconnect interrupt handle */
+ if (int_flag & GINTF_DISCIF) {
+ retval |= usbh_intf_disconnect (pudev);
+ }
+
+ /* isochronous IN transfer not complete interrupt handle */
+ if (int_flag & GINTF_ISOONCIF) {
+ retval |= usbh_intf_iso_incomplete_xfer (pudev);
+ }
+ }
+
+ return retval;
+}
+
+/*!
+ \brief handle the start-of-frame interrupt in host mode
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbh_intf_sof (usb_core_handle_struct *pudev)
+{
+ usbh_hcd_int_fops->sof(pudev);
+
+ /* clear interrupt */
+ USB_GINTF = GINTF_SOF;
+
+ return 1U;
+}
+
+/*!
+ \brief handle all host channels interrupt in host mode
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbh_intf_hc (usb_core_handle_struct *pudev)
+{
+ uint8_t i = 0U;
+ uint32_t retval = 0U;
+
+ for (i = 0U; i < pudev->cfg.host_channel_num; i++) {
+ if ((USB_HACHINT & HACHINT_HACHINT) & ((uint32_t)1U << i)) {
+ if ((USB_HCHxCTL((uint16_t)i) & HCHCTL_EPDIR) >> 15U) {
+ retval |= usbh_intf_hc_in (pudev, i);
+ } else {
+ retval |= usbh_intf_hc_out (pudev, i);
+ }
+ }
+ }
+
+ return retval;
+}
+
+/*!
+ \brief handle the disconnect interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbh_intf_disconnect (usb_core_handle_struct *pudev)
+{
+ usbh_hcd_int_fops->device_disconnected(pudev);
+
+ /* clear interrupt */
+ USB_GINTF = GINTF_DISCIF;
+
+ return 1U;
+}
+
+/*!
+ \brief handle the non-periodic tx fifo empty interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbh_intf_nptxfifo_empty (usb_core_handle_struct *pudev)
+{
+ uint8_t channel_num = 0U;
+ uint32_t dword_len = 0U, len = 0U;
+ usb_hostchannel_struct *puhc;
+
+ channel_num = (uint8_t)((USB_HNPTFQSTAT & HNPTFQSTAT_CNUM) >> 27U);
+ puhc = &pudev->host.host_channel[channel_num];
+ dword_len = (puhc->xfer_len + 3U) / 4U;
+
+ while (((USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS) > dword_len) && (0U != puhc->xfer_len)) {
+ len = (USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS) * 4U;
+
+ if (len > puhc->xfer_len) {
+ /* last packet */
+ len = (uint16_t)puhc->xfer_len;
+
+ USB_GINTEN &= ~GINTF_NPTXFEIF;
+
+ }
+
+ dword_len = (puhc->xfer_len + 3U) / 4U;
+ usb_fifo_write (puhc->xfer_buff, channel_num, (uint16_t)len);
+
+ puhc->xfer_buff += len;
+ puhc->xfer_len -= len;
+ puhc->xfer_count += len;
+ }
+
+ return 1U;
+}
+
+/*!
+ \brief handle the periodic tx fifo empty interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbh_intf_ptxfifo_empty (usb_core_handle_struct *pudev)
+{
+ uint8_t channel_num = 0U;
+ uint32_t dword_len = 0U, len = 0U;
+ usb_hostchannel_struct *puhc;
+
+ channel_num = (uint8_t)((USB_HPTFQSTAT & HPTFQSTAT_CNUM) >> 27U);
+ puhc = &pudev->host.host_channel[channel_num];
+ dword_len = (puhc->xfer_len + 3U) / 4U;
+
+ while (((USB_HPTFQSTAT & HPTFQSTAT_PTXFS) > dword_len) && (0U != puhc->xfer_len)) {
+ len = (USB_HPTFQSTAT & HPTFQSTAT_PTXFS) * 4U;
+
+ if (len > puhc->xfer_len) {
+ len = puhc->xfer_len;
+
+ /* last packet */
+ USB_GINTEN &= ~GINTF_PTXFEIF;
+ }
+
+ dword_len = (puhc->xfer_len + 3U) / 4U;
+ usb_fifo_write (puhc->xfer_buff, channel_num, (uint16_t)len);
+
+ puhc->xfer_buff += len;
+ puhc->xfer_len -= len;
+ puhc->xfer_count += len;
+ }
+
+ return 1U;
+}
+
+/*!
+ \brief handle the host port interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbh_intf_port (usb_core_handle_struct *pudev)
+{
+ uint8_t port_speed = 0U;
+ uint8_t port_reset = 0U;
+ uint32_t retval = 0U;
+ __IO uint32_t hostportdup = USB_HPCS;
+
+ /* clear the interrupt bits in gintsts */
+ hostportdup &= ~HPCS_PE;
+ hostportdup &= ~HPCS_PCD;
+ hostportdup &= ~HPCS_PEDC;
+
+ /* port connect detected */
+ if (USB_HPCS & HPCS_PCD) {
+ hostportdup |= HPCS_PCD;
+ usbh_hcd_int_fops->device_connected(pudev);
+ retval |= 1U;
+ }
+
+ /* port enable changed */
+ if (USB_HPCS & HPCS_PEDC) {
+ hostportdup |= HPCS_PEDC;
+
+ if (USB_HPCS & HPCS_PE) {
+ port_speed = (uint8_t)((USB_HPCS & HPCS_PS) >> 17U);
+
+ if (HPRT_PRTSPD_LOW_SPEED == port_speed) {
+ USB_HFT = 6000U;
+
+ if (HCTLR_6_MHZ != (USB_HCTL & HCTL_CLKSEL)) {
+ if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) {
+ USB_FSLSCLOCK_INIT(HCTLR_6_MHZ);
+ }
+ port_reset = 1U;
+ }
+ } else if(HPRT_PRTSPD_FULL_SPEED == port_speed) {
+ USB_HFT = 48000U;
+
+ if (HCTLR_48_MHZ != (USB_HCTL & HCTL_CLKSEL)) {
+ if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) {
+ USB_FSLSCLOCK_INIT(HCTLR_48_MHZ);
+ }
+ port_reset = 1U;
+ }
+ } else {
+ /* for high speed device and others */
+ port_reset = 1U;
+ }
+ }
+ }
+
+ if (port_reset) {
+ usb_port_reset(pudev);
+ }
+
+ /* clear port interrupts */
+ USB_HPCS = hostportdup;
+
+ return retval;
+}
+
+/*!
+ \brief handle the OUT channel interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[in] channel_num: host channel number which is in (0..7)
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbh_intf_hc_out (usb_core_handle_struct *pudev, uint8_t channel_num)
+{
+ uint32_t channel_intr = USB_HCHxINTF((uint16_t)channel_num);
+ usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
+
+ channel_intr &= USB_HCHxINTEN((uint16_t)channel_num);
+
+ if (channel_intr & HCHINTF_ACK) {
+ if (URB_PING == puhc->urb_state) {
+ puhc->err_count = 0U;
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ usb_hostchannel_halt(pudev, channel_num);
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF;
+ puhc->status = HC_XF;
+ }
+
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_ACK;
+ } else if (channel_intr & HCHINTF_REQOVR) {
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ usb_hostchannel_halt(pudev, channel_num);
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_REQOVR;
+ } else if (channel_intr & HCHINTF_TF) {
+ puhc->err_count = 0U;
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ usb_hostchannel_halt(pudev, channel_num);
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF;
+ puhc->status = HC_XF;
+ } else if (channel_intr & HCHINTF_STALL) {
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_STALL;
+ usb_hostchannel_halt(pudev, channel_num);
+ puhc->status = HC_STALL;
+ } else if (channel_intr & HCHINTF_NAK) {
+ puhc->err_count = 0U;
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ usb_hostchannel_halt(pudev, channel_num);
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
+ puhc->status = HC_NAK;
+ } else if (channel_intr & HCHINTF_USBER) {
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ usb_hostchannel_halt(pudev, channel_num);
+ puhc->err_count ++;
+ puhc->status = HC_TRACERR;
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_USBER;
+ } else if (channel_intr & HCHINTF_NYET) {
+ puhc->err_count = 0U;
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ puhc->status = HC_NYET;
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NYET;
+ } else if (channel_intr & HCHINTF_DTER) {
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ usb_hostchannel_halt(pudev, channel_num);
+ puhc->status= HC_DTGERR;
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_DTER;
+ } else if (channel_intr & HCHINTF_CH) {
+ USB_HCHxINTEN((uint16_t)channel_num) &= ~HCHINTEN_CHIE;
+
+ switch (puhc->status) {
+ case HC_XF:
+ puhc->urb_state = URB_DONE;
+
+ if (USB_EPTYPE_BULK == ((USB_HCHxCTL((uint16_t)channel_num) & HCHCTL_EPTYPE) >> 18)) {
+ puhc->data_tg_out ^= 1U;
+ }
+ break;
+ case HC_NAK:
+ puhc->urb_state = URB_NOTREADY;
+ break;
+ case HC_NYET:
+ break;
+ case HC_STALL:
+ puhc->urb_state = URB_STALL;
+ break;
+ case HC_TRACERR:
+ if (3U == puhc->err_count) {
+ puhc->urb_state = URB_ERROR;
+ puhc->err_count = 0U;
+ }
+ break;
+ default:
+ break;
+ }
+
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_CH;
+ } else {
+ /* no operation */
+ }
+
+ return 1U;
+}
+
+/*!
+ \brief handle the IN channel interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[in] channel_num: host channel number which is in (0..7)
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbh_intf_hc_in (usb_core_handle_struct *pudev, uint8_t channel_num)
+{
+ uint8_t endp_type = 0U;
+ usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
+
+ uint32_t channle_intf = USB_HCHxINTF((uint16_t)channel_num);
+ __IO uint32_t channel_ctrl = USB_HCHxCTL((uint16_t)channel_num);
+
+ channle_intf &= USB_HCHxINTEN((uint16_t)channel_num);
+
+ endp_type = (uint8_t)((channel_ctrl & HCHCTL_EPTYPE) >> 18U);
+
+ if (channle_intf & HCHINTF_ACK) {
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_ACK;
+ } else if (channle_intf & HCHINTF_STALL) {
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ puhc->status = HC_STALL;
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_STALL;
+
+ /* NOTE: When there is a 'stall', reset also nak,
+ else, the pudev->host.status = HC_STALL
+ will be overwritten by 'nak' in code below */
+ channle_intf &= ~HCHINTF_NAK;
+
+ usb_hostchannel_halt(pudev, channel_num);
+ } else if (channle_intf & HCHINTF_DTER) {
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ usb_hostchannel_halt(pudev, channel_num);
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
+ puhc->status = HC_DTGERR;
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_DTER;
+ } else {
+ /* no operation */
+ }
+
+ if (channle_intf & HCHINTF_REQOVR) {
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ usb_hostchannel_halt(pudev, channel_num);
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_REQOVR;
+ } else if (channle_intf & HCHINTF_TF) {
+ puhc->status = HC_XF;
+ puhc->err_count = 0U;
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF;
+
+ if ((USB_EPTYPE_CTRL == endp_type) || (USB_EPTYPE_BULK == endp_type)) {
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ usb_hostchannel_halt(pudev, channel_num);
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
+ puhc->data_tg_in ^= 1U;
+ } else if (USB_EPTYPE_INTR == endp_type) {
+ channel_ctrl |= HCHCTL_ODDFRM;
+ USB_HCHxCTL((uint16_t)channel_num) = channel_ctrl;
+ puhc->urb_state = URB_DONE;
+ } else {
+ /* no operation */
+ }
+ } else if (channle_intf & HCHINTF_CH) {
+ USB_HCHxINTEN((uint16_t)channel_num) &= ~HCHINTEN_CHIE;
+
+ switch (puhc->status) {
+ case HC_XF:
+ puhc->urb_state = URB_DONE;
+ break;
+ case HC_TRACERR:
+ case HC_DTGERR:
+ puhc->err_count = 0U;
+ puhc->urb_state = URB_ERROR;
+ break;
+ case HC_STALL:
+ puhc->urb_state = URB_STALL;
+ break;
+ default:
+ if (USB_EPTYPE_INTR == endp_type) {
+ puhc->data_tg_in ^= 1U;
+ }
+ break;
+ }
+
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_CH;
+ } else if (channle_intf & HCHINTF_USBER) {
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ (puhc->err_count)++;
+ puhc->status = HC_TRACERR;
+ usb_hostchannel_halt(pudev, channel_num);
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_USBER;
+ } else if (channle_intf & HCHINTF_NAK) {
+ if (USB_EPTYPE_INTR == endp_type) {
+ USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
+ usb_hostchannel_halt(pudev, channel_num);
+ } else if ((USB_EPTYPE_CTRL == endp_type) || (USB_EPTYPE_BULK == endp_type)) {
+ /* re-activate the channel */
+ channel_ctrl |= HCHCTL_CEN;
+ channel_ctrl &= ~HCHCTL_CDIS;
+ USB_HCHxCTL((uint16_t)channel_num) = channel_ctrl;
+ } else {
+ /* no operation */
+ }
+
+ puhc->status = HC_NAK;
+ USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
+ } else {
+ /* no operation */
+ }
+
+ return 1U;
+}
+
+/*!
+ \brief handle the rx fifo non-empty interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbh_intf_rxfifo_noempty (usb_core_handle_struct *pudev)
+{
+ uint32_t count = 0U;
+ __IO uint8_t channel_num = 0U;
+ __IO uint32_t rx_status = 0U;
+ uint32_t usbh_ch_ctl_reg = 0U;
+ usb_hostchannel_struct *puhc;
+
+ /* disable the Rx status queue level interrupt */
+ USB_GINTEN &= ~GINTF_RXFNEIF;
+
+ rx_status = USB_GRSTATP;
+ channel_num = (uint8_t)(rx_status & GRSTATRP_CNUM);
+ puhc = &pudev->host.host_channel[channel_num];
+
+ switch ((rx_status & GRSTATRP_RPCKST) >> 17) {
+ case GRSTATR_RPCKST_IN:
+ count = (rx_status & GRSTATRP_BCOUNT) >> 4;
+
+ /* read the data into the host buffer. */
+ if ((count > 0U) && (puhc->xfer_buff != (void *)0)) {
+ usb_fifo_read(puhc->xfer_buff, (uint16_t)count);
+
+ /* manage multiple Xfer */
+ puhc->xfer_buff += count;
+ puhc->xfer_count += count;
+
+ if (USB_HCHxLEN((uint16_t)channel_num) & HCHLEN_PCNT) {
+ /* re-activate the channel when more packets are expected */
+ usbh_ch_ctl_reg = USB_HCHxCTL((uint16_t)channel_num);
+ usbh_ch_ctl_reg |= HCHCTL_CEN;
+ usbh_ch_ctl_reg &= ~HCHCTL_CDIS;
+ USB_HCHxCTL((uint16_t)channel_num) = usbh_ch_ctl_reg;
+ }
+ }
+ break;
+ case GRSTATR_RPCKST_IN_XFER_COMP:
+ break;
+ case GRSTATR_RPCKST_DATA_TOGGLE_ERR:
+ count = (rx_status & GRSTATRP_BCOUNT) >> 4;
+
+ while (count > 0) {
+ rx_status = USB_GRSTATP;
+ count--;
+ }
+ break;
+ case GRSTATR_RPCKST_CH_HALTED:
+ break;
+ default:
+ break;
+ }
+
+ /* enable the Rx status queue level interrupt */
+ USB_GINTEN |= GINTF_RXFNEIF;
+
+ return 1U;
+}
+
+/*!
+ \brief handle the incomplete periodic transfer interrupt
+ \param[in] pudev: pointer to usb device instance
+ \param[out] none
+ \retval operation status
+*/
+static uint32_t usbh_intf_iso_incomplete_xfer (usb_core_handle_struct *pudev)
+{
+ __IO uint32_t gint_flag = 0U;
+
+ gint_flag = USB_HCHxCTL(0U);
+ USB_HCHxCTL(0U) = 0U;
+
+ gint_flag = 0U;
+
+ /* clear interrupt */
+ gint_flag |= GINTF_ISOONCIF;
+ USB_GINTF = gint_flag;
+
+ return 1U;
+}
diff --git a/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_std.c b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_std.c
new file mode 100644
index 0000000000000000000000000000000000000000..04adcfabc61bf6fb14f7a6e08f246d715dd5680d
--- /dev/null
+++ b/bsp/gd32350r-eval/Libraries/GD32F3x0_usbfs_driver/Source/usbh_std.c
@@ -0,0 +1,831 @@
+/*!
+ \file usbh_std.c
+ \brief USB 2.0 standard function definition
+
+ \version 2017-06-06, V1.0.0, firmware for GD32F3x0
+ \version 2019-06-01, V2.0.0, firmware for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 "usbh_core.h"
+#include "usbh_usr.h"
+#include "usbh_std.h"
+#include "usbh_ctrl.h"
+
+uint8_t local_buffer[64];
+uint8_t usbh_cfg_desc[512];
+uint8_t enum_polling_handle_flag = 0U;
+
+static void enum_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_full_dev_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_set_addr_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_cfg_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_full_cfg_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_mfc_string_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_product_string_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_get_serialnum_string_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_set_configuration_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+static void enum_dev_configured_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
+
+/* the enumeration state handle function array */
+void (*enum_state_handle[]) (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate) =
+{
+ enum_idle_handle,
+ enum_set_addr_handle,
+ enum_get_full_dev_desc_handle,
+ enum_get_cfg_desc_handle,
+ enum_get_full_cfg_desc_handle,
+ enum_get_mfc_string_desc_handle,
+ enum_get_product_string_desc_handle,
+ enum_get_serialnum_string_desc_handle,
+ enum_set_configuration_handle,
+ enum_dev_configured_handle,
+};
+
+/* the enumeration state handle table */
+state_table_struct enum_handle_table[ENUM_HANDLE_TABLE_SIZE] =
+{
+ /* the current state the current event the next state the event function */
+ {ENUM_IDLE, ENUM_EVENT_SET_ADDR, ENUM_SET_ADDR, only_state_move },
+ {ENUM_SET_ADDR, ENUN_EVENT_GET_FULL_DEV_DESC, ENUM_GET_FULL_DEV_DESC, only_state_move },
+ {ENUM_GET_FULL_DEV_DESC, ENUN_EVENT_GET_CFG_DESC, ENUM_GET_CFG_DESC, only_state_move },
+ {ENUM_GET_CFG_DESC, ENUN_EVENT_GET_FULL_CFG_DESC, ENUM_GET_FULL_CFG_DESC, only_state_move },
+ {ENUM_GET_FULL_CFG_DESC, ENUN_EVENT_GET_MFC_STRING_DESC, ENUM_GET_MFC_STRING_DESC, only_state_move },
+ {ENUM_GET_MFC_STRING_DESC, ENUN_EVENT_GET_PRODUCT_STRING_DESC, ENUM_GET_PRODUCT_STRING_DESC, only_state_move },
+ {ENUM_GET_PRODUCT_STRING_DESC, ENUN_EVENT_GET_SERIALNUM_STRING_DESC, ENUM_GET_SERIALNUM_STRING_DESC, only_state_move },
+ {ENUM_GET_SERIALNUM_STRING_DESC, ENUN_EVENT_SET_CONFIGURATION, ENUM_SET_CONFIGURATION, only_state_move },
+ {ENUM_SET_CONFIGURATION, ENUN_EVENT_DEV_CONFIGURED, ENUM_DEV_CONFIGURED, only_state_move },
+ {ENUM_DEV_CONFIGURED, GO_TO_UP_STATE_EVENT, UP_STATE, goto_up_state_fun },
+};
+
+/*!
+ \brief the polling function of enumeration state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval usb host status
+*/
+usbh_status_enum enum_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
+{
+ usbh_status_enum exe_state = USBH_BUSY;
+ usbh_state_handle_struct *p_state;
+ p_state = (usbh_state_handle_struct *)pustate;
+
+ if (0U == enum_polling_handle_flag) {
+ enum_polling_handle_flag = 1U;
+ scd_table_push(p_state);
+ scd_state_move(p_state, ENUM_IDLE);
+ }
+
+ /* start the enumeration state handle */
+ scd_begin(p_state,ENUM_FSM_ID);
+
+ if (0 == p_state->usbh_current_state_stack_top) {
+ enum_state_handle[p_state->usbh_current_state](pudev, puhost, p_state);
+ } else {
+ enum_state_handle[p_state->stack[1].state](pudev, puhost, p_state);
+ }
+
+ /* determine the enumeration whether to complete */
+ if (ENUM_DEV_CONFIGURED == puhost->usbh_backup_state.enum_backup_state) {
+ puhost->usbh_backup_state.enum_backup_state = ENUM_IDLE;
+ enum_polling_handle_flag = 0U;
+ exe_state = USBH_OK;
+ }
+
+ return exe_state;
+}
+
+/*!
+ \brief the handle function of ENUM_IDLE state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval none
+*/
+static void enum_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.enum_backup_state = ENUM_IDLE;
+
+ if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+ usbh_enum_desc_get(pudev,
+ puhost,
+ pudev->host.rx_buffer,
+ USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
+ USB_DEVDESC,
+ 8U);
+ if ((void *)0 != pudev->mdelay) {
+ pudev->mdelay(100U);
+ }
+ }
+
+ if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+ usbh_device_desc_parse(&puhost->device.dev_desc, pudev->host.rx_buffer, 8U);
+ puhost->control.ep0_size = puhost->device.dev_desc.bMaxPacketSize0;
+
+ /* issue reset */
+ usb_port_reset(pudev);
+
+ /* modify control channels configuration for maxpacket size */
+ usbh_channel_modify (pudev,
+ puhost->control.hc_out_num,
+ 0U,
+ 0U,
+ 0U,
+ (uint16_t)puhost->control.ep0_size);
+
+ usbh_channel_modify (pudev,
+ puhost->control.hc_in_num,
+ 0U,
+ 0U,
+ 0U,
+ (uint16_t)puhost->control.ep0_size);
+
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUM_EVENT_SET_ADDR,
+ pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of ENUM_GET_FULL_DEV_DESC state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval none
+*/
+static void enum_get_full_dev_desc_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.enum_backup_state = ENUM_GET_FULL_DEV_DESC;
+
+ if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+ usbh_enum_desc_get(pudev,
+ puhost,
+ pudev->host.rx_buffer,
+ USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
+ USB_DEVDESC,
+ USB_DEVDESC_SIZE);
+ }
+
+ if(USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)){
+ usbh_device_desc_parse(&puhost->device.dev_desc, pudev->host.rx_buffer, USB_DEVDESC_SIZE);
+ puhost->usr_cb->device_desc_available(&puhost->device.dev_desc);
+
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUN_EVENT_GET_CFG_DESC,
+ pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of ENUM_SET_ADDR state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval none
+*/
+static void enum_set_addr_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.enum_backup_state = ENUM_SET_ADDR;
+
+ if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+ usbh_enum_addr_set(pudev, puhost,USBH_DEVICE_ADDRESS);
+ if ((void *)0 != pudev->mdelay) {
+ pudev->mdelay(100U);
+ }
+ }
+
+ if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+ if ((void *)0 != pudev->mdelay) {
+ pudev->mdelay(2U);
+ }
+ puhost->device.address = USBH_DEVICE_ADDRESS;
+
+ /* user callback for device address assigned */
+ puhost->usr_cb->device_address_set();
+
+ /* modify control channels to update device address */
+ usbh_channel_modify (pudev,
+ puhost->control.hc_in_num,
+ puhost->device.address,
+ 0U,
+ 0U,
+ 0U);
+
+ usbh_channel_modify (pudev,
+ puhost->control.hc_out_num,
+ puhost->device.address,
+ 0U,
+ 0U,
+ 0U);
+
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUN_EVENT_GET_FULL_DEV_DESC,
+ pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of ENUM_GET_CFG_DESC state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval none
+*/
+static void enum_get_cfg_desc_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ uint16_t index = 0U;
+
+ puhost->usbh_backup_state.enum_backup_state = ENUM_GET_CFG_DESC;
+
+ if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+ usbh_enum_desc_get(pudev,
+ puhost,
+ pudev->host.rx_buffer,
+ USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
+ USB_CFGDESC,
+ USB_CFGDESC_SIZE);
+ }
+
+ if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+ /* save configuration descriptor for class parsing usage */
+ for (; index < USB_CFGDESC_SIZE; index ++) {
+ usbh_cfg_desc[index] = pudev->host.rx_buffer[index];
+ }
+
+ /* commands successfully sent and response received */
+ usbh_cfg_desc_parse (&puhost->device.cfg_desc,
+ puhost->device.itf_desc,
+ puhost->device.ep_desc,
+ pudev->host.rx_buffer,
+ USB_CFGDESC_SIZE);
+
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUN_EVENT_GET_FULL_CFG_DESC,
+ pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of ENUM_GET_FULL_CFG_DESC state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval none
+*/
+static void enum_get_full_cfg_desc_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+
+ uint16_t index = 0U;
+
+ puhost->usbh_backup_state.enum_backup_state = ENUM_GET_FULL_CFG_DESC;
+
+ if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+ usbh_enum_desc_get (pudev, puhost, pudev->host.rx_buffer,
+ USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
+ USB_CFGDESC, puhost->device.cfg_desc.wTotalLength);
+ }
+
+
+ if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+ /* save configuration descriptor for class parsing usage */
+ for (; index < puhost->device.cfg_desc.wTotalLength; index ++) {
+ usbh_cfg_desc[index] = pudev->host.rx_buffer[index];
+ }
+
+ /* commands successfully sent and response received */
+ usbh_cfg_desc_parse (&puhost->device.cfg_desc,
+ puhost->device.itf_desc,
+ puhost->device.ep_desc,
+ pudev->host.rx_buffer,
+ puhost->device.cfg_desc.wTotalLength);
+
+ /* User callback for configuration descriptors available */
+ puhost->usr_cb->configuration_desc_available(&puhost->device.cfg_desc,
+ puhost->device.itf_desc,
+ puhost->device.ep_desc[0]);
+
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUN_EVENT_GET_MFC_STRING_DESC,
+ pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of ENUM_GET_MFC_STRING_DESC state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval none
+*/
+static void enum_get_mfc_string_desc_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.enum_backup_state = ENUM_GET_MFC_STRING_DESC;
+
+ if (0U != puhost->device.dev_desc.iManufacturer) {
+ if(CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+ usbh_enum_desc_get(pudev,
+ puhost,
+ pudev->host.rx_buffer,
+ USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
+ USB_STRDESC | puhost->device.dev_desc.iManufacturer,
+ 0xffU);
+ }
+
+ if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+ usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU);
+ puhost->usr_cb->manufacturer_string(local_buffer);
+
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUN_EVENT_GET_PRODUCT_STRING_DESC,
+ pustate->usbh_current_state);
+ }
+ } else {
+ puhost->usr_cb->manufacturer_string("N/A");
+ scd_state_move((usbh_state_handle_struct *)pustate, ENUM_GET_PRODUCT_STRING_DESC);
+ }
+}
+
+/*!
+ \brief the handle function of ENUM_GET_PRODUCT_STRING_DESC state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval none
+*/
+static void enum_get_product_string_desc_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.enum_backup_state = ENUM_GET_PRODUCT_STRING_DESC;
+
+ if (0U != puhost->device.dev_desc.iProduct) {
+ if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+ usbh_enum_desc_get(pudev,
+ puhost,
+ pudev->host.rx_buffer,
+ USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
+ USB_STRDESC | puhost->device.dev_desc.iProduct,
+ 0xffU);
+ }
+
+ if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+ usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU);
+
+ /* user callback for product string */
+ puhost->usr_cb->product_string(local_buffer);
+
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUN_EVENT_GET_SERIALNUM_STRING_DESC,
+ pustate->usbh_current_state);
+ }
+ } else {
+ puhost->usr_cb->product_string("N/A");
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUN_EVENT_GET_SERIALNUM_STRING_DESC,
+ pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of ENUM_GET_SERIALNUM_STRING_DESC state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval none
+*/
+static void enum_get_serialnum_string_desc_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.enum_backup_state = ENUM_GET_SERIALNUM_STRING_DESC;
+
+ if (0U != puhost->device.dev_desc.iSerialNumber) {
+ if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
+ usbh_enum_desc_get(pudev,
+ puhost,
+ pudev->host.rx_buffer,
+ USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
+ USB_STRDESC | puhost->device.dev_desc.iSerialNumber,
+ 0xffU);
+ }
+
+ if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)){
+ usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU);
+
+ /* user callback for product string */
+ puhost->usr_cb->serial_num_string(local_buffer);
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUN_EVENT_SET_CONFIGURATION,
+ pustate->usbh_current_state);
+ }
+ } else {
+ puhost->usr_cb->serial_num_string("N/A");
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUN_EVENT_SET_CONFIGURATION,
+ pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of ENUM_SET_CONFIGURATION state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval none
+*/
+static void enum_set_configuration_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.enum_backup_state = ENUM_SET_CONFIGURATION;
+
+ if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state ) {
+ usbh_enum_cfg_set(pudev, puhost, (uint16_t)puhost->device.cfg_desc.bConfigurationValue);
+ }
+
+ if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
+ scd_event_handle(pudev,
+ puhost,
+ pustate,
+ ENUN_EVENT_DEV_CONFIGURED,
+ pustate->usbh_current_state);
+ }
+}
+
+/*!
+ \brief the handle function of ENUM_DEV_CONFIGURED state
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] pustate: pointer to USB state driver
+ \param[out] none
+ \retval none
+*/
+static void enum_dev_configured_handle (usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ usbh_state_handle_struct *pustate)
+{
+ puhost->usbh_backup_state.enum_backup_state = ENUM_DEV_CONFIGURED;
+ scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state);
+}
+
+/*!
+ \brief get descriptor in usb host enumeration stage
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] buf: buffer to store the descriptor
+ \param[in] ReqType: descriptor type
+ \param[in] ValueIdx: wValue for the GetDescriptr request
+ \param[in] Len: length of the descriptor
+ \param[out] none
+ \retval none
+*/
+void usbh_enum_desc_get(usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ uint8_t *buf,
+ uint8_t req_type,
+ uint16_t value_idx,
+ uint16_t len)
+{
+ usb_setup_union *pSetup = &(puhost->control.setup);
+
+ pSetup->b.bmRequestType = USB_DIR_IN | req_type;
+ pSetup->b.bRequest = USBREQ_GET_DESCRIPTOR;
+ pSetup->b.wValue = value_idx;
+
+ if (USB_STRDESC == (value_idx & 0xff00U)){
+ pSetup->b.wIndex = 0x0409U;
+ } else {
+ pSetup->b.wIndex = 0U;
+ }
+
+ pSetup->b.wLength = len;
+
+ puhost->control.buff = buf;
+ puhost->control.length = len;
+
+}
+
+/*!
+ \brief set address in usb host enumeration stage
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] device_address: the device address
+ \param[out] none
+ \retval none
+*/
+void usbh_enum_addr_set(usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ uint8_t device_address)
+{
+ usb_setup_union *p_setup = &(puhost->control.setup);
+
+ p_setup->b.bmRequestType = USB_DIR_OUT | USB_REQTYPE_DEVICE | USB_STANDARD_REQ;
+ p_setup->b.bRequest = USBREQ_SET_ADDRESS;
+ p_setup->b.wValue = (uint16_t)device_address;
+ p_setup->b.wIndex = 0U;
+ p_setup->b.wLength = 0U;
+ puhost->control.buff = 0U;
+ puhost->control.length = 0U;
+}
+
+/*!
+ \brief set configuration in usb host enumeration stage
+ \param[in] pudev: pointer to USB device
+ \param[in] puhost: pointer to USB host
+ \param[in] cfg_idx: the index of the configuration
+ \param[out] none
+ \retval none
+*/
+void usbh_enum_cfg_set(usb_core_handle_struct *pudev,
+ usbh_host_struct *puhost,
+ uint16_t cfg_idx)
+{
+ usb_setup_union *p_setup = &(puhost->control.setup);
+
+ p_setup->b.bmRequestType = USB_DIR_OUT | USB_REQTYPE_DEVICE | USB_STANDARD_REQ;
+ p_setup->b.bRequest = USBREQ_SET_CONFIGURATION;
+ p_setup->b.wValue = cfg_idx;
+ p_setup->b.wIndex = 0U;
+ p_setup->b.wLength = 0U;
+ puhost->control.buff = 0;
+ puhost->control.length = 0U;
+}
+
+/*!
+ \brief parse the device descriptor
+ \param[in] dev_desc: device_descriptor destinaton address
+ \param[in] buf: buffer where the source descriptor is available
+ \param[in] len: length of the descriptor
+ \param[out] none
+ \retval none
+*/
+void usbh_device_desc_parse (usb_descriptor_device_struct *dev_desc, uint8_t *buf, uint16_t len)
+{
+ dev_desc->Header.bLength = *(uint8_t *)(buf + 0);
+ dev_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
+ dev_desc->bcdUSB = SWAPBYTE(buf + 2);
+ dev_desc->bDeviceClass = *(uint8_t *)(buf + 4);
+ dev_desc->bDeviceSubClass = *(uint8_t *)(buf + 5);
+ dev_desc->bDeviceProtocol = *(uint8_t *)(buf + 6);
+ dev_desc->bMaxPacketSize0 = *(uint8_t *)(buf + 7);
+
+ if (len > 8U){
+ /* for 1st time after device connection, host may issue only 8 bytes for device descriptor length */
+ dev_desc->idVendor = SWAPBYTE(buf + 8);
+ dev_desc->idProduct = SWAPBYTE(buf + 10);
+ dev_desc->bcdDevice = SWAPBYTE(buf + 12);
+ dev_desc->iManufacturer = *(uint8_t *)(buf + 14);
+ dev_desc->iProduct = *(uint8_t *)(buf + 15);
+ dev_desc->iSerialNumber = *(uint8_t *)(buf + 16);
+ dev_desc->bNumberConfigurations = *(uint8_t *)(buf + 17);
+ }
+}
+
+/*!
+ \brief parse the configuration descriptor
+ \param[in] cfg_desc: configuration descriptor address
+ \param[in] itf_desc: interface descriptor address
+ \param[in] ep_desc: endpoint descriptor address
+ \param[in] buf: buffer where the source descriptor is available
+ \param[in] len: length of the descriptor
+ \param[out] none
+ \retval none
+*/
+void usbh_cfg_desc_parse (usb_descriptor_configuration_struct *cfg_desc,
+ usb_descriptor_interface_struct *itf_desc,
+ usb_descriptor_endpoint_struct ep_desc[][USBH_MAX_EP_NUM],
+ uint8_t *buf,
+ uint16_t len)
+{
+ usb_descriptor_interface_struct *pitf = NULL;
+ usb_descriptor_interface_struct temp_pitf;
+ usb_descriptor_endpoint_struct *pep = NULL;
+ usb_descriptor_header_struct *pdesc = (usb_descriptor_header_struct *)buf;
+
+ uint8_t itf_ix = 0U;
+ uint8_t ep_ix = 0U;
+ uint16_t ptr = 0U;
+ static uint8_t prev_itf = 0U;
+ static uint16_t prev_ep_size = 0U;
+
+ /* parse configuration descriptor */
+ cfg_desc->Header.bLength = *(uint8_t *)(buf + 0);
+ cfg_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
+ cfg_desc->wTotalLength = SWAPBYTE(buf + 2);
+ cfg_desc->bNumInterfaces = *(uint8_t *)(buf + 4);
+ cfg_desc->bConfigurationValue = *(uint8_t *)(buf + 5);
+ cfg_desc->iConfiguration = *(uint8_t *)(buf + 6);
+ cfg_desc->bmAttributes = *(uint8_t *)(buf + 7);
+ cfg_desc->bMaxPower = *(uint8_t *)(buf + 8);
+
+ if (len > USB_CFGDESC_SIZE) {
+ ptr = USB_CFG_DESC_LEN;
+
+ if (cfg_desc->bNumInterfaces <= USBH_MAX_INTERFACES_NUM) {
+ pitf = (usb_descriptor_interface_struct *)0;
+
+ for (; ptr < cfg_desc->wTotalLength; ) {
+ pdesc = usbh_next_desc_get((uint8_t *)pdesc, &ptr);
+
+ if (USB_DESCTYPE_INTERFACE == pdesc->bDescriptorType) {
+ itf_ix = *((uint8_t *)pdesc + 2U);
+ pitf = &itf_desc[itf_ix];
+
+ if (*((uint8_t *)pdesc + 3U) < 3U) {
+ usbh_interface_desc_parse (&temp_pitf, (uint8_t *)pdesc);
+
+ /* parse endpoint descriptors relative to the current interface */
+ if (temp_pitf.bNumEndpoints <= USBH_MAX_EP_NUM) {
+ for (ep_ix = 0U; ep_ix < temp_pitf.bNumEndpoints;) {
+ pdesc = usbh_next_desc_get((void* )pdesc, &ptr);
+
+ if (USB_DESCTYPE_ENDPOINT == pdesc->bDescriptorType) {
+ pep = &ep_desc[itf_ix][ep_ix];
+
+ if (prev_itf != itf_ix) {
+ prev_itf = itf_ix;
+ usbh_interface_desc_parse (pitf, (uint8_t *)&temp_pitf);
+ } else {
+ if (prev_ep_size > SWAPBYTE((uint8_t *)pdesc + 4)) {
+ break;
+ } else {
+ usbh_interface_desc_parse (pitf, (uint8_t *)&temp_pitf);
+ }
+ }
+
+ usbh_endpoint_desc_parse (pep, (uint8_t *)pdesc);
+ prev_ep_size = SWAPBYTE((uint8_t *)pdesc + 4);
+ ep_ix++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ prev_ep_size = 0U;
+ prev_itf = 0U;
+ }
+}
+
+/*!
+ \brief parse the interface descriptor
+ \param[in] itf_desc: interface descriptor destination
+ \param[in] buf: buffer where the descriptor data is available
+ \param[out] none
+ \retval none
+*/
+void usbh_interface_desc_parse (usb_descriptor_interface_struct *itf_desc, uint8_t *buf)
+{
+ itf_desc->Header.bLength = *(uint8_t *)(buf + 0);
+ itf_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
+ itf_desc->bInterfaceNumber = *(uint8_t *)(buf + 2);
+ itf_desc->bAlternateSetting = *(uint8_t *)(buf + 3);
+ itf_desc->bNumEndpoints = *(uint8_t *)(buf + 4);
+ itf_desc->bInterfaceClass = *(uint8_t *)(buf + 5);
+ itf_desc->bInterfaceSubClass = *(uint8_t *)(buf + 6);
+ itf_desc->bInterfaceProtocol = *(uint8_t *)(buf + 7);
+ itf_desc->iInterface = *(uint8_t *)(buf + 8);
+}
+
+/*!
+ \brief parse the endpoint descriptor
+ \param[in] ep_desc: endpoint descriptor destination address
+ \param[in] buf: buffer where the parsed descriptor stored
+ \param[out] none
+ \retval none
+*/
+void usbh_endpoint_desc_parse (usb_descriptor_endpoint_struct *ep_desc, uint8_t *buf)
+{
+ ep_desc->Header.bLength = *(uint8_t *)(buf + 0);
+ ep_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
+ ep_desc->bEndpointAddress = *(uint8_t *)(buf + 2);
+ ep_desc->bmAttributes = *(uint8_t *)(buf + 3);
+ ep_desc->wMaxPacketSize = SWAPBYTE(buf + 4);
+ ep_desc->bInterval = *(uint8_t *)(buf + 6);
+}
+
+/*!
+ \brief parse the string descriptor
+ \param[in] psrc: source pointer containing the descriptor data
+ \param[in] pdest: destination address pointer
+ \param[in] len: length of the descriptor
+ \param[out] none
+ \retval none
+*/
+void usbh_string_desc_parse (uint8_t* psrc, uint8_t* pdest, uint16_t len)
+{
+ uint16_t strlength;
+ uint16_t idx;
+
+ /* the unicode string descriptor is not null-terminated. the string length is
+ computed by substracting two from the value of the first byte of the descriptor.
+ */
+
+ /* check which is lower size, the size of string or the length of bytes read from the device */
+
+ if (USB_DESCTYPE_STRING == psrc[1]){
+ /* make sure the descriptor is string type */
+
+ /* psrc[0] contains size of descriptor, subtract 2 to get the length of string */
+ strlength = ((((uint16_t)psrc[0] - 2U) <= len) ? ((uint16_t)psrc[0] - 2U) : len);
+ psrc += 2; /* adjust the offset ignoring the string len and descriptor type */
+
+ for (idx = 0U; idx < strlength; idx += 2U) {
+ /* copy only the string and ignore the unicode id, hence add the src */
+ *pdest = psrc[idx];
+ pdest++;
+ }
+
+ *pdest = 0U; /* mark end of string */
+ }
+}
+
+/*!
+ \brief get the next descriptor header
+ \param[in] pbuf: pointer to buffer where the cfg descriptor is available
+ \param[in] ptr: data popinter inside the configuration descriptor
+ \param[out] none
+ \retval next descriptor header
+*/
+usb_descriptor_header_struct *usbh_next_desc_get (uint8_t *pbuf, uint16_t *ptr)
+{
+ uint8_t len = ((usb_descriptor_header_struct *)pbuf)->bLength;
+
+ usb_descriptor_header_struct *pnext;
+
+ *ptr += len;
+
+ pnext = (usb_descriptor_header_struct *)((uint8_t *)pbuf + len);
+
+ return(pnext);
+}
+
diff --git a/bsp/gd32350r-eval/Libraries/SConscript b/bsp/gd32350r-eval/Libraries/SConscript
new file mode 100644
index 0000000000000000000000000000000000000000..dad0c6c89e26be42633ff899993fcc1e069d4487
--- /dev/null
+++ b/bsp/gd32350r-eval/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('GD32F3x0_standard_peripheral/Source/*.c')
+src += [cwd + '/CMSIS/GD/GD32F3x0/Source/system_gd32f3x0.c']
+
+#add for startup script
+if rtconfig.CROSS_TOOL == 'gcc':
+ src += [cwd + '/CMSIS/GD/GD32F3x0/Source/GCC/startup_gd32f3x0.S']
+elif rtconfig.CROSS_TOOL == 'keil':
+ src += [cwd + '/CMSIS/GD/GD32F3x0/Source/ARM/startup_gd32f3x0.s']
+elif rtconfig.CROSS_TOOL == 'iar':
+ src += [cwd + '/CMSIS/GD/GD32F3x0/Source/IAR/startup_gd32f3x0.s']
+
+path = [
+ cwd + '/CMSIS/GD/GD32F3x0/Include',
+ cwd + '/CMSIS',
+ cwd + '/GD32F3x0_standard_peripheral/Include',]
+
+if GetDepend(['RT_USING_BSP_USB']):
+ path += [cwd + '/GD32F4xx_usb_driver/Include']
+ src += [cwd + '/GD32F4xx_usb_driver/Source']
+
+CPPDEFINES = ['USE_STDPERIPH_DRIVER', 'GD32F350']
+
+group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES)
+
+Return('group')
diff --git a/bsp/gd32350r-eval/README.md b/bsp/gd32350r-eval/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..8f2a434511da5f38c55bc954ba9213605e236755
--- /dev/null
+++ b/bsp/gd32350r-eval/README.md
@@ -0,0 +1,55 @@
+# GD32350R-EVAL
+
+## 简介
+
+GD32350R-EVAL是-兆易创新推出的一款GD32F350系列的评估æ¿ï¼Œæ¿è½½èµ„æºä¸»è¦å¦‚下:
+
+| 硬件 | æè¿° |
+| --------- | ------------- |
+| èŠ¯ç‰‡åž‹å· | GD32F350R8T6 |
+| CPU | ARM Cortex M4 |
+| 主频 | 108M |
+| 片内SRAM | 16K |
+| 片内FLASH | 64K |
+
+## 编译说明
+
+GD32450Z-EVALæ¿çº§åŒ…支æŒMDK5å¼€å‘环境以下是具体版本信æ¯ï¼š
+
+| IDE/编译器 | 已测试版本 |
+| ---------- | ---------- |
+| MDK5 | MDK524a |
+
+## 烧写åŠæ‰§è¡Œ
+
+供电方å¼ï¼šå¼€å‘æ¿ä½¿ç”¨ Mini USB 接å£æˆ–者 DC-005 连接器æä¾› 5V 电æºã€‚
+
+下载程åºï¼šä¸‹è½½ç¨‹åºåˆ°å¼€å‘æ¿éœ€è¦ä¸€å¥— JLink 或者使用 GD-Link 工具。
+
+串å£è¿žæŽ¥ï¼šä½¿ç”¨ä¸²å£çº¿è¿žæŽ¥åˆ°COM1(UART0),或者使用USB转TTL模å—连接PA9(MCU TX)å’ŒPA10(MCU RX)。
+
+### è¿è¡Œç»“æžœ
+
+如果编译 & çƒ§å†™æ— è¯¯ï¼Œå½“å¤ä½è®¾å¤‡åŽï¼Œä¼šåœ¨ä¸²å£ä¸Šçœ‹åˆ°RT-Threadçš„å¯åŠ¨logoä¿¡æ¯ï¼š
+
+```bash
+ \ | /
+- RT - Thread Operating System
+ / | \ 4.0.4 build Jun 21 2021
+ 2006 - 2021 Copyright by rt-thread team
+
+
+
+msh >
+```
+## 驱动支æŒæƒ…况åŠè®¡åˆ’
+
+| 驱动 | 支æŒæƒ…况 | 备注 |
+| --------- | -------- | :------------------------: |
+| UART | æ”¯æŒ | UART0~1 |
+| GPIO | æ”¯æŒ | ALL |
+
+## è”系人信æ¯
+
+维护人:[RiceChen](https://gitee.com/RiceChen0)
+邮箱:980307037@qq.com
diff --git a/bsp/gd32350r-eval/SConscript b/bsp/gd32350r-eval/SConscript
new file mode 100644
index 0000000000000000000000000000000000000000..fe0ae941ae9a759ae478de901caec1c961e56af8
--- /dev/null
+++ b/bsp/gd32350r-eval/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')
diff --git a/bsp/gd32350r-eval/SConstruct b/bsp/gd32350r-eval/SConstruct
new file mode 100644
index 0000000000000000000000000000000000000000..63793d5195ce66e233380a0a4c587ecf47ae436a
--- /dev/null
+++ b/bsp/gd32350r-eval/SConstruct
@@ -0,0 +1,40 @@
+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-gd32f3x0.' + rtconfig.TARGET_EXT
+
+DefaultEnvironment(tools=[])
+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)
diff --git a/bsp/gd32350r-eval/applications/SConscript b/bsp/gd32350r-eval/applications/SConscript
new file mode 100644
index 0000000000000000000000000000000000000000..01eb940dfb35f92c503a78b0b49a4354590f9f3a
--- /dev/null
+++ b/bsp/gd32350r-eval/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')
diff --git a/bsp/gd32350r-eval/applications/main.c b/bsp/gd32350r-eval/applications/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..3aa60cf2b2ce0f823d300533d9634c6b4c17ff28
--- /dev/null
+++ b/bsp/gd32350r-eval/applications/main.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-06-21 RiceChen the first version
+ */
+
+#include
+#include
+#include "rtdevice.h"
+
+int main(void)
+{
+ rt_kprintf("\n\n\n");
+
+ return 0;
+}
diff --git a/bsp/gd32350r-eval/drivers/SConscript b/bsp/gd32350r-eval/drivers/SConscript
new file mode 100644
index 0000000000000000000000000000000000000000..f40845bdf7e3353723c7f9ed2dd60b3c7a479382
--- /dev/null
+++ b/bsp/gd32350r-eval/drivers/SConscript
@@ -0,0 +1,24 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd = os.path.join(str(Dir('#')), 'drivers')
+
+# add the general drivers.
+src = Split("""
+board.c
+""")
+
+CPPPATH = [cwd]
+
+# add pin drivers.
+if GetDepend('RT_USING_PIN'):
+ src += ['drv_gpio.c']
+
+# add uart drivers.
+if GetDepend('RT_USING_SERIAL'):
+ src += ['drv_usart.c']
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/bsp/gd32350r-eval/drivers/board.c b/bsp/gd32350r-eval/drivers/board.c
new file mode 100644
index 0000000000000000000000000000000000000000..93d3f93bd5b13938b66086e05a3134ce229b06fe
--- /dev/null
+++ b/bsp/gd32350r-eval/drivers/board.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-01-05 Bernard first implementation
+ */
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+/**
+ * @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();
+}
+
+char heap[1024 *16];
+/**
+ * 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 BSP_USING_SDRAM
+ rt_system_heap_init((void *)EXT_SDRAM_BEGIN, (void *)EXT_SDRAM_END);
+#else
+ rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
+#endif
+}
+
+/*@}*/
diff --git a/bsp/gd32350r-eval/drivers/board.h b/bsp/gd32350r-eval/drivers/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..05d3c7e9722eea628c648f2f0b8eba0f21abd1b3
--- /dev/null
+++ b/bsp/gd32350r-eval/drivers/board.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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
+
+#define EXT_SDRAM_BEGIN (0xC0000000U) /* the begining address of external SDRAM */
+#define EXT_SDRAM_END (EXT_SDRAM_BEGIN + (32U * 1024 * 1024)) /* the end address of external SDRAM */
+
+// Internal SRAM memory size[Kbytes] <8-64>
+// 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 16
+#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 >>> ***
diff --git a/bsp/gd32350r-eval/drivers/drv_gpio.c b/bsp/gd32350r-eval/drivers/drv_gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d15638d5fd49a48583e8a0588932dcaa37e3915
--- /dev/null
+++ b/bsp/gd32350r-eval/drivers/drv_gpio.c
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-06-20 RiceChen the first version
+ */
+
+#include
+#include
+
+#ifdef RT_USING_PIN
+
+#include "drv_gpio.h"
+
+static const struct pin_index pins[] =
+{
+ GD32_PIN(1, A, 0),
+ GD32_PIN(2, A, 1),
+ GD32_PIN(3, A, 2),
+ GD32_PIN(4, A, 3),
+ GD32_PIN(5, A, 4),
+ GD32_PIN(6, A, 5),
+ GD32_PIN(7, A, 6),
+ GD32_PIN(8, A, 7),
+ GD32_PIN(9, A, 8),
+ GD32_PIN(10, A, 9),
+ GD32_PIN(11, A, 10),
+ GD32_PIN(12, A, 11),
+ GD32_PIN(13, A, 12),
+ GD32_PIN(14, A, 13),
+ GD32_PIN(15, A, 14),
+ GD32_PIN(16, A, 15),
+ GD32_PIN(17, B, 0),
+ GD32_PIN(18, B, 1),
+ GD32_PIN(19, B, 2),
+ GD32_PIN(20, B, 3),
+ GD32_PIN(21, B, 4),
+ GD32_PIN(22, B, 5),
+ GD32_PIN(23, B, 6),
+ GD32_PIN(24, B, 7),
+ GD32_PIN(25, B, 8),
+ GD32_PIN(26, B, 9),
+ GD32_PIN(27, B, 10),
+ GD32_PIN(28, B, 11),
+ GD32_PIN(29, B, 12),
+ GD32_PIN(30, B, 13),
+ GD32_PIN(31, B, 14),
+ GD32_PIN(32, B, 15),
+ GD32_PIN(33, C, 0),
+ GD32_PIN(34, C, 1),
+ GD32_PIN(35, C, 2),
+ GD32_PIN(36, C, 3),
+ GD32_PIN(37, C, 4),
+ GD32_PIN(38, C, 5),
+ GD32_PIN(39, C, 6),
+ GD32_PIN(40, C, 7),
+ GD32_PIN(41, C, 8),
+ GD32_PIN(42, C, 9),
+ GD32_PIN(43, C, 10),
+ GD32_PIN(44, C, 11),
+ GD32_PIN(45, C, 12),
+ GD32_PIN(46, C, 13),
+ GD32_PIN(47, C, 14),
+ GD32_PIN(48, C, 15),
+ GD32_PIN(51, D, 2),
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN(65, F, 0),
+ GD32_PIN(66, F, 1),
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN(69, F, 4),
+ GD32_PIN(70, F, 5),
+ GD32_PIN(71, F, 6),
+ GD32_PIN(72, F, 7),
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+ GD32_PIN_DEFAULT,
+};
+
+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_NULL;
+ rt_uint32_t pin_mode = 0, pin_pupd = 0, pin_odpp = 0;
+
+ index = get_pin(pin);
+ if (index == RT_NULL)
+ {
+ return;
+ }
+
+ /* GPIO Periph clock enable */
+ rcu_periph_clock_enable(index->clk);
+ pin_mode = GPIO_MODE_OUTPUT;
+
+ switch(mode)
+ {
+ case PIN_MODE_OUTPUT:
+ /* output setting */
+ pin_mode = GPIO_MODE_OUTPUT;
+ pin_pupd = GPIO_PUPD_NONE;
+ pin_odpp = GPIO_OTYPE_PP;
+ break;
+ case PIN_MODE_OUTPUT_OD:
+ /* output setting: od. */
+ pin_mode = GPIO_MODE_OUTPUT;
+ pin_pupd = GPIO_PUPD_NONE;
+ pin_odpp = GPIO_OTYPE_OD;
+ break;
+ case PIN_MODE_INPUT:
+ /* input setting: not pull. */
+ pin_mode = GPIO_MODE_INPUT;
+ pin_pupd = GPIO_PUPD_PULLUP | GPIO_PUPD_PULLDOWN;
+ break;
+ case PIN_MODE_INPUT_PULLUP:
+ /* input setting: pull up. */
+ pin_mode = GPIO_MODE_INPUT;
+ pin_pupd = GPIO_PUPD_PULLUP;
+ break;
+ case PIN_MODE_INPUT_PULLDOWN:
+ /* input setting: pull down. */
+ pin_mode = GPIO_MODE_INPUT;
+ pin_pupd = GPIO_PUPD_PULLDOWN;
+ break;
+ default:
+ break;
+ }
+
+ gpio_mode_set(index->gpio_periph, pin_mode, pin_pupd, index->pin);
+ if(pin_mode == GPIO_MODE_OUTPUT)
+ {
+ gpio_output_options_set(index->gpio_periph, pin_odpp, 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 = RT_NULL;
+
+ 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 = PIN_LOW;
+ const struct pin_index *index = RT_NULL;
+
+ 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 map_index = bit2bitno(pinbit);
+ if (map_index < 0 || map_index >= ITEM_NUM(pin_irq_map))
+ {
+ return RT_NULL;
+ }
+ return &pin_irq_map[map_index];
+};
+
+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_NULL;
+ 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_NULL;
+ 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_CFGCMP);
+
+ /* enable and set interrupt priority */
+ nvic_irq_enable(irqmap->irqno, 5U, 0U);
+
+ /* 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,
+ RT_NULL,
+};
+
+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_1_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ GD32_GPIO_EXTI_IRQHandler(0);
+ GD32_GPIO_EXTI_IRQHandler(1);
+ rt_interrupt_leave();
+}
+
+void EXTI2_3_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ GD32_GPIO_EXTI_IRQHandler(2);
+ GD32_GPIO_EXTI_IRQHandler(3);
+ rt_interrupt_leave();
+}
+
+void EXTI4_15_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ GD32_GPIO_EXTI_IRQHandler(4);
+ 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);
+ 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();
+}
+
+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);
+
+#endif
diff --git a/bsp/gd32350r-eval/drivers/drv_gpio.h b/bsp/gd32350r-eval/drivers/drv_gpio.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3e750970d15f0ef98dcb6397f979d2cbd4b7fe5
--- /dev/null
+++ b/bsp/gd32350r-eval/drivers/drv_gpio.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-06-20 RiceChen the first version
+ */
+
+#ifndef __DRV_GPIO_H__
+#define __DRV_GPIO_H__
+
+#include "gd32f3x0.h"
+#include "gd32f3x0_exti.h"
+
+#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, 0, 0}
+
+struct pin_index
+{
+ rt_int16_t index;
+ rcu_periph_enum clk;
+ rt_uint32_t gpio_periph;
+ rt_uint32_t pin;
+ rt_uint8_t port_src;
+ rt_uint8_t pin_src;
+};
+
+struct pin_irq_map
+{
+ rt_uint16_t pinbit;
+ IRQn_Type irqno;
+};
+
+#endif
diff --git a/bsp/gd32350r-eval/drivers/drv_usart.c b/bsp/gd32350r-eval/drivers/drv_usart.c
new file mode 100644
index 0000000000000000000000000000000000000000..254b24a093c6834bd656704b7f3d82c84bf44422
--- /dev/null
+++ b/bsp/gd32350r-eval/drivers/drv_usart.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-06-21 RiceChen the first version
+ */
+
+
+#include
+
+#ifdef RT_USING_SERIAL
+
+#if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1)
+#error "Please define at least one UARTx"
+#endif
+
+#include "drv_usart.h"
+
+static struct gd32_usart_config usart_config[] =
+{
+#ifdef BSP_USING_UART0
+ UART0_BUS_CONFIG,
+#endif
+#ifdef BSP_USING_UART1
+ UART1_BUS_CONFIG,
+#endif
+};
+
+static struct gd32_usart_bus usart_obj[sizeof(usart_config) / sizeof(usart_config[0])];
+
+void gd32_usart_gpio_init(struct gd32_usart_bus *bus)
+{
+ rcu_periph_clock_enable(bus->config->per_clk);
+ rcu_periph_clock_enable(bus->config->tx_gpio_clk);
+ rcu_periph_clock_enable(bus->config->rx_gpio_clk);
+
+ gpio_af_set(bus->config->tx_port, GPIO_AF_1, bus->config->tx_pin);
+ gpio_af_set(bus->config->rx_port, GPIO_AF_1, bus->config->rx_pin);
+
+ gpio_mode_set(bus->config->tx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, bus->config->tx_pin);
+ gpio_output_options_set(bus->config->tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, bus->config->tx_pin);
+
+ gpio_mode_set(bus->config->rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, bus->config->rx_pin);
+ gpio_output_options_set(bus->config->rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, bus->config->rx_pin);
+
+ NVIC_SetPriority(bus->config->irqn, 0);
+ NVIC_EnableIRQ(bus->config->irqn);
+ usart_deinit(bus->config->periph);
+}
+
+rt_err_t gd32_usart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
+{
+ struct gd32_usart_bus *bus = RT_NULL;
+
+ bus = (struct gd32_usart_bus *)serial->parent.user_data;
+
+ gd32_usart_gpio_init(bus);
+
+ usart_baudrate_set(bus->config->periph, cfg->baud_rate);
+
+ switch (cfg->data_bits)
+ {
+ case DATA_BITS_9:
+ usart_word_length_set(bus->config->periph, USART_WL_9BIT);
+ break;
+
+ default:
+ usart_word_length_set(bus->config->periph, USART_WL_8BIT);
+ break;
+ }
+
+ switch (cfg->stop_bits)
+ {
+ case STOP_BITS_2:
+ usart_stop_bit_set(bus->config->periph, USART_STB_2BIT);
+ break;
+ default:
+ usart_stop_bit_set(bus->config->periph, USART_STB_1BIT);
+ break;
+ }
+
+ switch (cfg->parity)
+ {
+ case PARITY_ODD:
+ usart_parity_config(bus->config->periph, USART_PM_ODD);
+ break;
+ case PARITY_EVEN:
+ usart_parity_config(bus->config->periph, USART_PM_EVEN);
+ break;
+ default:
+ usart_parity_config(bus->config->periph, USART_PM_NONE);
+ break;
+ }
+
+ usart_receive_config(bus->config->periph, USART_RECEIVE_ENABLE);
+ usart_transmit_config(bus->config->periph, USART_TRANSMIT_ENABLE);
+ usart_enable(bus->config->periph);
+
+ return RT_EOK;
+}
+
+rt_err_t gd32_usart_control(struct rt_serial_device *serial, int cmd, void *arg)
+{
+ struct gd32_usart_bus *bus = RT_NULL;
+
+ bus = (struct gd32_usart_bus *)serial->parent.user_data;
+
+ switch (cmd)
+ {
+ case RT_DEVICE_CTRL_CLR_INT:
+ /* disable rx irq */
+ NVIC_DisableIRQ(bus->config->irqn);
+ /* disable interrupt */
+ usart_interrupt_disable(bus->config->periph, USART_INT_RBNE);
+
+ break;
+ case RT_DEVICE_CTRL_SET_INT:
+ /* enable rx irq */
+ NVIC_EnableIRQ(bus->config->irqn);
+ /* enable interrupt */
+ usart_interrupt_enable(bus->config->periph, USART_INT_RBNE);
+ break;
+ }
+
+ return RT_EOK;
+}
+
+int gd32_usart_putc(struct rt_serial_device *serial, char c)
+{
+ struct gd32_usart_bus *bus = RT_NULL;
+
+ bus = (struct gd32_usart_bus *)serial->parent.user_data;
+
+ usart_data_transmit(bus->config->periph, c);
+ while((usart_flag_get(bus->config->periph, USART_FLAG_TC) == RESET));
+
+ return 1;
+}
+
+int gd32_usart_getc(struct rt_serial_device *serial)
+{
+ int ch;
+ struct gd32_usart_bus *bus = RT_NULL;
+
+ bus = (struct gd32_usart_bus *)serial->parent.user_data;
+
+ ch = -1;
+ if (usart_flag_get(bus->config->periph, USART_FLAG_RBNE) != RESET)
+ ch = usart_data_receive(bus->config->periph);
+ return ch;
+}
+
+rt_size_t gd32_usart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
+{
+ return RT_EOK;
+}
+
+static struct rt_uart_ops usart_ops =
+{
+ gd32_usart_configure,
+ gd32_usart_control,
+ gd32_usart_putc,
+ gd32_usart_getc,
+ gd32_usart_dma_transmit,
+};
+
+static void uart_isr(rt_uint32_t periph)
+{
+ int obj_num = 0;
+ struct gd32_usart_bus *bus = RT_NULL;
+
+ obj_num = sizeof(usart_config) / sizeof(usart_config[0]);
+
+ for(int i = 0; i < obj_num; i++)
+ {
+ if(usart_obj[i].config->periph == periph)
+ {
+ bus = &usart_obj[i];
+ break;
+ }
+ }
+
+ if(bus != RT_NULL)
+ {
+ if ((usart_interrupt_flag_get(bus->config->periph, USART_INT_FLAG_RBNE) != RESET) &&
+ (usart_flag_get(bus->config->periph, USART_FLAG_RBNE) != RESET))
+ {
+ rt_hw_serial_isr(&bus->serial, RT_SERIAL_EVENT_RX_IND);
+ /* Clear RXNE interrupt flag */
+ usart_flag_clear(bus->config->periph, USART_FLAG_RBNE);
+ }
+ }
+}
+
+#ifdef BSP_USING_UART0
+void USART0_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ uart_isr(USART0);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+#endif
+
+#ifdef BSP_USING_UART1
+void USART1_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ uart_isr(USART1);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+#endif
+
+int rt_hw_usart_init(void)
+{
+ int obj_num = 0;
+ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+
+ obj_num = sizeof(usart_config) / sizeof(usart_config[0]);
+
+ for(int i = 0; i < obj_num; i++)
+ {
+ usart_obj[i].serial.ops = &usart_ops;
+ usart_obj[i].serial.config = config;
+ usart_obj[i].config = &usart_config[i];
+
+ /* register UART device */
+ rt_hw_serial_register(&usart_obj[i].serial,
+ usart_obj[i].config->dev_name,
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+ (void *)&usart_obj[i]);
+ }
+
+ return RT_EOK;
+}
+INIT_BOARD_EXPORT(rt_hw_usart_init);
+
+#endif
diff --git a/bsp/gd32350r-eval/drivers/drv_usart.h b/bsp/gd32350r-eval/drivers/drv_usart.h
new file mode 100644
index 0000000000000000000000000000000000000000..10561646a7999aeab1fcac89bf7e078b21ec4715
--- /dev/null
+++ b/bsp/gd32350r-eval/drivers/drv_usart.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-06-20 RiceChen the first version
+ */
+
+#ifndef __DRV_USART_H__
+#define __DRV_USART_H__
+
+#include
+#include
+#include "gd32f3x0.h"
+#include "gd32f3x0_usart.h"
+#include "gd32f3x0_exti.h"
+
+struct gd32_usart_config
+{
+ char *dev_name;
+ rt_uint32_t periph;
+ IRQn_Type irqn;
+ rcu_periph_enum per_clk;
+ rcu_periph_enum tx_gpio_clk;
+ rcu_periph_enum rx_gpio_clk;
+ rt_uint32_t tx_port;
+ rt_uint32_t tx_pin;
+ rt_uint32_t rx_port;
+ rt_uint32_t rx_pin;
+};
+
+struct gd32_usart_bus
+{
+ struct rt_serial_device serial;
+ struct gd32_usart_config *config;
+};
+
+#ifdef BSP_USING_UART0
+#define UART0_BUS_CONFIG \
+ { \
+ .dev_name = "uart0", \
+ .periph = USART0, \
+ .irqn = USART0_IRQn, \
+ .per_clk = RCU_USART0, \
+ .tx_gpio_clk = RCU_GPIOA, \
+ .rx_gpio_clk = RCU_GPIOA, \
+ .tx_port = GPIOA, \
+ .tx_pin = GPIO_PIN_9, \
+ .rx_port = GPIOA, \
+ .rx_pin = GPIO_PIN_10, \
+ }
+#endif /* BSP_USING_UART0 */
+
+#ifdef BSP_USING_UART1
+#define UART1_BUS_CONFIG \
+ { \
+ .dev_name = "uart1", \
+ .periph = USART1, \
+ .irqn = USART1_IRQn, \
+ .per_clk = RCU_USART1, \
+ .tx_gpio_clk = RCU_GPIOA, \
+ .rx_gpio_clk = RCU_GPIOA, \
+ .tx_port = GPIOA, \
+ .tx_pin = GPIO_PIN_2, \
+ .rx_port = GPIOA, \
+ .rx_pin = GPIO_PIN_3, \
+ }
+#endif /* BSP_USING_UART1 */
+
+#endif
diff --git a/bsp/gd32350r-eval/drivers/gd32f3x0_libopt.h b/bsp/gd32350r-eval/drivers/gd32f3x0_libopt.h
new file mode 100644
index 0000000000000000000000000000000000000000..7192e4fb125c1dc3652eda871a9f894f83afc520
--- /dev/null
+++ b/bsp/gd32350r-eval/drivers/gd32f3x0_libopt.h
@@ -0,0 +1,66 @@
+/*!
+ \file gd32f3x0_libopt.h
+ \brief library optional for gd32f3x0
+
+ \version 2017-06-28, V1.0.0, demo for GD32F3x0
+ \version 2019-06-01, V2.0.0, demo for GD32F3x0
+*/
+
+/*
+ Copyright (c) 2019, GigaDevice Semiconductor Inc.
+
+ 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 GD32F3X0_LIBOPT_H
+#define GD32F3X0_LIBOPT_H
+
+#include "gd32f3x0_adc.h"
+#include "gd32f3x0_crc.h"
+#include "gd32f3x0_ctc.h"
+#include "gd32f3x0_dbg.h"
+#include "gd32f3x0_dma.h"
+#include "gd32f3x0_exti.h"
+#include "gd32f3x0_fmc.h"
+#include "gd32f3x0_gpio.h"
+#include "gd32f3x0_syscfg.h"
+#include "gd32f3x0_i2c.h"
+#include "gd32f3x0_fwdgt.h"
+#include "gd32f3x0_pmu.h"
+#include "gd32f3x0_rcu.h"
+#include "gd32f3x0_rtc.h"
+#include "gd32f3x0_spi.h"
+#include "gd32f3x0_timer.h"
+#include "gd32f3x0_usart.h"
+#include "gd32f3x0_wwdgt.h"
+#include "gd32f3x0_misc.h"
+#include "gd32f3x0_tsi.h"
+
+#ifdef GD32F350
+#include "gd32f3x0_cec.h"
+#include "gd32f3x0_cmp.h"
+#include "gd32f3x0_dac.h"
+#endif /* GD32F350 */
+
+#endif /* GD32F3X0_LIBOPT_H */
diff --git a/bsp/gd32350r-eval/gd32_rom.icf b/bsp/gd32350r-eval/gd32_rom.icf
new file mode 100644
index 0000000000000000000000000000000000000000..1741be6a715abe9150b82853f9afc884e55f974f
--- /dev/null
+++ b/bsp/gd32350r-eval/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__ = 0x082FFFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF;
+/*-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 };
\ No newline at end of file
diff --git a/bsp/gd32350r-eval/gd32_rom.ld b/bsp/gd32350r-eval/gd32_rom.ld
new file mode 100644
index 0000000000000000000000000000000000000000..ec1c65c34e962bb84f3ca998517a6208a76c31c6
--- /dev/null
+++ b/bsp/gd32350r-eval/gd32_rom.ld
@@ -0,0 +1,142 @@
+/*
+ * linker script for GD32F4xx 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 = 3072k /* 3072KB flash */
+ DATA (rw) : ORIGIN = 0x20000000, LENGTH = 192k /* 192KB 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) }
+}
diff --git a/bsp/gd32350r-eval/gd32_rom.sct b/bsp/gd32350r-eval/gd32_rom.sct
new file mode 100644
index 0000000000000000000000000000000000000000..a4fc4f27657be5f0828f4df52ed3c6ec98c28c28
--- /dev/null
+++ b/bsp/gd32350r-eval/gd32_rom.sct
@@ -0,0 +1,15 @@
+; *************************************************************
+; *** Scatter-Loading Description File generated by uVision ***
+; *************************************************************
+
+LR_IROM1 0x08000000 0x00200000 { ; load region size_region
+ ER_IROM1 0x08000000 0x00200000 { ; load address = execution address
+ *.o (RESET, +First)
+ *(InRoot$$Sections)
+ .ANY (+RO)
+ }
+ RW_IRAM1 0x20000000 0x00004000 { ; RW data
+ .ANY (+RW +ZI)
+ }
+}
+
diff --git a/bsp/gd32350r-eval/project.uvoptx b/bsp/gd32350r-eval/project.uvoptx
new file mode 100644
index 0000000000000000000000000000000000000000..45a8b35cef5de36beb34ef82f6029bb014bbbbbf
--- /dev/null
+++ b/bsp/gd32350r-eval/project.uvoptx
@@ -0,0 +1,1094 @@
+
+
+
+ 1.0
+
+ ### uVision Project, (C) Keil Software
+
+
+ *.c
+ *.s*; *.src; *.a*
+ *.obj; *.o
+ *.lib
+ *.txt; *.h; *.inc
+ *.plm
+ *.cpp
+ 0
+
+
+
+ 0
+ 0
+
+
+
+ rt-thread_gd32f30x
+ 0x4
+ ARM-ADS
+
+ 12000000
+
+ 1
+ 1
+ 0
+ 1
+ 0
+
+
+ 1
+ 65535
+ 0
+ 0
+ 0
+
+
+ 79
+ 66
+ 8
+ .\build\
+
+
+ 1
+ 1
+ 1
+ 0
+ 1
+ 1
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+
+
+ 1
+ 0
+ 1
+
+ 255
+
+ 0
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 0
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+ 1
+ 0
+ 0
+ 3
+
+
+
+
+
+
+
+
+
+
+ BIN\CMSIS_AGDI.dll
+
+
+
+ 0
+ ARMRTXEVENTFLAGS
+ -L70 -Z18 -C0 -M0 -T1
+
+
+ 0
+ DLGTARM
+ (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)
+
+
+ 0
+ ARMDBGFLAGS
+
+
+
+ 0
+ DLGUARM
+
+
+
+ 0
+ CMSIS_AGDI
+ -X"Any" -UAny -O206 -S0 -C0 -P00 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F3x0.FLM -FS08000000 -FL020000 -FP0($$Device:GD32F350R8$Flash\GD32F3x0.FLM)
+
+
+ 0
+ UL2CM3
+ UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0GD32F3x0 -FL010000 -FS08000000 -FP0($$Device:GD32F350R8$Flash\GD32F3x0.FLM)
+
+
+ 0
+ JL2CM3
+ -U59401765 -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 -FF0GD32F4xx_3MB.FLM -FS08000000 -FL0300000 -FP0($$Device:GD32F450ZK$Flash\GD32F4xx_3MB.FLM)
+
+
+
+
+ 0
+
+
+ 0
+ 0
+ 1
+ 0
+ 1
+ 1
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+ Applications
+ 0
+ 0
+ 0
+ 0
+
+ 1
+ 1
+ 1
+ 0
+ 0
+ 0
+ applications\main.c
+ main.c
+ 0
+ 0
+
+
+
+
+ CPU
+ 0
+ 0
+ 0
+ 0
+
+ 2
+ 2
+ 1
+ 0
+ 0
+ 0
+ ..\..\libcpu\arm\common\showmem.c
+ showmem.c
+ 0
+ 0
+
+
+ 2
+ 3
+ 1
+ 0
+ 0
+ 0
+ ..\..\libcpu\arm\common\div0.c
+ div0.c
+ 0
+ 0
+
+
+ 2
+ 4
+ 1
+ 0
+ 0
+ 0
+ ..\..\libcpu\arm\common\backtrace.c
+ backtrace.c
+ 0
+ 0
+
+
+ 2
+ 5
+ 2
+ 0
+ 0
+ 0
+ ..\..\libcpu\arm\cortex-m4\context_rvds.S
+ context_rvds.S
+ 0
+ 0
+
+
+ 2
+ 6
+ 1
+ 0
+ 0
+ 0
+ ..\..\libcpu\arm\cortex-m4\cpuport.c
+ cpuport.c
+ 0
+ 0
+
+
+
+
+ DeviceDrivers
+ 0
+ 0
+ 0
+ 0
+
+ 3
+ 7
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\drivers\misc\pin.c
+ pin.c
+ 0
+ 0
+
+
+ 3
+ 8
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\drivers\serial\serial.c
+ serial.c
+ 0
+ 0
+
+
+ 3
+ 9
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\drivers\src\completion.c
+ completion.c
+ 0
+ 0
+
+
+ 3
+ 10
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\drivers\src\workqueue.c
+ workqueue.c
+ 0
+ 0
+
+
+ 3
+ 11
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\drivers\src\ringblk_buf.c
+ ringblk_buf.c
+ 0
+ 0
+
+
+ 3
+ 12
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\drivers\src\waitqueue.c
+ waitqueue.c
+ 0
+ 0
+
+
+ 3
+ 13
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\drivers\src\ringbuffer.c
+ ringbuffer.c
+ 0
+ 0
+
+
+ 3
+ 14
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\drivers\src\dataqueue.c
+ dataqueue.c
+ 0
+ 0
+
+
+ 3
+ 15
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\drivers\src\pipe.c
+ pipe.c
+ 0
+ 0
+
+
+
+
+ Drivers
+ 0
+ 0
+ 0
+ 0
+
+ 4
+ 16
+ 1
+ 0
+ 0
+ 0
+ drivers\drv_gpio.c
+ drv_gpio.c
+ 0
+ 0
+
+
+ 4
+ 17
+ 1
+ 0
+ 0
+ 0
+ drivers\drv_usart.c
+ drv_usart.c
+ 0
+ 0
+
+
+ 4
+ 18
+ 1
+ 0
+ 0
+ 0
+ drivers\board.c
+ board.c
+ 0
+ 0
+
+
+
+
+ finsh
+ 0
+ 0
+ 0
+ 0
+
+ 5
+ 19
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\finsh_node.c
+ finsh_node.c
+ 0
+ 0
+
+
+ 5
+ 20
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\finsh_parser.c
+ finsh_parser.c
+ 0
+ 0
+
+
+ 5
+ 21
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\cmd.c
+ cmd.c
+ 0
+ 0
+
+
+ 5
+ 22
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\finsh_vm.c
+ finsh_vm.c
+ 0
+ 0
+
+
+ 5
+ 23
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\shell.c
+ shell.c
+ 0
+ 0
+
+
+ 5
+ 24
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\finsh_var.c
+ finsh_var.c
+ 0
+ 0
+
+
+ 5
+ 25
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\finsh_compiler.c
+ finsh_compiler.c
+ 0
+ 0
+
+
+ 5
+ 26
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\finsh_heap.c
+ finsh_heap.c
+ 0
+ 0
+
+
+ 5
+ 27
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\finsh_ops.c
+ finsh_ops.c
+ 0
+ 0
+
+
+ 5
+ 28
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\msh.c
+ msh.c
+ 0
+ 0
+
+
+ 5
+ 29
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\finsh_error.c
+ finsh_error.c
+ 0
+ 0
+
+
+ 5
+ 30
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\finsh_token.c
+ finsh_token.c
+ 0
+ 0
+
+
+ 5
+ 31
+ 1
+ 0
+ 0
+ 0
+ ..\..\components\finsh\finsh_init.c
+ finsh_init.c
+ 0
+ 0
+
+
+
+
+ Kernel
+ 0
+ 0
+ 0
+ 0
+
+ 6
+ 32
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\components.c
+ components.c
+ 0
+ 0
+
+
+ 6
+ 33
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\mem.c
+ mem.c
+ 0
+ 0
+
+
+ 6
+ 34
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\object.c
+ object.c
+ 0
+ 0
+
+
+ 6
+ 35
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\device.c
+ device.c
+ 0
+ 0
+
+
+ 6
+ 36
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\thread.c
+ thread.c
+ 0
+ 0
+
+
+ 6
+ 37
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\irq.c
+ irq.c
+ 0
+ 0
+
+
+ 6
+ 38
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\clock.c
+ clock.c
+ 0
+ 0
+
+
+ 6
+ 39
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\idle.c
+ idle.c
+ 0
+ 0
+
+
+ 6
+ 40
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\timer.c
+ timer.c
+ 0
+ 0
+
+
+ 6
+ 41
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\kservice.c
+ kservice.c
+ 0
+ 0
+
+
+ 6
+ 42
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\scheduler.c
+ scheduler.c
+ 0
+ 0
+
+
+ 6
+ 43
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\ipc.c
+ ipc.c
+ 0
+ 0
+
+
+ 6
+ 44
+ 1
+ 0
+ 0
+ 0
+ ..\..\src\mempool.c
+ mempool.c
+ 0
+ 0
+
+
+
+
+ Libraries
+ 0
+ 0
+ 0
+ 0
+
+ 7
+ 45
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_dbg.c
+ gd32f3x0_dbg.c
+ 0
+ 0
+
+
+ 7
+ 46
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_dac.c
+ gd32f3x0_dac.c
+ 0
+ 0
+
+
+ 7
+ 47
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_timer.c
+ gd32f3x0_timer.c
+ 0
+ 0
+
+
+ 7
+ 48
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_rtc.c
+ gd32f3x0_rtc.c
+ 0
+ 0
+
+
+ 7
+ 49
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_exti.c
+ gd32f3x0_exti.c
+ 0
+ 0
+
+
+ 7
+ 50
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_i2c.c
+ gd32f3x0_i2c.c
+ 0
+ 0
+
+
+ 7
+ 51
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_gpio.c
+ gd32f3x0_gpio.c
+ 0
+ 0
+
+
+ 7
+ 52
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_fwdgt.c
+ gd32f3x0_fwdgt.c
+ 0
+ 0
+
+
+ 7
+ 53
+ 1
+ 0
+ 0
+ 0
+ Libraries\CMSIS\GD\GD32F3x0\Source\system_gd32f3x0.c
+ system_gd32f3x0.c
+ 0
+ 0
+
+
+ 7
+ 54
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_cec.c
+ gd32f3x0_cec.c
+ 0
+ 0
+
+
+ 7
+ 55
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_wwdgt.c
+ gd32f3x0_wwdgt.c
+ 0
+ 0
+
+
+ 7
+ 56
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_ctc.c
+ gd32f3x0_ctc.c
+ 0
+ 0
+
+
+ 7
+ 57
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_rcu.c
+ gd32f3x0_rcu.c
+ 0
+ 0
+
+
+ 7
+ 58
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_dma.c
+ gd32f3x0_dma.c
+ 0
+ 0
+
+
+ 7
+ 59
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_spi.c
+ gd32f3x0_spi.c
+ 0
+ 0
+
+
+ 7
+ 60
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_syscfg.c
+ gd32f3x0_syscfg.c
+ 0
+ 0
+
+
+ 7
+ 61
+ 2
+ 0
+ 0
+ 0
+ Libraries\CMSIS\GD\GD32F3x0\Source\ARM\startup_gd32f3x0.s
+ startup_gd32f3x0.s
+ 0
+ 0
+
+
+ 7
+ 62
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_misc.c
+ gd32f3x0_misc.c
+ 0
+ 0
+
+
+ 7
+ 63
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_fmc.c
+ gd32f3x0_fmc.c
+ 0
+ 0
+
+
+ 7
+ 64
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_usart.c
+ gd32f3x0_usart.c
+ 0
+ 0
+
+
+ 7
+ 65
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_adc.c
+ gd32f3x0_adc.c
+ 0
+ 0
+
+
+ 7
+ 66
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_crc.c
+ gd32f3x0_crc.c
+ 0
+ 0
+
+
+ 7
+ 67
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_tsi.c
+ gd32f3x0_tsi.c
+ 0
+ 0
+
+
+ 7
+ 68
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_pmu.c
+ gd32f3x0_pmu.c
+ 0
+ 0
+
+
+ 7
+ 69
+ 1
+ 0
+ 0
+ 0
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_cmp.c
+ gd32f3x0_cmp.c
+ 0
+ 0
+
+
+
+
+ ::CMSIS
+ 0
+ 0
+ 0
+ 1
+
+
+
diff --git a/bsp/gd32350r-eval/project.uvprojx b/bsp/gd32350r-eval/project.uvprojx
new file mode 100644
index 0000000000000000000000000000000000000000..1b88ac78901922e11bf582210d2c3e2bcab034fa
--- /dev/null
+++ b/bsp/gd32350r-eval/project.uvprojx
@@ -0,0 +1,782 @@
+
+
+
+ 2.1
+
+ ### uVision Project, (C) Keil Software
+
+
+
+ rt-thread_gd32f30x
+ 0x4
+ ARM-ADS
+ 5060750::V5.06 update 6 (build 750)::ARMCC
+ 0
+
+
+ GD32F350R8
+ GigaDevice
+ GigaDevice.GD32F3x0_DFP.2.0.0
+ http://gd32mcu.21ic.com/data/documents/yingyongruanjian/
+ IRAM(0x20000000,0x04000) IROM(0x08000000,0x10000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE
+
+
+ UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F3x0 -FS08000000 -FL010000 -FP0($$Device:GD32F350R8$Flash\GD32F3x0.FLM))
+ 0
+ $$Device:GD32F350R8$Device\Include\gd32f3x0.h
+
+
+
+
+
+
+
+
+
+ $$Device:GD32F350R8$SVD\GD32F3x0.svd
+ 0
+ 0
+
+
+
+
+
+
+ 0
+ 0
+ 0
+ 0
+ 1
+
+ .\build\
+ rtthread-gd32f3x0
+ 1
+ 0
+ 1
+ 1
+ 0
+ .\build\
+ 1
+ 0
+ 0
+
+ 0
+ 0
+
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 0
+ 0
+
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 0
+ fromelf --bin !L --output rtthread.bin
+
+ 0
+ 0
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 3
+
+
+ 1
+
+
+ SARMCM3.DLL
+ -REMAP -MPU
+ DCM.DLL
+ -pCM4
+ SARMCM3.DLL
+ -MPU
+ TCM.DLL
+ -pCM4
+
+
+
+ 1
+ 0
+ 0
+ 0
+ 16
+
+
+
+
+ 1
+ 0
+ 0
+ 1
+ 1
+ 4096
+
+ 1
+ BIN\UL2CM3.DLL
+ "" ()
+
+
+
+
+ 0
+
+
+
+ 0
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 0
+ 1
+ 1
+ 0
+ 1
+ 1
+ 0
+ 0
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+ "Cortex-M4"
+
+ 0
+ 0
+ 0
+ 1
+ 1
+ 0
+ 0
+ 2
+ 0
+ 0
+ 0
+ 8
+ 0
+ 0
+ 0
+ 0
+ 3
+ 3
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x20000000
+ 0x4000
+
+
+ 1
+ 0x8000000
+ 0x10000
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 1
+ 0x0
+ 0x0
+
+
+ 1
+ 0x0
+ 0x0
+
+
+ 1
+ 0x0
+ 0x0
+
+
+ 1
+ 0x8000000
+ 0x20000
+
+
+ 1
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x20000000
+ 0x4000
+
+
+ 0
+ 0x0
+ 0x0
+
+
+
+
+
+ 1
+ 4
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+ 0
+
+
+ GD32F350, USE_STDPERIPH_DRIVER, __RTTHREAD__, __CLK_TCK=RT_TICK_PER_SECOND
+
+ applications;.;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m4;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;drivers;..\..\components\finsh;.;..\..\include;..\..\components\libc\compilers\common;..\..\components\libc\compilers\common\none-gcc;Libraries\CMSIS\GD\GD32F3x0\Include;Libraries\CMSIS;Libraries\GD32F3x0_standard_peripheral\Include;..\..\examples\utest\testcases\kernel
+
+
+
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0x08000000
+ 0x20000000
+
+ .\gd32_rom.ld
+
+
+
+
+
+
+
+
+
+
+ Applications
+
+
+ main.c
+ 1
+ applications\main.c
+
+
+
+
+ CPU
+
+
+ showmem.c
+ 1
+ ..\..\libcpu\arm\common\showmem.c
+
+
+ div0.c
+ 1
+ ..\..\libcpu\arm\common\div0.c
+
+
+ backtrace.c
+ 1
+ ..\..\libcpu\arm\common\backtrace.c
+
+
+ context_rvds.S
+ 2
+ ..\..\libcpu\arm\cortex-m4\context_rvds.S
+
+
+ cpuport.c
+ 1
+ ..\..\libcpu\arm\cortex-m4\cpuport.c
+
+
+
+
+ DeviceDrivers
+
+
+ pin.c
+ 1
+ ..\..\components\drivers\misc\pin.c
+
+
+ serial.c
+ 1
+ ..\..\components\drivers\serial\serial.c
+
+
+ completion.c
+ 1
+ ..\..\components\drivers\src\completion.c
+
+
+ workqueue.c
+ 1
+ ..\..\components\drivers\src\workqueue.c
+
+
+ ringblk_buf.c
+ 1
+ ..\..\components\drivers\src\ringblk_buf.c
+
+
+ waitqueue.c
+ 1
+ ..\..\components\drivers\src\waitqueue.c
+
+
+ ringbuffer.c
+ 1
+ ..\..\components\drivers\src\ringbuffer.c
+
+
+ dataqueue.c
+ 1
+ ..\..\components\drivers\src\dataqueue.c
+
+
+ pipe.c
+ 1
+ ..\..\components\drivers\src\pipe.c
+
+
+
+
+ Drivers
+
+
+ drv_gpio.c
+ 1
+ drivers\drv_gpio.c
+
+
+ drv_usart.c
+ 1
+ drivers\drv_usart.c
+
+
+ board.c
+ 1
+ drivers\board.c
+
+
+
+
+ finsh
+
+
+ finsh_node.c
+ 1
+ ..\..\components\finsh\finsh_node.c
+
+
+ finsh_parser.c
+ 1
+ ..\..\components\finsh\finsh_parser.c
+
+
+ cmd.c
+ 1
+ ..\..\components\finsh\cmd.c
+
+
+ finsh_vm.c
+ 1
+ ..\..\components\finsh\finsh_vm.c
+
+
+ shell.c
+ 1
+ ..\..\components\finsh\shell.c
+
+
+ finsh_var.c
+ 1
+ ..\..\components\finsh\finsh_var.c
+
+
+ finsh_compiler.c
+ 1
+ ..\..\components\finsh\finsh_compiler.c
+
+
+ finsh_heap.c
+ 1
+ ..\..\components\finsh\finsh_heap.c
+
+
+ finsh_ops.c
+ 1
+ ..\..\components\finsh\finsh_ops.c
+
+
+ msh.c
+ 1
+ ..\..\components\finsh\msh.c
+
+
+ finsh_error.c
+ 1
+ ..\..\components\finsh\finsh_error.c
+
+
+ finsh_token.c
+ 1
+ ..\..\components\finsh\finsh_token.c
+
+
+ finsh_init.c
+ 1
+ ..\..\components\finsh\finsh_init.c
+
+
+
+
+ Kernel
+
+
+ components.c
+ 1
+ ..\..\src\components.c
+
+
+ mem.c
+ 1
+ ..\..\src\mem.c
+
+
+ object.c
+ 1
+ ..\..\src\object.c
+
+
+ device.c
+ 1
+ ..\..\src\device.c
+
+
+ thread.c
+ 1
+ ..\..\src\thread.c
+
+
+ irq.c
+ 1
+ ..\..\src\irq.c
+
+
+ clock.c
+ 1
+ ..\..\src\clock.c
+
+
+ idle.c
+ 1
+ ..\..\src\idle.c
+
+
+ timer.c
+ 1
+ ..\..\src\timer.c
+
+
+ kservice.c
+ 1
+ ..\..\src\kservice.c
+
+
+ scheduler.c
+ 1
+ ..\..\src\scheduler.c
+
+
+ ipc.c
+ 1
+ ..\..\src\ipc.c
+
+
+ mempool.c
+ 1
+ ..\..\src\mempool.c
+
+
+
+
+ Libraries
+
+
+ gd32f3x0_dbg.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_dbg.c
+
+
+ gd32f3x0_dac.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_dac.c
+
+
+ gd32f3x0_timer.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_timer.c
+
+
+ gd32f3x0_rtc.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_rtc.c
+
+
+ gd32f3x0_exti.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_exti.c
+
+
+ gd32f3x0_i2c.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_i2c.c
+
+
+ gd32f3x0_gpio.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_gpio.c
+
+
+ gd32f3x0_fwdgt.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_fwdgt.c
+
+
+ system_gd32f3x0.c
+ 1
+ Libraries\CMSIS\GD\GD32F3x0\Source\system_gd32f3x0.c
+
+
+ gd32f3x0_cec.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_cec.c
+
+
+ gd32f3x0_wwdgt.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_wwdgt.c
+
+
+ gd32f3x0_ctc.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_ctc.c
+
+
+ gd32f3x0_rcu.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_rcu.c
+
+
+ gd32f3x0_dma.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_dma.c
+
+
+ gd32f3x0_spi.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_spi.c
+
+
+ gd32f3x0_syscfg.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_syscfg.c
+
+
+ startup_gd32f3x0.s
+ 2
+ Libraries\CMSIS\GD\GD32F3x0\Source\ARM\startup_gd32f3x0.s
+
+
+ gd32f3x0_misc.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_misc.c
+
+
+ gd32f3x0_fmc.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_fmc.c
+
+
+ gd32f3x0_usart.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_usart.c
+
+
+ gd32f3x0_adc.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_adc.c
+
+
+ gd32f3x0_crc.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_crc.c
+
+
+ gd32f3x0_tsi.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_tsi.c
+
+
+ gd32f3x0_pmu.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_pmu.c
+
+
+ gd32f3x0_cmp.c
+ 1
+ Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_cmp.c
+
+
+
+
+ ::CMSIS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bsp/gd32350r-eval/rtconfig.h b/bsp/gd32350r-eval/rtconfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..add7a07ad6b0c9a2d03a662909c7a4bbf26d36aa
--- /dev/null
+++ b/bsp/gd32350r-eval/rtconfig.h
@@ -0,0 +1,169 @@
+#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_USING_OVERFLOW_CHECK
+#define RT_USING_HOOK
+#define RT_USING_IDLE_HOOK
+#define RT_IDLE_HOOK_LIST_SIZE 4
+#define IDLE_THREAD_STACK_SIZE 256
+#define RT_USING_TIMER_SOFT
+#define RT_TIMER_THREAD_PRIO 4
+#define RT_TIMER_THREAD_STACK_SIZE 512
+
+/* kservice optimization */
+
+#define RT_DEBUG
+
+/* 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"
+#define RT_VER_NUM 0x40004
+
+/* RT-Thread Components */
+
+#define RT_USING_COMPONENTS_INIT
+#define RT_USING_USER_MAIN
+#define RT_MAIN_THREAD_STACK_SIZE 2048
+#define RT_MAIN_THREAD_PRIORITY 10
+
+/* 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
+#define FINSH_ARG_MAX 10
+
+/* Device virtual file system */
+
+
+/* Device Drivers */
+
+#define RT_USING_DEVICE_IPC
+#define RT_PIPE_BUFSZ 512
+#define RT_USING_SERIAL
+#define RT_USING_SERIAL_V1
+#define RT_SERIAL_USING_DMA
+#define RT_SERIAL_RB_BUFSZ 64
+#define RT_USING_PIN
+
+/* Using USB */
+
+
+/* POSIX layer and C standard library */
+
+
+/* Network */
+
+/* Socket abstraction layer */
+
+
+/* Network interface device */
+
+
+/* light weight TCP/IP stack */
+
+
+/* AT commands */
+
+
+/* VBUS(Virtual Software BUS) */
+
+
+/* Utilities */
+
+
+/* RT-Thread Utestcases */
+
+
+/* RT-Thread online packages */
+
+/* IoT - internet of things */
+
+
+/* Wi-Fi */
+
+/* Marvell WiFi */
+
+
+/* Wiced WiFi */
+
+
+/* IoT Cloud */
+
+
+/* security packages */
+
+
+/* language packages */
+
+
+/* multimedia packages */
+
+
+/* tools packages */
+
+
+/* system packages */
+
+/* acceleration: Assembly language or algorithmic acceleration packages */
+
+
+/* Micrium: Micrium software products porting for RT-Thread */
+
+
+/* peripheral libraries and drivers */
+
+
+/* AI packages */
+
+
+/* miscellaneous packages */
+
+
+/* samples: kernel and components samples */
+
+
+/* entertainment: terminal games and other interesting software packages */
+
+#define SOC_GD32350R
+#define BSP_USING_UART0
+
+#endif
diff --git a/bsp/gd32350r-eval/rtconfig.py b/bsp/gd32350r-eval/rtconfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..1db5d5c2ba47eacbdaf8be20fd16c7d96166ff16
--- /dev/null
+++ b/bsp/gd32350r-eval/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')
+if os.getenv('RTT_ROOT'):
+ RTT_ROOT = os.getenv('RTT_ROOT')
+
+# cross_tool provides the cross compiler
+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'D:/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 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -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.fp'
+ CFLAGS = DEVICE + ' --apcs=interwork --cpu Cortex-M4.fp'
+ AFLAGS = DEVICE
+ LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-gd32.map --scatter gd32_rom.sct'
+
+ CFLAGS += ' -I' + EXEC_PATH + '/ARM/RV31/INC'
+ LFLAGS += ' --libpath ' + EXEC_PATH + '/ARM/RV31/LIB'
+
+ EXEC_PATH += '/arm/bin40/'
+
+ 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'
+
+ 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 = ''
diff --git a/bsp/gd32350r-eval/template.uvoptx b/bsp/gd32350r-eval/template.uvoptx
new file mode 100644
index 0000000000000000000000000000000000000000..96b3c092db005e6ee70eadd94c476caaad65b220
--- /dev/null
+++ b/bsp/gd32350r-eval/template.uvoptx
@@ -0,0 +1,190 @@
+
+
+
+ 1.0
+
+ ### uVision Project, (C) Keil Software
+
+
+ *.c
+ *.s*; *.src; *.a*
+ *.obj; *.o
+ *.lib
+ *.txt; *.h; *.inc
+ *.plm
+ *.cpp
+ 0
+
+
+
+ 0
+ 0
+
+
+
+ rt-thread_gd32f30x
+ 0x4
+ ARM-ADS
+
+ 12000000
+
+ 1
+ 1
+ 0
+ 1
+ 0
+
+
+ 1
+ 65535
+ 0
+ 0
+ 0
+
+
+ 79
+ 66
+ 8
+ .\build\
+
+
+ 1
+ 1
+ 1
+ 0
+ 1
+ 1
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+
+
+ 1
+ 0
+ 1
+
+ 255
+
+ 0
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 0
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+ 1
+ 0
+ 0
+ 3
+
+
+
+
+
+
+
+
+
+
+ BIN\CMSIS_AGDI.dll
+
+
+
+ 0
+ CMSIS_AGDI
+ -X"Any" -UAny -O206 -S0 -C0 -P00 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F3x0.FLM -FS08000000 -FL020000 -FP0($$Device:GD32F350R8$Flash\GD32F3x0.FLM)
+
+
+ 0
+ UL2CM3
+ UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0GD32F3x0 -FL010000 -FS08000000 -FP0($$Device:GD32F350R8$Flash\GD32F3x0.FLM)
+
+
+ 0
+ JL2CM3
+ -U59401765 -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 -FF0GD32F4xx_3MB.FLM -FS08000000 -FL0300000 -FP0($$Device:GD32F450ZK$Flash\GD32F4xx_3MB.FLM)
+
+
+
+
+ 0
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+ ::CMSIS
+ 0
+ 0
+ 0
+ 1
+
+
+
diff --git a/bsp/gd32350r-eval/template.uvprojx b/bsp/gd32350r-eval/template.uvprojx
new file mode 100644
index 0000000000000000000000000000000000000000..101d86a95500ff10d7fa726eb958cad49b9c8297
--- /dev/null
+++ b/bsp/gd32350r-eval/template.uvprojx
@@ -0,0 +1,401 @@
+
+
+
+ 2.1
+
+ ### uVision Project, (C) Keil Software
+
+
+
+ rt-thread_gd32f30x
+ 0x4
+ ARM-ADS
+ 0
+
+
+ GD32F350R8
+ GigaDevice
+ GigaDevice.GD32F3x0_DFP.2.0.0
+ http://gd32mcu.21ic.com/data/documents/yingyongruanjian/
+ IRAM(0x20000000,0x04000) IROM(0x08000000,0x10000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE
+
+
+ UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F3x0 -FS08000000 -FL010000 -FP0($$Device:GD32F350R8$Flash\GD32F3x0.FLM))
+ 0
+ $$Device:GD32F350R8$Device\Include\gd32f3x0.h
+
+
+
+
+
+
+
+
+
+ $$Device:GD32F350R8$SVD\GD32F3x0.svd
+ 0
+ 0
+
+
+
+
+
+
+ 0
+ 0
+ 0
+ 0
+ 1
+
+ .\build\
+ rtthread-gd32f3x0
+ 1
+ 0
+ 1
+ 1
+ 0
+ .\build\
+ 1
+ 0
+ 0
+
+ 0
+ 0
+
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 0
+ 0
+
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 0
+ fromelf --bin !L --output rtthread.bin
+
+ 0
+ 0
+ 0
+ 0
+
+ 0
+
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 3
+
+
+ 1
+
+
+ SARMCM3.DLL
+ -REMAP -MPU
+ DCM.DLL
+ -pCM4
+ SARMCM3.DLL
+ -MPU
+ TCM.DLL
+ -pCM4
+
+
+
+ 1
+ 0
+ 0
+ 0
+ 16
+
+
+
+
+ 1
+ 0
+ 0
+ 1
+ 1
+ 4096
+
+ 1
+ BIN\UL2CM3.DLL
+ "" ()
+
+
+
+
+ 0
+
+
+
+ 0
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 0
+ 1
+ 1
+ 0
+ 1
+ 1
+ 0
+ 0
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+ "Cortex-M4"
+
+ 0
+ 0
+ 0
+ 1
+ 1
+ 0
+ 0
+ 2
+ 0
+ 0
+ 0
+ 8
+ 0
+ 0
+ 0
+ 0
+ 3
+ 3
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x20000000
+ 0x4000
+
+
+ 1
+ 0x8000000
+ 0x10000
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 1
+ 0x0
+ 0x0
+
+
+ 1
+ 0x0
+ 0x0
+
+
+ 1
+ 0x0
+ 0x0
+
+
+ 1
+ 0x8000000
+ 0x20000
+
+
+ 1
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x0
+ 0x0
+
+
+ 0
+ 0x20000000
+ 0x4000
+
+
+ 0
+ 0x0
+ 0x0
+
+
+
+
+
+ 1
+ 4
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 1
+ 1
+ 1
+ 1
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0x08000000
+ 0x20000000
+
+ .\gd32_rom.ld
+
+
+
+
+
+
+
+
+
+
+ ::CMSIS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+