[add]add gd32350r-eval bsp

This commit is contained in:
RiceChen 2021-06-18 22:34:45 +08:00
parent 82f3a84ec8
commit f02ebb3661
103 changed files with 39814 additions and 0 deletions

555
bsp/gd32350r-eval/.config Normal file
View File

@ -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

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
<component name="EventRecorderStub" version="1.0.0"/> <!--name and version of the component-->
<events>
</events>
</component_viewer>

37
bsp/gd32350r-eval/Kconfig Normal file
View File

@ -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

View File

@ -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 <stdint.h>
/* 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

View File

@ -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 <stdint.h>
/* system clock frequency (core clock) */
extern uint32_t SystemCoreClock;
/* function declarations */
/* initialize the system and update the SystemCoreClock variable */
extern void SystemInit (void);
/* update the SystemCoreClock with current core clock retrieved from cpu registers */
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* SYSTEM_GD32F3X0_H */

View File

@ -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.
;*/
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000400
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; /* reset Vector Mapped to at Address 0 */
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD 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

View File

@ -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

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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 <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/* not yet supported */
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM4_SIMD_H */

View File

@ -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 <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#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 */

View File

@ -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 <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

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

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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));
}
}

View File

@ -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;
}
}

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

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

View File

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

View File

@ -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) (&REG32(((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 */

View File

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

View File

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

View File

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

View File

@ -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 <wchar.h>
#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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}

View File

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

View File

@ -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;
}

View File

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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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')

View File

@ -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
<RT-Thread -- GD32F350R8T6>
msh >
```
## 驱动支持情况及计划
| 驱动 | 支持情况 | 备注 |
| --------- | -------- | :------------------------: |
| UART | 支持 | UART0~1 |
| GPIO | 支持 | ALL |
## 联系人信息
维护人:[RiceChen](https://gitee.com/RiceChen0)
邮箱980307037@qq.com

View File

@ -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')

View File

@ -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)

View File

@ -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')

View File

@ -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 <stdio.h>
#include <rtthread.h>
#include "rtdevice.h"
int main(void)
{
rt_kprintf("\n<RT-Thread -- GD32F350R8T6>\n\n");
return 0;
}

View File

@ -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')

View File

@ -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 <stdint.h>
#include <rthw.h>
#include <rtthread.h>
#include <gd32f3x0.h>
#include <board.h>
#include <drv_usart.h>
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler */
/* User can add his own implementation to report the HAL error return state */
while (1)
{
}
/* USER CODE END Error_Handler */
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
NVIC_SetPriority(SysTick_IRQn, 0);
}
/**
* This is the timer interrupt service routine.
*
*/
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
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
}
/*@}*/

View File

@ -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 <gd32f3x0.h>
#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 */
// <o> Internal SRAM memory size[Kbytes] <8-64>
// <i>Default: 64
#ifdef __ICCARM__
// Use *.icf ram symbal, to avoid hardcode.
extern char __ICFEDIT_region_RAM_end__;
#define GD32_SRAM_END &__ICFEDIT_region_RAM_end__
#else
#define GD32_SRAM_SIZE 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 >>> ***

View File

@ -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 <rtdevice.h>
#include <rthw.h>
#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

View File

@ -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

View File

@ -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 <rthw.h>
#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

View File

@ -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 <rtthread.h>
#include <rtdevice.h>
#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

View File

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

View File

@ -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 };

View File

@ -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) }
}

View File

@ -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)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,782 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
<SchemaVersion>2.1</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header>
<Targets>
<Target>
<TargetName>rt-thread_gd32f30x</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed>
<uAC6>0</uAC6>
<TargetOption>
<TargetCommonOption>
<Device>GD32F350R8</Device>
<Vendor>GigaDevice</Vendor>
<PackID>GigaDevice.GD32F3x0_DFP.2.0.0</PackID>
<PackURL>http://gd32mcu.21ic.com/data/documents/yingyongruanjian/</PackURL>
<Cpu>IRAM(0x20000000,0x04000) IROM(0x08000000,0x10000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile>
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F3x0 -FS08000000 -FL010000 -FP0($$Device:GD32F350R8$Flash\GD32F3x0.FLM))</FlashDriverDll>
<DeviceId>0</DeviceId>
<RegisterFile>$$Device:GD32F350R8$Device\Include\gd32f3x0.h</RegisterFile>
<MemoryEnv></MemoryEnv>
<Cmp></Cmp>
<Asm></Asm>
<Linker></Linker>
<OHString></OHString>
<InfinionOptionDll></InfinionOptionDll>
<SLE66CMisc></SLE66CMisc>
<SLE66AMisc></SLE66AMisc>
<SLE66LinkerMisc></SLE66LinkerMisc>
<SFDFile>$$Device:GD32F350R8$SVD\GD32F3x0.svd</SFDFile>
<bCustSvd>0</bCustSvd>
<UseEnv>0</UseEnv>
<BinPath></BinPath>
<IncludePath></IncludePath>
<LibPath></LibPath>
<RegisterFilePath></RegisterFilePath>
<DBRegisterFilePath></DBRegisterFilePath>
<TargetStatus>
<Error>0</Error>
<ExitCodeStop>0</ExitCodeStop>
<ButtonStop>0</ButtonStop>
<NotGenerated>0</NotGenerated>
<InvalidFlash>1</InvalidFlash>
</TargetStatus>
<OutputDirectory>.\build\</OutputDirectory>
<OutputName>rtthread-gd32f3x0</OutputName>
<CreateExecutable>1</CreateExecutable>
<CreateLib>0</CreateLib>
<CreateHexFile>1</CreateHexFile>
<DebugInformation>1</DebugInformation>
<BrowseInformation>0</BrowseInformation>
<ListingPath>.\build\</ListingPath>
<HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K>
<CreateBatchFile>0</CreateBatchFile>
<BeforeCompile>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopU1X>0</nStopU1X>
<nStopU2X>0</nStopU2X>
</BeforeCompile>
<BeforeMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopB1X>0</nStopB1X>
<nStopB2X>0</nStopB2X>
</BeforeMake>
<AfterMake>
<RunUserProg1>1</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name>fromelf --bin !L --output rtthread.bin</UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopA1X>0</nStopA1X>
<nStopA2X>0</nStopA2X>
</AfterMake>
<SelectedForBatchBuild>0</SelectedForBatchBuild>
<SVCSIdString></SVCSIdString>
</TargetCommonOption>
<CommonProperty>
<UseCPPCompiler>0</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>0</GenerateAssemblyFile>
<AssembleAssemblyFile>0</AssembleAssemblyFile>
<PublicsOnly>0</PublicsOnly>
<StopOnExitCode>3</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<DllOption>
<SimDllName>SARMCM3.DLL</SimDllName>
<SimDllArguments> -REMAP -MPU</SimDllArguments>
<SimDlgDll>DCM.DLL</SimDlgDll>
<SimDlgDllArguments>-pCM4</SimDlgDllArguments>
<TargetDllName>SARMCM3.DLL</TargetDllName>
<TargetDllArguments> -MPU</TargetDllArguments>
<TargetDlgDll>TCM.DLL</TargetDlgDll>
<TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
</DllOption>
<DebugOption>
<OPTHX>
<HexSelection>1</HexSelection>
<HexRangeLowAddress>0</HexRangeLowAddress>
<HexRangeHighAddress>0</HexRangeHighAddress>
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
</DebugOption>
<Utilities>
<Flash1>
<UseTargetDll>1</UseTargetDll>
<UseExternalTool>0</UseExternalTool>
<RunIndependent>0</RunIndependent>
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
<Capability>1</Capability>
<DriverSelection>4096</DriverSelection>
</Flash1>
<bUseTDR>1</bUseTDR>
<Flash2>BIN\UL2CM3.DLL</Flash2>
<Flash3>"" ()</Flash3>
<Flash4></Flash4>
<pFcarmOut></pFcarmOut>
<pFcarmGrp></pFcarmGrp>
<pFcArmRoot></pFcArmRoot>
<FcArmLst>0</FcArmLst>
</Utilities>
<TargetArmAds>
<ArmAdsMisc>
<GenerateListings>0</GenerateListings>
<asHll>1</asHll>
<asAsm>1</asAsm>
<asMacX>1</asMacX>
<asSyms>1</asSyms>
<asFals>1</asFals>
<asDbgD>1</asDbgD>
<asForm>1</asForm>
<ldLst>0</ldLst>
<ldmm>1</ldmm>
<ldXref>1</ldXref>
<BigEnd>0</BigEnd>
<AdsALst>1</AdsALst>
<AdsACrf>1</AdsACrf>
<AdsANop>0</AdsANop>
<AdsANot>0</AdsANot>
<AdsLLst>1</AdsLLst>
<AdsLmap>1</AdsLmap>
<AdsLcgr>1</AdsLcgr>
<AdsLsym>1</AdsLsym>
<AdsLszi>1</AdsLszi>
<AdsLtoi>1</AdsLtoi>
<AdsLsun>1</AdsLsun>
<AdsLven>1</AdsLven>
<AdsLsxf>1</AdsLsxf>
<RvctClst>0</RvctClst>
<GenPPlst>0</GenPPlst>
<AdsCpuType>"Cortex-M4"</AdsCpuType>
<RvctDeviceName></RvctDeviceName>
<mOS>0</mOS>
<uocRom>0</uocRom>
<uocRam>0</uocRam>
<hadIROM>1</hadIROM>
<hadIRAM>1</hadIRAM>
<hadXRAM>0</hadXRAM>
<uocXRam>0</uocXRam>
<RvdsVP>2</RvdsVP>
<RvdsMve>0</RvdsMve>
<hadIRAM2>0</hadIRAM2>
<hadIROM2>0</hadIROM2>
<StupSel>8</StupSel>
<useUlib>0</useUlib>
<EndSel>0</EndSel>
<uLtcg>0</uLtcg>
<nSecure>0</nSecure>
<RoSelD>3</RoSelD>
<RwSelD>3</RwSelD>
<CodeSel>0</CodeSel>
<OptFeed>0</OptFeed>
<NoZi1>0</NoZi1>
<NoZi2>0</NoZi2>
<NoZi3>0</NoZi3>
<NoZi4>0</NoZi4>
<NoZi5>0</NoZi5>
<Ro1Chk>0</Ro1Chk>
<Ro2Chk>0</Ro2Chk>
<Ro3Chk>0</Ro3Chk>
<Ir1Chk>1</Ir1Chk>
<Ir2Chk>0</Ir2Chk>
<Ra1Chk>0</Ra1Chk>
<Ra2Chk>0</Ra2Chk>
<Ra3Chk>0</Ra3Chk>
<Im1Chk>1</Im1Chk>
<Im2Chk>0</Im2Chk>
<OnChipMemories>
<Ocm1>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm1>
<Ocm2>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm2>
<Ocm3>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm3>
<Ocm4>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm4>
<Ocm5>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm5>
<Ocm6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm6>
<IRAM>
<Type>0</Type>
<StartAddress>0x20000000</StartAddress>
<Size>0x4000</Size>
</IRAM>
<IROM>
<Type>1</Type>
<StartAddress>0x8000000</StartAddress>
<Size>0x10000</Size>
</IROM>
<XRAM>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</XRAM>
<OCR_RVCT1>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT1>
<OCR_RVCT2>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT2>
<OCR_RVCT3>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT3>
<OCR_RVCT4>
<Type>1</Type>
<StartAddress>0x8000000</StartAddress>
<Size>0x20000</Size>
</OCR_RVCT4>
<OCR_RVCT5>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT5>
<OCR_RVCT6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT6>
<OCR_RVCT7>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT7>
<OCR_RVCT8>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT8>
<OCR_RVCT9>
<Type>0</Type>
<StartAddress>0x20000000</StartAddress>
<Size>0x4000</Size>
</OCR_RVCT9>
<OCR_RVCT10>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT10>
</OnChipMemories>
<RvctStartVector></RvctStartVector>
</ArmAdsMisc>
<Cads>
<interw>1</interw>
<Optim>4</Optim>
<oTime>0</oTime>
<SplitLS>0</SplitLS>
<OneElfS>0</OneElfS>
<Strict>0</Strict>
<EnumInt>0</EnumInt>
<PlainCh>0</PlainCh>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<wLevel>0</wLevel>
<uThumb>0</uThumb>
<uSurpInc>0</uSurpInc>
<uC99>1</uC99>
<uGnu>0</uGnu>
<useXO>0</useXO>
<v6Lang>1</v6Lang>
<v6LangP>1</v6LangP>
<vShortEn>1</vShortEn>
<vShortWch>1</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>GD32F350, USE_STDPERIPH_DRIVER, __RTTHREAD__, __CLK_TCK=RT_TICK_PER_SECOND</Define>
<Undefine></Undefine>
<IncludePath>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</IncludePath>
</VariousControls>
</Cads>
<Aads>
<interw>1</interw>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<thumb>0</thumb>
<SplitLS>0</SplitLS>
<SwStkChk>0</SwStkChk>
<NoWarn>0</NoWarn>
<uSurpInc>0</uSurpInc>
<useXO>0</useXO>
<uClangAs>0</uClangAs>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Aads>
<LDads>
<umfTarg>1</umfTarg>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<noStLib>0</noStLib>
<RepFail>1</RepFail>
<useFile>0</useFile>
<TextAddressRange>0x08000000</TextAddressRange>
<DataAddressRange>0x20000000</DataAddressRange>
<pXoBase></pXoBase>
<ScatterFile>.\gd32_rom.ld</ScatterFile>
<IncludeLibs></IncludeLibs>
<IncludeLibsPath></IncludeLibsPath>
<Misc></Misc>
<LinkerInputFile></LinkerInputFile>
<DisabledWarnings></DisabledWarnings>
</LDads>
</TargetArmAds>
</TargetOption>
<Groups>
<Group>
<GroupName>Applications</GroupName>
<Files>
<File>
<FileName>main.c</FileName>
<FileType>1</FileType>
<FilePath>applications\main.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>CPU</GroupName>
<Files>
<File>
<FileName>showmem.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\showmem.c</FilePath>
</File>
<File>
<FileName>div0.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\div0.c</FilePath>
</File>
<File>
<FileName>backtrace.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\backtrace.c</FilePath>
</File>
<File>
<FileName>context_rvds.S</FileName>
<FileType>2</FileType>
<FilePath>..\..\libcpu\arm\cortex-m4\context_rvds.S</FilePath>
</File>
<File>
<FileName>cpuport.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\cortex-m4\cpuport.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>DeviceDrivers</GroupName>
<Files>
<File>
<FileName>pin.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\misc\pin.c</FilePath>
</File>
<File>
<FileName>serial.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\serial\serial.c</FilePath>
</File>
<File>
<FileName>completion.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\completion.c</FilePath>
</File>
<File>
<FileName>workqueue.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\workqueue.c</FilePath>
</File>
<File>
<FileName>ringblk_buf.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\ringblk_buf.c</FilePath>
</File>
<File>
<FileName>waitqueue.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\waitqueue.c</FilePath>
</File>
<File>
<FileName>ringbuffer.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\ringbuffer.c</FilePath>
</File>
<File>
<FileName>dataqueue.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\dataqueue.c</FilePath>
</File>
<File>
<FileName>pipe.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\pipe.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Drivers</GroupName>
<Files>
<File>
<FileName>drv_gpio.c</FileName>
<FileType>1</FileType>
<FilePath>drivers\drv_gpio.c</FilePath>
</File>
<File>
<FileName>drv_usart.c</FileName>
<FileType>1</FileType>
<FilePath>drivers\drv_usart.c</FilePath>
</File>
<File>
<FileName>board.c</FileName>
<FileType>1</FileType>
<FilePath>drivers\board.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>finsh</GroupName>
<Files>
<File>
<FileName>finsh_node.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_node.c</FilePath>
</File>
<File>
<FileName>finsh_parser.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_parser.c</FilePath>
</File>
<File>
<FileName>cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\cmd.c</FilePath>
</File>
<File>
<FileName>finsh_vm.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_vm.c</FilePath>
</File>
<File>
<FileName>shell.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\shell.c</FilePath>
</File>
<File>
<FileName>finsh_var.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_var.c</FilePath>
</File>
<File>
<FileName>finsh_compiler.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_compiler.c</FilePath>
</File>
<File>
<FileName>finsh_heap.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_heap.c</FilePath>
</File>
<File>
<FileName>finsh_ops.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_ops.c</FilePath>
</File>
<File>
<FileName>msh.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\msh.c</FilePath>
</File>
<File>
<FileName>finsh_error.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_error.c</FilePath>
</File>
<File>
<FileName>finsh_token.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_token.c</FilePath>
</File>
<File>
<FileName>finsh_init.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\finsh\finsh_init.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Kernel</GroupName>
<Files>
<File>
<FileName>components.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\components.c</FilePath>
</File>
<File>
<FileName>mem.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\mem.c</FilePath>
</File>
<File>
<FileName>object.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\object.c</FilePath>
</File>
<File>
<FileName>device.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\device.c</FilePath>
</File>
<File>
<FileName>thread.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\thread.c</FilePath>
</File>
<File>
<FileName>irq.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\irq.c</FilePath>
</File>
<File>
<FileName>clock.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\clock.c</FilePath>
</File>
<File>
<FileName>idle.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\idle.c</FilePath>
</File>
<File>
<FileName>timer.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\timer.c</FilePath>
</File>
<File>
<FileName>kservice.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\kservice.c</FilePath>
</File>
<File>
<FileName>scheduler.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\scheduler.c</FilePath>
</File>
<File>
<FileName>ipc.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\ipc.c</FilePath>
</File>
<File>
<FileName>mempool.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\mempool.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Libraries</GroupName>
<Files>
<File>
<FileName>gd32f3x0_dbg.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_dbg.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_dac.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_dac.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_timer.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_timer.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_rtc.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_rtc.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_exti.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_exti.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_i2c.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_i2c.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_gpio.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_gpio.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_fwdgt.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_fwdgt.c</FilePath>
</File>
<File>
<FileName>system_gd32f3x0.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\CMSIS\GD\GD32F3x0\Source\system_gd32f3x0.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_cec.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_cec.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_wwdgt.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_wwdgt.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_ctc.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_ctc.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_rcu.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_rcu.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_dma.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_dma.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_spi.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_spi.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_syscfg.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_syscfg.c</FilePath>
</File>
<File>
<FileName>startup_gd32f3x0.s</FileName>
<FileType>2</FileType>
<FilePath>Libraries\CMSIS\GD\GD32F3x0\Source\ARM\startup_gd32f3x0.s</FilePath>
</File>
<File>
<FileName>gd32f3x0_misc.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_misc.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_fmc.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_fmc.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_usart.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_usart.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_adc.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_adc.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_crc.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_crc.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_tsi.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_tsi.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_pmu.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_pmu.c</FilePath>
</File>
<File>
<FileName>gd32f3x0_cmp.c</FileName>
<FileType>1</FileType>
<FilePath>Libraries\GD32F3x0_standard_peripheral\Source\gd32f3x0_cmp.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>::CMSIS</GroupName>
</Group>
</Groups>
</Target>
</Targets>
<RTE>
<apis/>
<components>
<component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.4.0" condition="ARMv6_7_8-M Device">
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.7.0"/>
<targetInfos>
<targetInfo name="rt-thread_gd32f30x"/>
</targetInfos>
</component>
</components>
<files/>
</RTE>
</Project>

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More