diff --git a/bsp/gd32vf103v-eval/.cproject b/bsp/gd32vf103v-eval/.cproject new file mode 100644 index 0000000000000000000000000000000000000000..aea4ab4f37f3563c9dd351367d96f22f3a42c6bb --- /dev/null +++ b/bsp/gd32vf103v-eval/.cproject @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/gd32vf103v-eval/.gitignore b/bsp/gd32vf103v-eval/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..69c708b7c787f7d859fc24708891b047136c4699 --- /dev/null +++ b/bsp/gd32vf103v-eval/.gitignore @@ -0,0 +1 @@ +/GD32VF103xB/ diff --git a/bsp/gd32vf103v-eval/.project b/bsp/gd32vf103v-eval/.project new file mode 100644 index 0000000000000000000000000000000000000000..ee79a7f74b375a8275d059d4b01bbdccd90b5add --- /dev/null +++ b/bsp/gd32vf103v-eval/.project @@ -0,0 +1,88 @@ + + + GD32V103V_EVAL + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + rt-thread + 2 + virtual:/virtual + + + rt-thread/components + 2 + virtual:/virtual + + + rt-thread/include + 2 + $%7BPARENT-2-PROJECT_LOC%7D/include + + + rt-thread/lipcpu + 2 + virtual:/virtual + + + rt-thread/src + 2 + $%7BPARENT-2-PROJECT_LOC%7D/src + + + rt-thread/components/drivers + 2 + virtual:/virtual + + + rt-thread/components/finsh + 2 + $%7BPARENT-2-PROJECT_LOC%7D/components/finsh + + + rt-thread/components/src + 2 + $%7BPARENT-2-PROJECT_LOC%7D/components/drivers/src + + + rt-thread/lipcpu/bumblebee + 2 + $%7BPARENT-2-PROJECT_LOC%7D/libcpu/risc-v/bumblebee + + + rt-thread/lipcpu/common + 2 + $%7BPARENT-2-PROJECT_LOC%7D/libcpu/risc-v/common + + + rt-thread/components/drivers/include + 2 + $%7BPARENT-2-PROJECT_LOC%7D/components/drivers/include + + + rt-thread/components/drivers/serial + 2 + $%7BPARENT-2-PROJECT_LOC%7D/components/drivers/serial + + + diff --git a/bsp/gd32vf103v-eval/.settings/ilg.gnumcueclipse.debug.gdbjtag.openocd.prefs b/bsp/gd32vf103v-eval/.settings/ilg.gnumcueclipse.debug.gdbjtag.openocd.prefs new file mode 100644 index 0000000000000000000000000000000000000000..4405a95acf5239a0c0ac18991dd2be4dcc6b7877 --- /dev/null +++ b/bsp/gd32vf103v-eval/.settings/ilg.gnumcueclipse.debug.gdbjtag.openocd.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +install.folder=E\:\\GD32\\GD32VF103\\GD32VF103SDK\\GDM32501_SDK\\IDE\\eclipse_toolchain\\openocd\\0.10.0-12-20190618-0815\\bin diff --git a/bsp/gd32vf103v-eval/.settings/ilg.gnumcueclipse.managedbuild.cross.prefs b/bsp/gd32vf103v-eval/.settings/ilg.gnumcueclipse.managedbuild.cross.prefs new file mode 100644 index 0000000000000000000000000000000000000000..ad2ccabb4b83e57f3346ca8ba9d3939bccf4b26d --- /dev/null +++ b/bsp/gd32vf103v-eval/.settings/ilg.gnumcueclipse.managedbuild.cross.prefs @@ -0,0 +1,2 @@ +buildTools.path=E\:\\GD32\\GD32VF103\\GD32VF103SDK\\GDM32501_SDK\\IDE\\eclipse_toolchain\\BuildTools\\2.10-20180103-1919\\bin +eclipse.preferences.version=1 diff --git a/bsp/gd32vf103v-eval/.settings/ilg.gnumcueclipse.managedbuild.cross.riscv.prefs b/bsp/gd32vf103v-eval/.settings/ilg.gnumcueclipse.managedbuild.cross.riscv.prefs new file mode 100644 index 0000000000000000000000000000000000000000..85f8498577d25fa6f720c577a07df4761462ed2f --- /dev/null +++ b/bsp/gd32vf103v-eval/.settings/ilg.gnumcueclipse.managedbuild.cross.riscv.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +toolchain.path.512258282=E\:\\GD32\\GD32VF103\\GD32VF103SDK\\GDM32501_SDK\\IDE\\eclipse_toolchain\\RISC-VEmbeddedGCC\\riscv64-unknown-elf-gcc-8.2.0-2019.02.0-x86_64-w64-mingw32\\bin diff --git a/bsp/gd32vf103v-eval/.settings/language.settings.xml b/bsp/gd32vf103v-eval/.settings/language.settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..931634b7b0e46710426dbd497afe9a5687744baa --- /dev/null +++ b/bsp/gd32vf103v-eval/.settings/language.settings.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/bsp/gd32vf103v-eval/Kconfig b/bsp/gd32vf103v-eval/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..223a0f5becab759176d9861a5b9a3296816e835e --- /dev/null +++ b/bsp/gd32vf103v-eval/Kconfig @@ -0,0 +1,20 @@ +mainmenu "RT-Thread Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config RTT_DIR + string + option env="RTT_ROOT" + default "../.." + +config PKGS_DIR + string + option env="PKGS_ROOT" + default "packages" + +source "$RTT_DIR/Kconfig" +source "$PKGS_DIR/Kconfig" +source "board/Kconfig" diff --git a/bsp/gd32vf103v-eval/README.md b/bsp/gd32vf103v-eval/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7c65c15b7862b4efb19fbd4e9d266d523a3e1d4a --- /dev/null +++ b/bsp/gd32vf103v-eval/README.md @@ -0,0 +1,185 @@ +# HIFIVE1 # + +## 简介 + +[HIFIVE1](https://www.sifive.com/products/hifive1/) 是由 SiFive 公司推出的全球首款基于开源指令集 RISC-V 架构的商用 SoC Freedom E310 的开发板。 + +![1538284005769](figures/board.png) + + + +### 板载资源: + +| 硬件 | 描述 | +| -- | -- | +|Soc| SiFive Freedom E310 (FE310) | +| 内核 | SiFive E31 RISC-V Core | +| 架构 | 32-bit RV32IMAC | +| 主频 | 320+ MHz | +| 性能 | 1.61 DMIPs/MHz, 2.73 Coremark/MHz | +|SRAM| 16KB | +|Flash| 16MB QSPI + 16KB 指令Cache | + +## 编译说明 + +### 下载 Freedom Studio + +Freedom Studio 是 SiFive 公司推出的一个集成开发环境,用来编写和调试基于 SiFive 处理器的软件。内嵌了编译好的 RISC-V GCC 工具链、OpenOCD、以及一些示例和文档。 + +下载地址:[官网下载](https://www.sifive.com/products/tools/) + +![1538295358180](figures/dowmload.png) + +下载成功之后,解压到和 rt-thread 源码同一目录下 + +![1538295750998](figures/untar.png) + +### 配置工具链 + +工具链就在解压开的 IDE `F:\FreedomStudio\SiFive\riscv64-unknown-elf-gcc-20171231-x86_64-w64-mingw32\bin` 目录下。 + +在源码 `rt-thread/bsp/hifive1/` 目录下,运行 env 工具,输入下面的命令设置 gcc 工具链路径 + +``` +set RTT_EXEC_PATH=F:\FreedomStudio\SiFive\riscv64-unknown-elf-gcc-20171231-x86_64-w64-mingw32\bin +``` + +### 添加环境变量 + +将 **工具链**和**编译工具**的路径 添加到环境变量里,输入命令如下 + +``` +set path=%path%;工具链的路径;编译工具的路径; +``` + +例如: + +``` +set path=%path%;F:\FreedomStudio\SiFive\riscv64-unknown-elf-gcc-20171231-x86_64-w64-mingw32\bin;F:\FreedomStudio\build-tools\bin +``` + +![1538296570129](figures/env.png) + +### 从 env 工具打开 IDE + +利用 cd 命令,切换到解压开的 IDE 目录 + +![1538296766437](figures/cd.png) + +输入 Freedom Studio 按 Tab 键 自动补全,然后按回车运行 IDE。 + +![1538296878924](figures/open_ide.png) + +在弹出的窗口输入 workspace 创建工作空间,然后点击启动打开 IDE。 + +![1538296978929](figures/ide.png) + +### 导入工程 + +在菜单栏点击 `File->Import` + +![1538297215062](figures/import.png) + +按照下面的图片导入工程 + +![1538297303505](figures/import2.png) + +![1538297553367](figures/import3.png) + + + +### 编译 + +![1538297679868](figures/build.png) + +然后等待编译完成 + +![1538297922206](figures/builded.png) + + + + +## 烧写及执行 + +### 安装驱动 + +1. 使用 Micro USB 线连接电脑和开发板。 + +2. 然后双击安装 IDE 目录 `F:\FreedomStudio\SiFive\Drivers` 下的驱动文件 + +### 添加字符串定义 + +点击菜单栏 `Window->preferences` 按下图的步骤将 字符串 `cross_prefix` 定义为 `riscv64-unknown-elf-` + +![1538298633528](figures/string.png) + +### 配置 Debug 参数 + +选中生成的 `rtthread.elf` 文件,右键配置 Debug 参数,如下图所示 + +![1538298914673](figures/debug.png) + +按下图新建一个 Debug 选项 + +![1538299063801](figures/debug1.png) + +打开 `Debugger` 选项卡 添加如下参数 + +``` +-f openocd.cfg + +set mem inaccessible-by-default off +set arch riscv:rv32 +set remotetimeout 250 +``` + +如下图所示: + +![1538299273874](figures/debug2.png) + +打开 `startup` 选项卡,去掉**主机模式**和**复位命令** + +![1538299521246](figures/debug3.png) + +然后待程序停止在 main 函数处,然后点击继续运行程序就运行起来了。 + +![1538299736730](figures/run.png) + +### 运行结果 + +下载程序之后,连接串口(115200-N-8-1),可以看到RT-Thread的输出信息: + +``` + \ | / +- RT - Thread Operating System + / | \ 3.0.4 build May 30 2018 + 2006 - 2018 Copyright by rt-thread team +msh > +``` + +## 4. 驱动支持情况及计划 + +| 驱动 | 支持情况 | 备注 | +| ------ | ---- | :------: | +| UART | 支持 | UART0_RX/TX:GPIO 16/17 | + + +### 4.1 IO在板级支持包中的映射情况 + +| IO号 | 板级包中的定义 | +| -- | -- | +| GPIO19 | LED_GREEN | +| GPIO21 | LED_BLUE | +| GPIO22 | LED_RED | + +## 5. 联系人信息 + +维护人: +- [tanek](https://github.com/TanekLiang) + +## 6. 参考 + +* [HIFIVE1 Info](https://www.sifive.com/products/hifive1/) +* [HIFIVE1 Software Development Tools](https://www.sifive.com/products/tools/) +* [hifive1-getting-started-guide](https://www.sifive.com/documentation/boards/hifive1/hifive1-getting-started-guide/) +* [hifive1-schematics](https://www.sifive.com/documentation/boards/hifive1/hifive1-schematics/) diff --git a/bsp/gd32vf103v-eval/SConscript b/bsp/gd32vf103v-eval/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..534ec8eb5a34d300b893b887a896b5e39e33b613 --- /dev/null +++ b/bsp/gd32vf103v-eval/SConscript @@ -0,0 +1,18 @@ +# for module compiling +import os +Import('RTT_ROOT') +from building import * + +cwd = str(Dir('#')) +src = Glob('*.c') +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')) + +group = DefineGroup('', src, depend = [''], CPPPATH = []) +#objs += group +Return('objs') diff --git a/bsp/gd32vf103v-eval/SConstruct b/bsp/gd32vf103v-eval/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..3caac2f35db63d3b0daa597e643d79fc390ae4a9 --- /dev/null +++ b/bsp/gd32vf103v-eval/SConstruct @@ -0,0 +1,30 @@ +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')] +from building import * + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) +env['ASCOM'] = env['ASPPCOM'] + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/gd32vf103v-eval/applications/SConscript b/bsp/gd32vf103v-eval/applications/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..ef1c39fd83245f317e1fb64035e62c169c430c62 --- /dev/null +++ b/bsp/gd32vf103v-eval/applications/SConscript @@ -0,0 +1,11 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd, ] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/gd32vf103v-eval/applications/main.c b/bsp/gd32vf103v-eval/applications/main.c new file mode 100644 index 0000000000000000000000000000000000000000..c411937c18148e62011da7be9b56af725d76a577 --- /dev/null +++ b/bsp/gd32vf103v-eval/applications/main.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-23 tyustli first version + */ + +#include +#include + +int main(int argc, char *argv[]) { + return RT_EOK; +} + +/******************** end of file *******************/ + diff --git a/bsp/gd32vf103v-eval/board/Kconfig b/bsp/gd32vf103v-eval/board/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..402b48b4aa2743d3d3b350201925eebcfd8c6fe9 --- /dev/null +++ b/bsp/gd32vf103v-eval/board/Kconfig @@ -0,0 +1,34 @@ +menu "Hardware Drivers Config" + +config SOC_STM32F429IG + bool + select SOC_SERIES_STM32F4 + default y + +menu "Onboard Peripheral Drivers" + + config BSP_USING_USART + bool "Enable USART (usart0)" + select BSP_USING_UART + select BSP_USING_UART0 + default y +endmenu + +menu "On-chip Peripheral Drivers" + + menuconfig BSP_USING_UART + bool "Enable UART" + default y + select RT_USING_SERIAL + if BSP_USING_UART + config BSP_USING_UART0 + bool "Enable UART0" + default y + endif +endmenu + +menu "Board extended module Drivers" + +endmenu + +endmenu diff --git a/bsp/gd32vf103v-eval/board/SConscript b/bsp/gd32vf103v-eval/board/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..afdaecc64275ec518261534f5298b4b7aab0870b --- /dev/null +++ b/bsp/gd32vf103v-eval/board/SConscript @@ -0,0 +1,11 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/gd32vf103v-eval/board/board.c b/bsp/gd32vf103v-eval/board/board.c new file mode 100644 index 0000000000000000000000000000000000000000..6e666c281c83e5c00b40438bae94ec46c4725354 --- /dev/null +++ b/bsp/gd32vf103v-eval/board/board.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-23 tyustli first version + * + */ + +#include +#include +#include "board.h" + +#ifdef RT_USING_SERIAL +#include +#endif + +/* System Tick Configuration */ +static void systick_config(rt_uint32_t ticks) { + /* set value */ + *(rt_uint64_t *) (TMR_CTRL_ADDR + TMR_MTIMECMP) = ticks; + /* enable interrupt */ + eclic_irq_enable(CLIC_INT_TMR, 0, 0); + /* clear value */ + *(rt_uint64_t *) (TMR_CTRL_ADDR + TMR_MTIME) = 0; +} + +/* This is the timer interrupt service routine. */ +void eclic_mtip_handler(void) { + /* clear value */ + *(rt_uint64_t *) (TMR_CTRL_ADDR + TMR_MTIME) = 0; + + /* enter interrupt */ + rt_interrupt_enter(); + /* tick increase */ + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +void rt_hw_board_init(void) { + systick_config(TMR_FREQ / RT_TICK_PER_SECOND); + +#ifdef RT_USING_HEAP + rt_system_heap_init((void *) HEAP_BEGIN, (void *) HEAP_END); +#endif + + /* USART driver initialization is open by default */ +#ifdef RT_USING_SERIAL + rt_hw_usart_init(); +#endif + + /* Set the shell console output device */ +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + + /* Board underlying hardware initialization */ +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif +} + +/******************** end of file *******************/ + diff --git a/bsp/gd32vf103v-eval/board/board.h b/bsp/gd32vf103v-eval/board/board.h new file mode 100644 index 0000000000000000000000000000000000000000..422634fc3845a9c08a8731fe43c384b370a52358 --- /dev/null +++ b/bsp/gd32vf103v-eval/board/board.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-23 tyustli first version + * + */ + +#ifndef __BOARD__ +#define __BOARD__ +#include "gd32vf103.h" + +extern void *_end; +extern void *_heap_end; +#define HEAP_BEGIN &_end +#define HEAP_END &_heap_end + +void rt_hw_board_init(void); + +#endif /* __BOARD__ */ + +/******************** end of file *******************/ diff --git a/bsp/gd32vf103v-eval/board/gd32vf103_libopt.h b/bsp/gd32vf103v-eval/board/gd32vf103_libopt.h new file mode 100644 index 0000000000000000000000000000000000000000..ca292d265930bcc41dd0b50c8f13a64240cd45c7 --- /dev/null +++ b/bsp/gd32vf103v-eval/board/gd32vf103_libopt.h @@ -0,0 +1,64 @@ +/*! + \file gd32vf103_libopt.h + \brief library optional for gd32vf103 + + \version 2019-6-5, V1.0.0, demo for GD32VF103 + */ + +/* + 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 GD32VF103_LIBOPT_H +#define GD32VF103_LIBOPT_H + +#include "gd32vf103_adc.h" +#include "gd32vf103_bkp.h" +#include "gd32vf103_can.h" +#include "gd32vf103_crc.h" +#include "gd32vf103_dac.h" +#include "gd32vf103_dma.h" +#include "gd32vf103_eclic.h" +#include "gd32vf103_exmc.h" +#include "gd32vf103_exti.h" +#include "gd32vf103_fmc.h" +#include "gd32vf103_gpio.h" +#include "gd32vf103_i2c.h" +#include "gd32vf103_fwdgt.h" +#include "gd32vf103_dbg.h" +#include "gd32vf103_pmu.h" +#include "gd32vf103_rcu.h" +#include "gd32vf103_rtc.h" +#include "gd32vf103_spi.h" +#include "gd32vf103_timer.h" +#include "gd32vf103_usart.h" +#include "gd32vf103_wwdgt.h" +#include "n22_func.h" + +#endif /* GD32VF103_LIBOPT_H */ + +/******************** end of file *******************/ + diff --git a/bsp/gd32vf103v-eval/drivers/SConscript b/bsp/gd32vf103v-eval/drivers/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..975bcd5d5da3e65b53a2af7ed8b4ee91a93c0418 --- /dev/null +++ b/bsp/gd32vf103v-eval/drivers/SConscript @@ -0,0 +1,19 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Split(''' +drv_uart.c +''') +CPPPATH = [cwd] + +if GetDepend('RT_USING_PIN'): + src += ['drv_gpio.c'] + +if GetDepend('RT_USING_I2C'): + src += ['drv_i2c.c'] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/gd32vf103v-eval/drivers/drv_usart.c b/bsp/gd32vf103v-eval/drivers/drv_usart.c new file mode 100644 index 0000000000000000000000000000000000000000..b093ebe5aa897bf26960ccd9967a5582a304042d --- /dev/null +++ b/bsp/gd32vf103v-eval/drivers/drv_usart.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-23 tyustli first version + */ + +#include + +#ifdef RT_USING_SERIAL + +#if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) \ + && !defined(BSP_USING_UART3) && !defined(BSP_USING_UART4) && !defined(BSP_USING_UART5) + #error "Please define at least one BSP_USING_UARTx" + /* this driver can be disabled at menuconfig RT-Thread Components Device Drivers */ +#endif + +struct gd32_usart { + char *name; + rt_uint32_t usart_base; + rt_uint32_t usart_clk; + rt_uint32_t gpio_clk; + rt_uint32_t gpio_port; + rt_uint32_t tx_pin; + rt_uint32_t rx_pin; + IRQn_Type irqn; + struct rt_serial_device serial; +}; + +enum { +#ifdef BSP_USING_UART0 + GDUSART0_INDEX, +#endif +}; + +static struct gd32_usart usart_config[] = { +#ifdef BSP_USING_UART0 + { "uart0", + USART0, RCU_USART0, RCU_GPIOA, + GPIOA, + GPIO_PIN_9, + GPIO_PIN_10, USART0_IRQn, }, +#endif + }; + +static rt_err_t gd32_configure(struct rt_serial_device *serial, + struct serial_configure *cfg) { + struct gd32_usart *usart; + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + usart = (struct gd32_usart *) serial->parent.user_data; + RT_ASSERT(usart != RT_NULL); + + /* enable GPIO clock */ + rcu_periph_clock_enable(usart->gpio_clk); + /* enable USART clock */ + rcu_periph_clock_enable(usart->usart_clk); + /* connect port to USARTx_Tx */ + gpio_init(usart->gpio_port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, + usart->tx_pin); + /* connect port to USARTx_Rx */ + gpio_init(usart->gpio_port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, + usart->rx_pin); + + usart_deinit(usart->usart_base); + usart_baudrate_set(usart->usart_base, cfg->baud_rate); + + switch (cfg->data_bits) { + case DATA_BITS_8: + usart_word_length_set(usart->usart_base, USART_WL_8BIT); + break; + + case DATA_BITS_9: + usart_word_length_set(usart->usart_base, USART_WL_9BIT); + break; + default: + usart_word_length_set(usart->usart_base, USART_WL_8BIT); + break; + } + + switch (cfg->stop_bits) { + case STOP_BITS_1: + usart_stop_bit_set(usart->usart_base, USART_STB_1BIT); + break; + case STOP_BITS_2: + usart_stop_bit_set(usart->usart_base, USART_STB_2BIT); + break; + default: + usart_stop_bit_set(usart->usart_base, USART_STB_1BIT); + break; + } + + switch (cfg->parity) { + case PARITY_NONE: + usart_parity_config(usart->usart_base, USART_PM_NONE); + break; + case PARITY_ODD: + usart_parity_config(usart->usart_base, USART_PM_ODD); + break; + case PARITY_EVEN: + usart_parity_config(usart->usart_base, USART_PM_EVEN); + break; + default: + usart_parity_config(usart->usart_base, USART_PM_NONE); + break; + } + usart_hardware_flow_rts_config(usart->usart_base, USART_RTS_DISABLE); + usart_hardware_flow_cts_config(usart->usart_base, USART_RTS_DISABLE); + usart_receive_config(usart->usart_base, USART_RECEIVE_ENABLE); + usart_transmit_config(usart->usart_base, USART_TRANSMIT_ENABLE); + usart_enable(usart->usart_base); + + return RT_EOK; +} + +static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, + void *arg) { + struct gd32_usart *usart; + + RT_ASSERT(serial != RT_NULL); + usart = (struct gd32_usart *) serial->parent.user_data; + RT_ASSERT(usart != RT_NULL); + + switch (cmd) { + case RT_DEVICE_CTRL_CLR_INT: + eclic_irq_disable(usart->usart_base); + usart_interrupt_disable(usart->usart_base, USART_INT_RBNE); + break; + case RT_DEVICE_CTRL_SET_INT: + eclic_set_nlbits(ECLIC_GROUP_LEVEL3_PRIO1); + eclic_irq_enable(usart->irqn, 1, 0); + /* enable USART0 receive interrupt */ + usart_interrupt_enable(usart->usart_base, USART_INT_RBNE); + break; + } + + return RT_EOK; +} + +static int gd32_putc(struct rt_serial_device *serial, char ch) { + struct gd32_usart *usart; + + RT_ASSERT(serial != RT_NULL); + usart = (struct gd32_usart *) serial->parent.user_data; + RT_ASSERT(usart != RT_NULL); + + usart_data_transmit(usart->usart_base, (uint8_t) ch); + while (usart_flag_get(usart->usart_base, USART_FLAG_TBE) == RESET) + ; + + return 1; +} + +static int gd32_getc(struct rt_serial_device *serial) { + int ch; + struct gd32_usart *usart; + + RT_ASSERT(serial != RT_NULL); + usart = (struct gd32_usart *) serial->parent.user_data; + RT_ASSERT(usart != RT_NULL); + + ch = -1; + if (RESET != usart_flag_get(usart->usart_base, USART_FLAG_RBNE)) { + ch = usart_data_receive(usart->usart_base) & 0xff; + } + + return ch; +} + +static const struct rt_uart_ops gd32_usart_ops = { gd32_configure, gd32_control, + gd32_putc, gd32_getc, + RT_NULL }; + +static void usart_isr(struct rt_serial_device *serial) { + struct gd32_usart *usart; + + RT_ASSERT(serial != RT_NULL); + + usart = (struct gd32_usart *) serial->parent.user_data; + RT_ASSERT(usart != RT_NULL); + + if ((usart_interrupt_flag_get(usart->usart_base, USART_INT_FLAG_RBNE) + != RESET) + && (RESET != usart_flag_get(usart->usart_base, USART_FLAG_RBNE))) { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + usart_interrupt_flag_clear(usart->usart_base, USART_INT_FLAG_RBNE); + usart_flag_clear(usart->usart_base, USART_FLAG_RBNE); + } else { + if (usart_flag_get(usart->usart_base, USART_FLAG_CTSF) != RESET) { + usart_flag_clear(usart->usart_base, USART_FLAG_CTSF); + } + + if (usart_flag_get(usart->usart_base, USART_FLAG_LBDF) != RESET) { + usart_flag_clear(usart->usart_base, USART_FLAG_LBDF); + } + + if (usart_flag_get(usart->usart_base, USART_FLAG_TC) != RESET) { + usart_flag_clear(usart->usart_base, USART_FLAG_TC); + } + } +} +#ifdef BSP_USING_UART0 + +void USART0_IRQHandler(void) { + rt_interrupt_enter(); + + usart_isr(&usart_config[GDUSART0_INDEX].serial); + + rt_interrupt_leave(); +} + +#endif + +int rt_hw_usart_init(void) { + rt_size_t obj_num; + int index; + + obj_num = sizeof(usart_config) / sizeof(struct gd32_usart); + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + rt_err_t result = 0; + + for (index = 0; index < obj_num; index++) { + usart_config[index].serial.ops = &gd32_usart_ops; + usart_config[index].serial.config = config; + + /* register UART device */ + result = rt_hw_serial_register(&usart_config[index].serial, + usart_config[index].name, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX + | RT_DEVICE_FLAG_INT_TX, &usart_config[index]); + RT_ASSERT(result == RT_EOK); + } + + return result; +} + +#endif /* RT_USING_SERIAL */ + +/******************** end of file *******************/ diff --git a/bsp/gd32vf103v-eval/drivers/drv_usart.h b/bsp/gd32vf103v-eval/drivers/drv_usart.h new file mode 100644 index 0000000000000000000000000000000000000000..d4883262ed42bf8c6c5f1d56b43bda9a447ce84d --- /dev/null +++ b/bsp/gd32vf103v-eval/drivers/drv_usart.h @@ -0,0 +1,12 @@ +#ifndef __DRV_UART_H__ +#define __DRV_UART_H__ + +#include +#include +#include "board.h" + +int rt_hw_usart_init(void); + +#endif /* __DRV_USART_H__ */ + +/******************* end of file *******************/ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_adc.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..316c021a3f9c9f9d683cd1baa0de9095f198865d --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_adc.h @@ -0,0 +1,396 @@ +/*! + \file gd32vf103_adc.h + \brief definitions for the ADC + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_ADC_H +#define GD32VF103_ADC_H + +#include "gd32vf103.h" + +/* ADC definitions */ +#define ADC0 ADC_BASE +#define ADC1 (ADC_BASE + 0x400U) + +/* registers definitions */ +#define ADC_STAT(adcx) REG32((adcx) + 0x00U) /*!< ADC status register */ +#define ADC_CTL0(adcx) REG32((adcx) + 0x04U) /*!< ADC control register 0 */ +#define ADC_CTL1(adcx) REG32((adcx) + 0x08U) /*!< ADC control register 1 */ +#define ADC_SAMPT0(adcx) REG32((adcx) + 0x0CU) /*!< ADC sampling time register 0 */ +#define ADC_SAMPT1(adcx) REG32((adcx) + 0x10U) /*!< ADC sampling time register 1 */ +#define ADC_IOFF0(adcx) REG32((adcx) + 0x14U) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1(adcx) REG32((adcx) + 0x18U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2(adcx) REG32((adcx) + 0x1CU) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3(adcx) REG32((adcx) + 0x20U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WDHT(adcx) REG32((adcx) + 0x24U) /*!< ADC watchdog high threshold register */ +#define ADC_WDLT(adcx) REG32((adcx) + 0x28U) /*!< ADC watchdog low threshold register */ +#define ADC_RSQ0(adcx) REG32((adcx) + 0x2CU) /*!< ADC regular sequence register 0 */ +#define ADC_RSQ1(adcx) REG32((adcx) + 0x30U) /*!< ADC regular sequence register 1 */ +#define ADC_RSQ2(adcx) REG32((adcx) + 0x34U) /*!< ADC regular sequence register 2 */ +#define ADC_ISQ(adcx) REG32((adcx) + 0x38U) /*!< ADC inserted sequence register */ +#define ADC_IDATA0(adcx) REG32((adcx) + 0x3CU) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1(adcx) REG32((adcx) + 0x40U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2(adcx) REG32((adcx) + 0x44U) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3(adcx) REG32((adcx) + 0x48U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA(adcx) REG32((adcx) + 0x4CU) /*!< ADC regular data register */ +#define ADC_OVSCR(adcx) REG32((adcx) + 0x80U) /*!< ADC oversample 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 */ +#define ADC_STAT_EOIC BIT(2) /*!< inserted channel end of conversion */ +#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_SYNCM BITS(16,19) /*!< sync mode selection */ +#define ADC_CTL0_IWDEN BIT(22) /*!< analog watchdog enable on inserted channels */ +#define ADC_CTL0_RWDEN BIT(23) /*!< analog watchdog enable on regular channels */ + +/* 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 conversion mode for inserted channels */ +#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) /*!< channel 16 and 17 enable of ADC0 */ + +/* ADC_SAMPTx x=0..1 */ +#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel n 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) /*!< nth conversion in regular sequence */ +#define ADC_RSQ0_RL BITS(20,23) /*!< regular channel sequence length */ + +/* ADC_ISQ */ +#define ADC_ISQ_ISQN BITS(0,4) /*!< nth conversion in inserted sequence */ +#define ADC_ISQ_IL BITS(20,21) /*!< inserted sequence length */ + +/* ADC_IDATAx x=0..3*/ +#define ADC_IDATAX_IDATAN BITS(0,15) /*!< inserted data n */ + +/* ADC_RDATA */ +#define ADC_RDATA_RDATA BITS(0,15) /*!< regular data */ +#define ADC_RDATA_ADC1RDTR BITS(16,31) /*!< ADC1 regular channel data */ + +/* ADC_OVSCR */ +#define ADC_OVSCR_OVSEN BIT(0) /*!< oversampling enable */ +#define ADC_OVSCR_OVSR BITS(2,4) /*!< oversampling ratio */ +#define ADC_OVSCR_OVSS BITS(5,8) /*!< oversampling shift */ +#define ADC_OVSCR_TOVS BIT(9) /*!< triggered oversampling */ +#define ADC_OVSCR_DRES BITS(12,13) /*!< ADC data resolution */ + +/* constants definitions */ +/* adc_stat register value */ +#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of conversion */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< inserted channel end of conversion */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< inserted channel start flag */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< regular channel start flag */ + +/* adc_ctl0 register value */ +#define CTL0_DISNUM(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< write value to ADC_CTL0_DISNUM bit field */ + +/* scan mode */ +#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */ + +/* inserted channel group convert automatically */ +#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted channel group convert automatically */ + +/* ADC sync mode */ +#define CTL0_SYNCM(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) /*!< write value to ADC_CTL0_SYNCM bit field */ +#define ADC_MODE_FREE CTL0_SYNCM(0) /*!< all the ADCs work independently */ +#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL CTL0_SYNCM(1) /*!< ADC0 and ADC1 work in combined regular parallel + inserted parallel mode */ +#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION CTL0_SYNCM(2) /*!< ADC0 and ADC1 work in combined regular parallel + trigger rotation mode */ +#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST CTL0_SYNCM(3) /*!< ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode */ +#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW CTL0_SYNCM(4) /*!< ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode */ +#define ADC_DAUL_INSERTED_PARALLEL CTL0_SYNCM(5) /*!< ADC0 and ADC1 work in inserted parallel mode only */ +#define ADC_DAUL_REGULAL_PARALLEL CTL0_SYNCM(6) /*!< ADC0 and ADC1 work in regular parallel mode only */ +#define ADC_DAUL_REGULAL_FOLLOWUP_FAST CTL0_SYNCM(7) /*!< ADC0 and ADC1 work in follow-up fast mode only */ +#define ADC_DAUL_REGULAL_FOLLOWUP_SLOW CTL0_SYNCM(8) /*!< ADC0 and ADC1 work in follow-up slow mode only */ +#define ADC_DAUL_INSERTED_TRIGGER_ROTATION CTL0_SYNCM(9) /*!< ADC0 and ADC1 work in trigger rotation mode only */ + +/* adc_ctl1 register value */ +#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */ +#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */ + +/* continuous mode */ +#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ + +/* external trigger select for regular channel */ +#define CTL1_ETSRC(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) /*!< write value to ADC_CTL1_ETSRC bit field */ +/* for ADC0 and ADC1 regular channel */ +#define ADC0_1_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< TIMER0 CH0 event select */ +#define ADC0_1_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< TIMER0 CH1 event select */ +#define ADC0_1_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< TIMER0 CH2 event select */ +#define ADC0_1_EXTTRIG_REGULAR_T1_CH1 CTL1_ETSRC(3) /*!< TIMER1 CH1 event select */ +#define ADC0_1_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(4) /*!< TIMER2 TRGO event select */ +#define ADC0_1_EXTTRIG_REGULAR_T3_CH3 CTL1_ETSRC(5) /*!< TIMER3 CH3 event select */ +#define ADC0_1_EXTTRIG_REGULAR_EXTI_11 CTL1_ETSRC(6) /*!< external interrupt line 11 */ +#define ADC0_1_EXTTRIG_REGULAR_NONE CTL1_ETSRC(7) /*!< software trigger */ + +/* external trigger mode for inserted channel */ +#define CTL1_ETSIC(regval) (BITS(12,14) & ((uint32_t)(regval) << 12)) /*!< write value to ADC_CTL1_ETSIC bit field */ +/* for ADC0 and ADC1 inserted channel */ +#define ADC0_1_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(0) /*!< TIMER0 TRGO event select */ +#define ADC0_1_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(1) /*!< TIMER0 CH3 event select */ +#define ADC0_1_EXTTRIG_INSERTED_T1_TRGO CTL1_ETSIC(2) /*!< TIMER1 TRGO event select */ +#define ADC0_1_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(3) /*!< TIMER1 CH0 event select */ +#define ADC0_1_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(4) /*!< TIMER2 CH3 event select */ +#define ADC0_1_EXTTRIG_INSERTED_T3_TRGO CTL1_ETSIC(5) /*!< TIMER3 TRGO event select */ +#define ADC0_1_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(6) /*!< external interrupt line 15 */ +#define ADC0_1_EXTTRIG_INSERTED_NONE CTL1_ETSIC(7) /*!< software trigger */ + +/* adc_samptx register value */ +#define SAMPTX_SPT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_SAMPTX_SPT bit field */ +#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_ioffx register value */ +#define IOFFX_IOFF(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_IOFFX_IOFF bit field */ + +/* adc_wdht register value */ +#define WDHT_WDHT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDHT_WDHT bit field */ + +/* adc_wdlt register value */ +#define WDLT_WDLT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDLT_WDLT bit field */ + +/* adc_rsqx register value */ +#define RSQ0_RL(regval) (BITS(20,23) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_RSQ0_RL bit field */ + +/* adc_isq register value */ +#define ISQ_IL(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_ISQ_IL bit field */ + +/* 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 */ + +/* ADC interrupt */ +#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 */ + +/* ADC resolution definitions */ +#define OVSCR_DRES(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define ADC_RESOLUTION_12B OVSCR_DRES(0) /*!< 12-bit ADC resolution */ +#define ADC_RESOLUTION_10B OVSCR_DRES(1) /*!< 10-bit ADC resolution */ +#define ADC_RESOLUTION_8B OVSCR_DRES(2) /*!< 8-bit ADC resolution */ +#define ADC_RESOLUTION_6B OVSCR_DRES(3) /*!< 6-bit ADC resolution */ + +/* ADC oversampling mode */ +#define ADC_OVERSAMPLING_ALL_CONVERT 0 /*!< all oversampled conversions for a channel are done consecutively after a trigger */ +#define ADC_OVERSAMPLING_ONE_CONVERT 1 /*!< each oversampled conversion for a channel needs a trigger */ + +/* ADC oversampling shift */ +#define OVSCR_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) +#define ADC_OVERSAMPLING_SHIFT_NONE OVSCR_OVSS(0) /*!< no oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_1B OVSCR_OVSS(1) /*!< 1-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_2B OVSCR_OVSS(2) /*!< 2-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_3B OVSCR_OVSS(3) /*!< 3-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_4B OVSCR_OVSS(4) /*!< 4-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_5B OVSCR_OVSS(5) /*!< 5-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_6B OVSCR_OVSS(6) /*!< 6-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_7B OVSCR_OVSS(7) /*!< 7-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_8B OVSCR_OVSS(8) /*!< 8-bit oversampling shift */ + +/* ADC oversampling ratio */ +#define OVSCR_OVSR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) +#define ADC_OVERSAMPLING_RATIO_MUL2 OVSCR_OVSR(0) /*!< oversampling ratio X2 */ +#define ADC_OVERSAMPLING_RATIO_MUL4 OVSCR_OVSR(1) /*!< oversampling ratio X4 */ +#define ADC_OVERSAMPLING_RATIO_MUL8 OVSCR_OVSR(2) /*!< oversampling ratio X8 */ +#define ADC_OVERSAMPLING_RATIO_MUL16 OVSCR_OVSR(3) /*!< oversampling ratio X16 */ +#define ADC_OVERSAMPLING_RATIO_MUL32 OVSCR_OVSR(4) /*!< oversampling ratio X32 */ +#define ADC_OVERSAMPLING_RATIO_MUL64 OVSCR_OVSR(5) /*!< oversampling ratio X64 */ +#define ADC_OVERSAMPLING_RATIO_MUL128 OVSCR_OVSR(6) /*!< oversampling ratio X128 */ +#define ADC_OVERSAMPLING_RATIO_MUL256 OVSCR_OVSR(7) /*!< oversampling ratio X256 */ + +/* function declarations */ +/* initialization config */ +/* reset ADC */ +void adc_deinit(uint32_t adc_periph); +/* configure the ADC sync mode */ +void adc_mode_config(uint32_t mode); +/* enable or disable ADC special function */ +void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue); +/* configure ADC data alignment */ +void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment); +/* enable ADC interface */ +void adc_enable(uint32_t adc_periph); +/* disable ADC interface */ +void adc_disable(uint32_t adc_periph); +/* ADC calibration and reset calibration */ +void adc_calibration_enable(uint32_t adc_periph); +/* 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); + +/* DMA config */ +/* enable DMA request */ +void adc_dma_mode_enable(uint32_t adc_periph); +/* disable DMA request */ +void adc_dma_mode_disable(uint32_t adc_periph); + +/* regular group and inserted group config */ +/* configure ADC discontinuous mode */ +void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint8_t length); + +/* configure the length of regular channel group or inserted channel group */ +void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length); +/* configure ADC regular channel */ +void adc_regular_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time); +/* configure ADC inserted channel */ +void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time); +/* configure ADC inserted channel offset */ +void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset); + +/* configure ADC external trigger source */ +void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source); +/* configure ADC external trigger */ +void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue); +/* enable ADC software trigger */ +void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_channel_group); + +/* get channel data */ +/* read ADC regular group data register */ +uint16_t adc_regular_data_read(uint32_t adc_periph); +/* read ADC inserted group data register */ +uint16_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel); +/* read the last ADC0 and ADC1 conversion result data in sync mode */ +uint32_t adc_sync_mode_convert_value_read(void); + +/* watchdog config */ +/* configure ADC analog watchdog single channel */ +void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel); +/* configure ADC analog watchdog group channel */ +void adc_watchdog_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group); +/* disable ADC analog watchdog */ +void adc_watchdog_disable(uint32_t adc_periph); +/* configure ADC analog watchdog threshold */ +void adc_watchdog_threshold_config(uint32_t adc_periph, uint16_t low_threshold, uint16_t high_threshold); + +/* interrupt & flag functions */ +/* get the ADC flag bits */ +FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t adc_flag); +/* clear the ADC flag bits */ +void adc_flag_clear(uint32_t adc_periph, uint32_t adc_flag); +/* get the bit state of ADCx software start conversion */ +FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph); +/* get the bit state of ADCx software inserted channel start conversion */ +FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph); +/* get the ADC interrupt bits */ +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t adc_interrupt); +/* clear the ADC flag */ +void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t adc_interrupt); +/* enable ADC interrupt */ +void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt); +/* disable ADC interrupt */ +void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt); + +/* ADC resolution & oversample */ +/* ADC resolution config */ +void adc_resolution_config(uint32_t adc_periph, uint32_t resolution); +/* ADC oversample mode config */ +void adc_oversample_mode_config(uint32_t adc_periph, uint8_t mode, uint16_t shift, uint8_t ratio); +/* enable ADC oversample mode */ +void adc_oversample_mode_enable(uint32_t adc_periph); +/* disable ADC oversample mode */ +void adc_oversample_mode_disable(uint32_t adc_periph); + +#endif /* GD32VF103_ADC_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_bkp.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_bkp.h new file mode 100644 index 0000000000000000000000000000000000000000..a6e1a3fd9e514e8aaa2ed0ec8057e873f78b9e42 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_bkp.h @@ -0,0 +1,227 @@ +/*! + \file gd32vf103_bkp.h + \brief definitions for the BKP + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_BKP_H +#define GD32VF103_BKP_H + +#include "gd32vf103.h" + +/* BKP definitions */ +#define BKP BKP_BASE /*!< BKP base address */ + +/* registers definitions */ +#define BKP_DATA0 REG16((BKP) + 0x04U) /*!< BKP data register 0 */ +#define BKP_DATA1 REG16((BKP) + 0x08U) /*!< BKP data register 1 */ +#define BKP_DATA2 REG16((BKP) + 0x0CU) /*!< BKP data register 2 */ +#define BKP_DATA3 REG16((BKP) + 0x10U) /*!< BKP data register 3 */ +#define BKP_DATA4 REG16((BKP) + 0x14U) /*!< BKP data register 4 */ +#define BKP_DATA5 REG16((BKP) + 0x18U) /*!< BKP data register 5 */ +#define BKP_DATA6 REG16((BKP) + 0x1CU) /*!< BKP data register 6 */ +#define BKP_DATA7 REG16((BKP) + 0x20U) /*!< BKP data register 7 */ +#define BKP_DATA8 REG16((BKP) + 0x24U) /*!< BKP data register 8 */ +#define BKP_DATA9 REG16((BKP) + 0x28U) /*!< BKP data register 9 */ +#define BKP_DATA10 REG16((BKP) + 0x40U) /*!< BKP data register 10 */ +#define BKP_DATA11 REG16((BKP) + 0x44U) /*!< BKP data register 11 */ +#define BKP_DATA12 REG16((BKP) + 0x48U) /*!< BKP data register 12 */ +#define BKP_DATA13 REG16((BKP) + 0x4CU) /*!< BKP data register 13 */ +#define BKP_DATA14 REG16((BKP) + 0x50U) /*!< BKP data register 14 */ +#define BKP_DATA15 REG16((BKP) + 0x54U) /*!< BKP data register 15 */ +#define BKP_DATA16 REG16((BKP) + 0x58U) /*!< BKP data register 16 */ +#define BKP_DATA17 REG16((BKP) + 0x5CU) /*!< BKP data register 17 */ +#define BKP_DATA18 REG16((BKP) + 0x60U) /*!< BKP data register 18 */ +#define BKP_DATA19 REG16((BKP) + 0x64U) /*!< BKP data register 19 */ +#define BKP_DATA20 REG16((BKP) + 0x68U) /*!< BKP data register 20 */ +#define BKP_DATA21 REG16((BKP) + 0x6CU) /*!< BKP data register 21 */ +#define BKP_DATA22 REG16((BKP) + 0x70U) /*!< BKP data register 22 */ +#define BKP_DATA23 REG16((BKP) + 0x74U) /*!< BKP data register 23 */ +#define BKP_DATA24 REG16((BKP) + 0x78U) /*!< BKP data register 24 */ +#define BKP_DATA25 REG16((BKP) + 0x7CU) /*!< BKP data register 25 */ +#define BKP_DATA26 REG16((BKP) + 0x80U) /*!< BKP data register 26 */ +#define BKP_DATA27 REG16((BKP) + 0x84U) /*!< BKP data register 27 */ +#define BKP_DATA28 REG16((BKP) + 0x88U) /*!< BKP data register 28 */ +#define BKP_DATA29 REG16((BKP) + 0x8CU) /*!< BKP data register 29 */ +#define BKP_DATA30 REG16((BKP) + 0x90U) /*!< BKP data register 30 */ +#define BKP_DATA31 REG16((BKP) + 0x94U) /*!< BKP data register 31 */ +#define BKP_DATA32 REG16((BKP) + 0x98U) /*!< BKP data register 32 */ +#define BKP_DATA33 REG16((BKP) + 0x9CU) /*!< BKP data register 33 */ +#define BKP_DATA34 REG16((BKP) + 0xA0U) /*!< BKP data register 34 */ +#define BKP_DATA35 REG16((BKP) + 0xA4U) /*!< BKP data register 35 */ +#define BKP_DATA36 REG16((BKP) + 0xA8U) /*!< BKP data register 36 */ +#define BKP_DATA37 REG16((BKP) + 0xACU) /*!< BKP data register 37 */ +#define BKP_DATA38 REG16((BKP) + 0xB0U) /*!< BKP data register 38 */ +#define BKP_DATA39 REG16((BKP) + 0xB4U) /*!< BKP data register 39 */ +#define BKP_DATA40 REG16((BKP) + 0xB8U) /*!< BKP data register 40 */ +#define BKP_DATA41 REG16((BKP) + 0xBCU) /*!< BKP data register 41 */ +#define BKP_OCTL REG16((BKP) + 0x2CU) /*!< RTC signal output control register */ +#define BKP_TPCTL REG16((BKP) + 0x30U) /*!< tamper pin control register */ +#define BKP_TPCS REG16((BKP) + 0x34U) /*!< tamper control and status register */ + +/* bits definitions */ +/* BKP_DATA */ +#define BKP_DATA BITS(0,15) /*!< backup data */ + +/* BKP_OCTL */ +#define BKP_OCTL_RCCV BITS(0,6) /*!< RTC clock calibration value */ +#define BKP_OCTL_COEN BIT(7) /*!< RTC clock calibration output enable */ +#define BKP_OCTL_ASOEN BIT(8) /*!< RTC alarm or second signal output enable */ +#define BKP_OCTL_ROSEL BIT(9) /*!< RTC output selection */ + +/* BKP_TPCTL */ +#define BKP_TPCTL_TPEN BIT(0) /*!< tamper detection enable */ +#define BKP_TPCTL_TPAL BIT(1) /*!< tamper pin active level */ + +/* BKP_TPCS */ +#define BKP_TPCS_TER BIT(0) /*!< tamper event reset */ +#define BKP_TPCS_TIR BIT(1) /*!< tamper interrupt reset */ +#define BKP_TPCS_TPIE BIT(2) /*!< tamper interrupt enable */ +#define BKP_TPCS_TEF BIT(8) /*!< tamper event flag */ +#define BKP_TPCS_TIF BIT(9) /*!< tamper interrupt flag */ + +/* constants definitions */ +/* BKP data register number */ +typedef enum +{ + BKP_DATA_0 = 1, /*!< BKP data register 0 */ + BKP_DATA_1, /*!< BKP data register 1 */ + BKP_DATA_2, /*!< BKP data register 2 */ + BKP_DATA_3, /*!< BKP data register 3 */ + BKP_DATA_4, /*!< BKP data register 4 */ + BKP_DATA_5, /*!< BKP data register 5 */ + BKP_DATA_6, /*!< BKP data register 6 */ + BKP_DATA_7, /*!< BKP data register 7 */ + BKP_DATA_8, /*!< BKP data register 8 */ + BKP_DATA_9, /*!< BKP data register 9 */ + BKP_DATA_10, /*!< BKP data register 10 */ + BKP_DATA_11, /*!< BKP data register 11 */ + BKP_DATA_12, /*!< BKP data register 12 */ + BKP_DATA_13, /*!< BKP data register 13 */ + BKP_DATA_14, /*!< BKP data register 14 */ + BKP_DATA_15, /*!< BKP data register 15 */ + BKP_DATA_16, /*!< BKP data register 16 */ + BKP_DATA_17, /*!< BKP data register 17 */ + BKP_DATA_18, /*!< BKP data register 18 */ + BKP_DATA_19, /*!< BKP data register 19 */ + BKP_DATA_20, /*!< BKP data register 20 */ + BKP_DATA_21, /*!< BKP data register 21 */ + BKP_DATA_22, /*!< BKP data register 22 */ + BKP_DATA_23, /*!< BKP data register 23 */ + BKP_DATA_24, /*!< BKP data register 24 */ + BKP_DATA_25, /*!< BKP data register 25 */ + BKP_DATA_26, /*!< BKP data register 26 */ + BKP_DATA_27, /*!< BKP data register 27 */ + BKP_DATA_28, /*!< BKP data register 28 */ + BKP_DATA_29, /*!< BKP data register 29 */ + BKP_DATA_30, /*!< BKP data register 30 */ + BKP_DATA_31, /*!< BKP data register 31 */ + BKP_DATA_32, /*!< BKP data register 32 */ + BKP_DATA_33, /*!< BKP data register 33 */ + BKP_DATA_34, /*!< BKP data register 34 */ + BKP_DATA_35, /*!< BKP data register 35 */ + BKP_DATA_36, /*!< BKP data register 36 */ + BKP_DATA_37, /*!< BKP data register 37 */ + BKP_DATA_38, /*!< BKP data register 38 */ + BKP_DATA_39, /*!< BKP data register 39 */ + BKP_DATA_40, /*!< BKP data register 40 */ + BKP_DATA_41, /*!< BKP data register 41 */ +}bkp_data_register_enum; + +/* BKP register */ +#define BKP_DATA0_9(number) REG16((BKP) + 0x04U + (number) * 0x04U) +#define BKP_DATA10_41(number) REG16((BKP) + 0x40U + ((number)-10U) * 0x04U) + +/* get data of BKP data register */ +#define BKP_DATA_GET(regval) GET_BITS((uint32_t)(regval), 0, 15) + +/* RTC clock calibration value */ +#define OCTL_RCCV(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) + +/* RTC output selection */ +#define RTC_OUTPUT_ALARM_PULSE ((uint16_t)0x0000U) /*!< RTC alarm pulse is selected as the RTC output */ +#define RTC_OUTPUT_SECOND_PULSE ((uint16_t)0x0200U) /*!< RTC second pulse is selected as the RTC output */ + +/* tamper pin active level */ +#define TAMPER_PIN_ACTIVE_HIGH ((uint16_t)0x0000U) /*!< the tamper pin is active high */ +#define TAMPER_PIN_ACTIVE_LOW ((uint16_t)0x0002U) /*!< the tamper pin is active low */ + +/* tamper flag */ +#define BKP_FLAG_TAMPER BKP_TPCS_TEF /*!< tamper event flag */ + +/* tamper interrupt flag */ +#define BKP_INT_FLAG_TAMPER BKP_TPCS_TIF /*!< tamper interrupt flag */ + +/* function declarations */ +/* reset BKP registers */ +void bkp_deinit(void); +/* write BKP data register */ +void bkp_data_write(bkp_data_register_enum register_number, uint16_t data); +/* read BKP data register */ +uint16_t bkp_data_read(bkp_data_register_enum register_number); + +/* RTC related functions */ +/* enable RTC clock calibration output */ +void bkp_rtc_calibration_output_enable(void); +/* disable RTC clock calibration output */ +void bkp_rtc_calibration_output_disable(void); +/* enable RTC alarm or second signal output */ +void bkp_rtc_signal_output_enable(void); +/* disable RTC alarm or second signal output */ +void bkp_rtc_signal_output_disable(void); +/* select RTC output */ +void bkp_rtc_output_select(uint16_t outputsel); +/* set RTC clock calibration value */ +void bkp_rtc_calibration_value_set(uint8_t value); + +/* tamper pin related functions */ +/* enable tamper pin detection */ +void bkp_tamper_detection_enable(void); +/* disable tamper pin detection */ +void bkp_tamper_detection_disable(void); +/* set tamper pin active level */ +void bkp_tamper_active_level_set(uint16_t level); + +/* interrupt & flag functions */ +/* enable tamper interrupt */ +void bkp_interrupt_enable(void); +/* disable tamper interrupt */ +void bkp_interrupt_disable(void); +/* get tamper flag state */ +FlagStatus bkp_flag_get(void); +/* clear tamper flag state */ +void bkp_flag_clear(void); +/* get tamper interrupt flag state */ +FlagStatus bkp_interrupt_flag_get(void); +/* clear tamper interrupt flag state */ +void bkp_interrupt_flag_clear(void); + +#endif /* GD32VF103_BKP_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_can.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_can.h new file mode 100644 index 0000000000000000000000000000000000000000..db12a5f982c7613c67b2edd17302c43f51151043 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_can.h @@ -0,0 +1,717 @@ +/*! + \file gd32vf103_can.h + \brief definitions for the CAN + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_CAN_H +#define GD32VF103_CAN_H + +#include "gd32vf103.h" + +/* CAN definitions */ +#define CAN0 CAN_BASE /*!< CAN0 base address */ +#define CAN1 (CAN0 + 0x00000400U) /*!< CAN1 base address */ + +/* registers definitions */ +#define CAN_CTL(canx) REG32((canx) + 0x00U) /*!< CAN control register */ +#define CAN_STAT(canx) REG32((canx) + 0x04U) /*!< CAN status register */ +#define CAN_TSTAT(canx) REG32((canx) + 0x08U) /*!< CAN transmit status register*/ +#define CAN_RFIFO0(canx) REG32((canx) + 0x0CU) /*!< CAN receive FIFO0 register */ +#define CAN_RFIFO1(canx) REG32((canx) + 0x10U) /*!< CAN receive FIFO1 register */ +#define CAN_INTEN(canx) REG32((canx) + 0x14U) /*!< CAN interrupt enable register */ +#define CAN_ERR(canx) REG32((canx) + 0x18U) /*!< CAN error register */ +#define CAN_BT(canx) REG32((canx) + 0x1CU) /*!< CAN bit timing register */ +#define CAN_TMI0(canx) REG32((canx) + 0x180U) /*!< CAN transmit mailbox0 identifier register */ +#define CAN_TMP0(canx) REG32((canx) + 0x184U) /*!< CAN transmit mailbox0 property register */ +#define CAN_TMDATA00(canx) REG32((canx) + 0x188U) /*!< CAN transmit mailbox0 data0 register */ +#define CAN_TMDATA10(canx) REG32((canx) + 0x18CU) /*!< CAN transmit mailbox0 data1 register */ +#define CAN_TMI1(canx) REG32((canx) + 0x190U) /*!< CAN transmit mailbox1 identifier register */ +#define CAN_TMP1(canx) REG32((canx) + 0x194U) /*!< CAN transmit mailbox1 property register */ +#define CAN_TMDATA01(canx) REG32((canx) + 0x198U) /*!< CAN transmit mailbox1 data0 register */ +#define CAN_TMDATA11(canx) REG32((canx) + 0x19CU) /*!< CAN transmit mailbox1 data1 register */ +#define CAN_TMI2(canx) REG32((canx) + 0x1A0U) /*!< CAN transmit mailbox2 identifier register */ +#define CAN_TMP2(canx) REG32((canx) + 0x1A4U) /*!< CAN transmit mailbox2 property register */ +#define CAN_TMDATA02(canx) REG32((canx) + 0x1A8U) /*!< CAN transmit mailbox2 data0 register */ +#define CAN_TMDATA12(canx) REG32((canx) + 0x1ACU) /*!< CAN transmit mailbox2 data1 register */ +#define CAN_RFIFOMI0(canx) REG32((canx) + 0x1B0U) /*!< CAN receive FIFO0 mailbox identifier register */ +#define CAN_RFIFOMP0(canx) REG32((canx) + 0x1B4U) /*!< CAN receive FIFO0 mailbox property register */ +#define CAN_RFIFOMDATA00(canx) REG32((canx) + 0x1B8U) /*!< CAN receive FIFO0 mailbox data0 register */ +#define CAN_RFIFOMDATA10(canx) REG32((canx) + 0x1BCU) /*!< CAN receive FIFO0 mailbox data1 register */ +#define CAN_RFIFOMI1(canx) REG32((canx) + 0x1C0U) /*!< CAN receive FIFO1 mailbox identifier register */ +#define CAN_RFIFOMP1(canx) REG32((canx) + 0x1C4U) /*!< CAN receive FIFO1 mailbox property register */ +#define CAN_RFIFOMDATA01(canx) REG32((canx) + 0x1C8U) /*!< CAN receive FIFO1 mailbox data0 register */ +#define CAN_RFIFOMDATA11(canx) REG32((canx) + 0x1CCU) /*!< CAN receive FIFO1 mailbox data1 register */ +#define CAN_FCTL(canx) REG32((canx) + 0x200U) /*!< CAN filter control register */ +#define CAN_FMCFG(canx) REG32((canx) + 0x204U) /*!< CAN filter mode register */ +#define CAN_FSCFG(canx) REG32((canx) + 0x20CU) /*!< CAN filter scale register */ +#define CAN_FAFIFO(canx) REG32((canx) + 0x214U) /*!< CAN filter associated FIFO register */ +#define CAN_FW(canx) REG32((canx) + 0x21CU) /*!< CAN filter working register */ +#define CAN_F0DATA0(canx) REG32((canx) + 0x240U) /*!< CAN filter 0 data 0 register */ +#define CAN_F1DATA0(canx) REG32((canx) + 0x248U) /*!< CAN filter 1 data 0 register */ +#define CAN_F2DATA0(canx) REG32((canx) + 0x250U) /*!< CAN filter 2 data 0 register */ +#define CAN_F3DATA0(canx) REG32((canx) + 0x258U) /*!< CAN filter 3 data 0 register */ +#define CAN_F4DATA0(canx) REG32((canx) + 0x260U) /*!< CAN filter 4 data 0 register */ +#define CAN_F5DATA0(canx) REG32((canx) + 0x268U) /*!< CAN filter 5 data 0 register */ +#define CAN_F6DATA0(canx) REG32((canx) + 0x270U) /*!< CAN filter 6 data 0 register */ +#define CAN_F7DATA0(canx) REG32((canx) + 0x278U) /*!< CAN filter 7 data 0 register */ +#define CAN_F8DATA0(canx) REG32((canx) + 0x280U) /*!< CAN filter 8 data 0 register */ +#define CAN_F9DATA0(canx) REG32((canx) + 0x288U) /*!< CAN filter 9 data 0 register */ +#define CAN_F10DATA0(canx) REG32((canx) + 0x290U) /*!< CAN filter 10 data 0 register */ +#define CAN_F11DATA0(canx) REG32((canx) + 0x298U) /*!< CAN filter 11 data 0 register */ +#define CAN_F12DATA0(canx) REG32((canx) + 0x2A0U) /*!< CAN filter 12 data 0 register */ +#define CAN_F13DATA0(canx) REG32((canx) + 0x2A8U) /*!< CAN filter 13 data 0 register */ +#define CAN_F14DATA0(canx) REG32((canx) + 0x2B0U) /*!< CAN filter 14 data 0 register */ +#define CAN_F15DATA0(canx) REG32((canx) + 0x2B8U) /*!< CAN filter 15 data 0 register */ +#define CAN_F16DATA0(canx) REG32((canx) + 0x2C0U) /*!< CAN filter 16 data 0 register */ +#define CAN_F17DATA0(canx) REG32((canx) + 0x2C8U) /*!< CAN filter 17 data 0 register */ +#define CAN_F18DATA0(canx) REG32((canx) + 0x2D0U) /*!< CAN filter 18 data 0 register */ +#define CAN_F19DATA0(canx) REG32((canx) + 0x2D8U) /*!< CAN filter 19 data 0 register */ +#define CAN_F20DATA0(canx) REG32((canx) + 0x2E0U) /*!< CAN filter 20 data 0 register */ +#define CAN_F21DATA0(canx) REG32((canx) + 0x2E8U) /*!< CAN filter 21 data 0 register */ +#define CAN_F22DATA0(canx) REG32((canx) + 0x2F0U) /*!< CAN filter 22 data 0 register */ +#define CAN_F23DATA0(canx) REG32((canx) + 0x3F8U) /*!< CAN filter 23 data 0 register */ +#define CAN_F24DATA0(canx) REG32((canx) + 0x300U) /*!< CAN filter 24 data 0 register */ +#define CAN_F25DATA0(canx) REG32((canx) + 0x308U) /*!< CAN filter 25 data 0 register */ +#define CAN_F26DATA0(canx) REG32((canx) + 0x310U) /*!< CAN filter 26 data 0 register */ +#define CAN_F27DATA0(canx) REG32((canx) + 0x318U) /*!< CAN filter 27 data 0 register */ +#define CAN_F0DATA1(canx) REG32((canx) + 0x244U) /*!< CAN filter 0 data 1 register */ +#define CAN_F1DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 1 data 1 register */ +#define CAN_F2DATA1(canx) REG32((canx) + 0x254U) /*!< CAN filter 2 data 1 register */ +#define CAN_F3DATA1(canx) REG32((canx) + 0x25CU) /*!< CAN filter 3 data 1 register */ +#define CAN_F4DATA1(canx) REG32((canx) + 0x264U) /*!< CAN filter 4 data 1 register */ +#define CAN_F5DATA1(canx) REG32((canx) + 0x26CU) /*!< CAN filter 5 data 1 register */ +#define CAN_F6DATA1(canx) REG32((canx) + 0x274U) /*!< CAN filter 6 data 1 register */ +#define CAN_F7DATA1(canx) REG32((canx) + 0x27CU) /*!< CAN filter 7 data 1 register */ +#define CAN_F8DATA1(canx) REG32((canx) + 0x284U) /*!< CAN filter 8 data 1 register */ +#define CAN_F9DATA1(canx) REG32((canx) + 0x28CU) /*!< CAN filter 9 data 1 register */ +#define CAN_F10DATA1(canx) REG32((canx) + 0x294U) /*!< CAN filter 10 data 1 register */ +#define CAN_F11DATA1(canx) REG32((canx) + 0x29CU) /*!< CAN filter 11 data 1 register */ +#define CAN_F12DATA1(canx) REG32((canx) + 0x2A4U) /*!< CAN filter 12 data 1 register */ +#define CAN_F13DATA1(canx) REG32((canx) + 0x2ACU) /*!< CAN filter 13 data 1 register */ +#define CAN_F14DATA1(canx) REG32((canx) + 0x2B4U) /*!< CAN filter 14 data 1 register */ +#define CAN_F15DATA1(canx) REG32((canx) + 0x2BCU) /*!< CAN filter 15 data 1 register */ +#define CAN_F16DATA1(canx) REG32((canx) + 0x2C4U) /*!< CAN filter 16 data 1 register */ +#define CAN_F17DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 17 data 1 register */ +#define CAN_F18DATA1(canx) REG32((canx) + 0x2D4U) /*!< CAN filter 18 data 1 register */ +#define CAN_F19DATA1(canx) REG32((canx) + 0x2DCU) /*!< CAN filter 19 data 1 register */ +#define CAN_F20DATA1(canx) REG32((canx) + 0x2E4U) /*!< CAN filter 20 data 1 register */ +#define CAN_F21DATA1(canx) REG32((canx) + 0x2ECU) /*!< CAN filter 21 data 1 register */ +#define CAN_F22DATA1(canx) REG32((canx) + 0x2F4U) /*!< CAN filter 22 data 1 register */ +#define CAN_F23DATA1(canx) REG32((canx) + 0x2FCU) /*!< CAN filter 23 data 1 register */ +#define CAN_F24DATA1(canx) REG32((canx) + 0x304U) /*!< CAN filter 24 data 1 register */ +#define CAN_F25DATA1(canx) REG32((canx) + 0x30CU) /*!< CAN filter 25 data 1 register */ +#define CAN_F26DATA1(canx) REG32((canx) + 0x314U) /*!< CAN filter 26 data 1 register */ +#define CAN_F27DATA1(canx) REG32((canx) + 0x31CU) /*!< CAN filter 27 data 1 register */ + +/* CAN transmit mailbox bank */ +#define CAN_TMI(canx, bank) REG32((canx) + 0x180U + ((bank) * 0x10U)) /*!< CAN transmit mailbox identifier register */ +#define CAN_TMP(canx, bank) REG32((canx) + 0x184U + ((bank) * 0x10U)) /*!< CAN transmit mailbox property register */ +#define CAN_TMDATA0(canx, bank) REG32((canx) + 0x188U + ((bank) * 0x10U)) /*!< CAN transmit mailbox data0 register */ +#define CAN_TMDATA1(canx, bank) REG32((canx) + 0x18CU + ((bank) * 0x10U)) /*!< CAN transmit mailbox data1 register */ + +/* CAN filter bank */ +#define CAN_FDATA0(canx, bank) REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x0U) /*!< CAN filter data 0 register */ +#define CAN_FDATA1(canx, bank) REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x4U) /*!< CAN filter data 1 register */ + +/* CAN receive fifo mailbox bank */ +#define CAN_RFIFOMI(canx, bank) REG32((canx) + 0x1B0U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox identifier register */ +#define CAN_RFIFOMP(canx, bank) REG32((canx) + 0x1B4U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox property register */ +#define CAN_RFIFOMDATA0(canx, bank) REG32((canx) + 0x1B8U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox data0 register */ +#define CAN_RFIFOMDATA1(canx, bank) REG32((canx) + 0x1BCU + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox data1 register */ + +/* bits definitions */ +/* CAN_CTL */ +#define CAN_CTL_IWMOD BIT(0) /*!< initial working mode */ +#define CAN_CTL_SLPWMOD BIT(1) /*!< sleep working mode */ +#define CAN_CTL_TFO BIT(2) /*!< transmit FIFO order */ +#define CAN_CTL_RFOD BIT(3) /*!< receive FIFO overwrite disable */ +#define CAN_CTL_ARD BIT(4) /*!< automatic retransmission disable */ +#define CAN_CTL_AWU BIT(5) /*!< automatic wakeup */ +#define CAN_CTL_ABOR BIT(6) /*!< automatic bus-off recovery */ +#define CAN_CTL_TTC BIT(7) /*!< time triggered communication */ +#define CAN_CTL_SWRST BIT(15) /*!< CAN software reset */ +#define CAN_CTL_DFZ BIT(16) /*!< CAN debug freeze */ + +/* CAN_STAT */ +#define CAN_STAT_IWS BIT(0) /*!< initial working state */ +#define CAN_STAT_SLPWS BIT(1) /*!< sleep working state */ +#define CAN_STAT_ERRIF BIT(2) /*!< error interrupt flag*/ +#define CAN_STAT_WUIF BIT(3) /*!< status change interrupt flag of wakeup from sleep working mode */ +#define CAN_STAT_SLPIF BIT(4) /*!< status change interrupt flag of sleep working mode entering */ +#define CAN_STAT_TS BIT(8) /*!< transmitting state */ +#define CAN_STAT_RS BIT(9) /*!< receiving state */ +#define CAN_STAT_LASTRX BIT(10) /*!< last sample value of rx pin */ +#define CAN_STAT_RXL BIT(11) /*!< CAN rx signal */ + +/* CAN_TSTAT */ +#define CAN_TSTAT_MTF0 BIT(0) /*!< mailbox0 transmit finished */ +#define CAN_TSTAT_MTFNERR0 BIT(1) /*!< mailbox0 transmit finished and no error */ +#define CAN_TSTAT_MAL0 BIT(2) /*!< mailbox0 arbitration lost */ +#define CAN_TSTAT_MTE0 BIT(3) /*!< mailbox0 transmit error */ +#define CAN_TSTAT_MST0 BIT(7) /*!< mailbox0 stop transmitting */ +#define CAN_TSTAT_MTF1 BIT(8) /*!< mailbox1 transmit finished */ +#define CAN_TSTAT_MTFNERR1 BIT(9) /*!< mailbox1 transmit finished and no error */ +#define CAN_TSTAT_MAL1 BIT(10) /*!< mailbox1 arbitration lost */ +#define CAN_TSTAT_MTE1 BIT(11) /*!< mailbox1 transmit error */ +#define CAN_TSTAT_MST1 BIT(15) /*!< mailbox1 stop transmitting */ +#define CAN_TSTAT_MTF2 BIT(16) /*!< mailbox2 transmit finished */ +#define CAN_TSTAT_MTFNERR2 BIT(17) /*!< mailbox2 transmit finished and no error */ +#define CAN_TSTAT_MAL2 BIT(18) /*!< mailbox2 arbitration lost */ +#define CAN_TSTAT_MTE2 BIT(19) /*!< mailbox2 transmit error */ +#define CAN_TSTAT_MST2 BIT(23) /*!< mailbox2 stop transmitting */ +#define CAN_TSTAT_NUM BITS(24,25) /*!< mailbox number */ +#define CAN_TSTAT_TME0 BIT(26) /*!< transmit mailbox0 empty */ +#define CAN_TSTAT_TME1 BIT(27) /*!< transmit mailbox1 empty */ +#define CAN_TSTAT_TME2 BIT(28) /*!< transmit mailbox2 empty */ +#define CAN_TSTAT_TMLS0 BIT(29) /*!< last sending priority flag for mailbox0 */ +#define CAN_TSTAT_TMLS1 BIT(30) /*!< last sending priority flag for mailbox1 */ +#define CAN_TSTAT_TMLS2 BIT(31) /*!< last sending priority flag for mailbox2 */ + +/* CAN_RFIFO0 */ +#define CAN_RFIFO0_RFL0 BITS(0,1) /*!< receive FIFO0 length */ +#define CAN_RFIFO0_RFF0 BIT(3) /*!< receive FIFO0 full */ +#define CAN_RFIFO0_RFO0 BIT(4) /*!< receive FIFO0 overfull */ +#define CAN_RFIFO0_RFD0 BIT(5) /*!< receive FIFO0 dequeue */ + +/* CAN_RFIFO1 */ +#define CAN_RFIFO1_RFL1 BITS(0,1) /*!< receive FIFO1 length */ +#define CAN_RFIFO1_RFF1 BIT(3) /*!< receive FIFO1 full */ +#define CAN_RFIFO1_RFO1 BIT(4) /*!< receive FIFO1 overfull */ +#define CAN_RFIFO1_RFD1 BIT(5) /*!< receive FIFO1 dequeue */ + +/* CAN_INTEN */ +#define CAN_INTEN_TMEIE BIT(0) /*!< transmit mailbox empty interrupt enable */ +#define CAN_INTEN_RFNEIE0 BIT(1) /*!< receive FIFO0 not empty interrupt enable */ +#define CAN_INTEN_RFFIE0 BIT(2) /*!< receive FIFO0 full interrupt enable */ +#define CAN_INTEN_RFOIE0 BIT(3) /*!< receive FIFO0 overfull interrupt enable */ +#define CAN_INTEN_RFNEIE1 BIT(4) /*!< receive FIFO1 not empty interrupt enable */ +#define CAN_INTEN_RFFIE1 BIT(5) /*!< receive FIFO1 full interrupt enable */ +#define CAN_INTEN_RFOIE1 BIT(6) /*!< receive FIFO1 overfull interrupt enable */ +#define CAN_INTEN_WERRIE BIT(8) /*!< warning error interrupt enable */ +#define CAN_INTEN_PERRIE BIT(9) /*!< passive error interrupt enable */ +#define CAN_INTEN_BOIE BIT(10) /*!< bus-off interrupt enable */ +#define CAN_INTEN_ERRNIE BIT(11) /*!< error number interrupt enable */ +#define CAN_INTEN_ERRIE BIT(15) /*!< error interrupt enable */ +#define CAN_INTEN_WIE BIT(16) /*!< wakeup interrupt enable */ +#define CAN_INTEN_SLPWIE BIT(17) /*!< sleep working interrupt enable */ + +/* CAN_ERR */ +#define CAN_ERR_WERR BIT(0) /*!< warning error */ +#define CAN_ERR_PERR BIT(1) /*!< passive error */ +#define CAN_ERR_BOERR BIT(2) /*!< bus-off error */ +#define CAN_ERR_ERRN BITS(4,6) /*!< error number */ +#define CAN_ERR_TECNT BITS(16,23) /*!< transmit error count */ +#define CAN_ERR_RECNT BITS(24,31) /*!< receive error count */ + +/* CAN_BT */ +#define CAN_BT_BAUDPSC BITS(0,9) /*!< baudrate prescaler */ +#define CAN_BT_BS1 BITS(16,19) /*!< bit segment 1 */ +#define CAN_BT_BS2 BITS(20,22) /*!< bit segment 2 */ +#define CAN_BT_SJW BITS(24,25) /*!< resynchronization jump width */ +#define CAN_BT_LCMOD BIT(30) /*!< loopback communication mode */ +#define CAN_BT_SCMOD BIT(31) /*!< silent communication mode */ + +/* CAN_TMIx */ +#define CAN_TMI_TEN BIT(0) /*!< transmit enable */ +#define CAN_TMI_FT BIT(1) /*!< frame type */ +#define CAN_TMI_FF BIT(2) /*!< frame format */ +#define CAN_TMI_EFID BITS(3,31) /*!< the frame identifier */ +#define CAN_TMI_SFID BITS(21,31) /*!< the frame identifier */ + +/* CAN_TMPx */ +#define CAN_TMP_DLENC BITS(0,3) /*!< data length code */ +#define CAN_TMP_TSEN BIT(8) /*!< time stamp enable */ +#define CAN_TMP_TS BITS(16,31) /*!< time stamp */ + +/* CAN_TMDATA0x */ +#define CAN_TMDATA0_DB0 BITS(0,7) /*!< transmit data byte 0 */ +#define CAN_TMDATA0_DB1 BITS(8,15) /*!< transmit data byte 1 */ +#define CAN_TMDATA0_DB2 BITS(16,23) /*!< transmit data byte 2 */ +#define CAN_TMDATA0_DB3 BITS(24,31) /*!< transmit data byte 3 */ + +/* CAN_TMDATA1x */ +#define CAN_TMDATA1_DB4 BITS(0,7) /*!< transmit data byte 4 */ +#define CAN_TMDATA1_DB5 BITS(8,15) /*!< transmit data byte 5 */ +#define CAN_TMDATA1_DB6 BITS(16,23) /*!< transmit data byte 6 */ +#define CAN_TMDATA1_DB7 BITS(24,31) /*!< transmit data byte 7 */ + +/* CAN_RFIFOMIx */ +#define CAN_RFIFOMI_FT BIT(1) /*!< frame type */ +#define CAN_RFIFOMI_FF BIT(2) /*!< frame format */ +#define CAN_RFIFOMI_EFID BITS(3,31) /*!< the frame identifier */ +#define CAN_RFIFOMI_SFID BITS(21,31) /*!< the frame identifier */ + +/* CAN_RFIFOMPx */ +#define CAN_RFIFOMP_DLENC BITS(0,3) /*!< receive data length code */ +#define CAN_RFIFOMP_FI BITS(8,15) /*!< filter index */ +#define CAN_RFIFOMP_TS BITS(16,31) /*!< time stamp */ + +/* CAN_RFIFOMDATA0x */ +#define CAN_RFIFOMDATA0_DB0 BITS(0,7) /*!< receive data byte 0 */ +#define CAN_RFIFOMDATA0_DB1 BITS(8,15) /*!< receive data byte 1 */ +#define CAN_RFIFOMDATA0_DB2 BITS(16,23) /*!< receive data byte 2 */ +#define CAN_RFIFOMDATA0_DB3 BITS(24,31) /*!< receive data byte 3 */ + +/* CAN_RFIFOMDATA1x */ +#define CAN_RFIFOMDATA1_DB4 BITS(0,7) /*!< receive data byte 4 */ +#define CAN_RFIFOMDATA1_DB5 BITS(8,15) /*!< receive data byte 5 */ +#define CAN_RFIFOMDATA1_DB6 BITS(16,23) /*!< receive data byte 6 */ +#define CAN_RFIFOMDATA1_DB7 BITS(24,31) /*!< receive data byte 7 */ + +/* CAN_FCTL */ +#define CAN_FCTL_FLD BIT(0) /*!< filter lock disable */ +#define CAN_FCTL_HBC1F BITS(8,13) /*!< header bank of CAN1 filter */ + +/* CAN_FMCFG */ +#define CAN_FMCFG_FMOD(regval) BIT(regval) /*!< filter mode, list or mask*/ + +/* CAN_FSCFG */ +#define CAN_FSCFG_FS(regval) BIT(regval) /*!< filter scale, 32 bits or 16 bits*/ + +/* CAN_FAFIFO */ +#define CAN_FAFIFOR_FAF(regval) BIT(regval) /*!< filter associated with FIFO */ + +/* CAN_FW */ +#define CAN_FW_FW(regval) BIT(regval) /*!< filter working */ + +/* CAN_FxDATAy */ +#define CAN_FDATA_FD(regval) BIT(regval) /*!< filter data */ + +/* consts definitions */ +/* define the CAN bit position and its register index offset */ +#define CAN_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define CAN_REG_VAL(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 6))) +#define CAN_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +#define CAN_REGIDX_BITS(regidx, bitpos0, bitpos1) (((uint32_t)(regidx) << 12) | ((uint32_t)(bitpos0) << 6) | (uint32_t)(bitpos1)) +#define CAN_REG_VALS(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 12))) +#define CAN_BIT_POS0(val) (((uint32_t)(val) >> 6) & 0x1FU) +#define CAN_BIT_POS1(val) ((uint32_t)(val) & 0x1FU) + +/* register offset */ +#define STAT_REG_OFFSET ((uint8_t)0x04U) /*!< STAT register offset */ +#define TSTAT_REG_OFFSET ((uint8_t)0x08U) /*!< TSTAT register offset */ +#define RFIFO0_REG_OFFSET ((uint8_t)0x0CU) /*!< RFIFO0 register offset */ +#define RFIFO1_REG_OFFSET ((uint8_t)0x10U) /*!< RFIFO1 register offset */ +#define ERR_REG_OFFSET ((uint8_t)0x18U) /*!< ERR register offset */ + +/* CAN flags */ +typedef enum { + /* flags in TSTAT register */ + CAN_FLAG_MTE2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 19U), /*!< mailbox 2 transmit error */ + CAN_FLAG_MTE1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 11U), /*!< mailbox 1 transmit error */ + CAN_FLAG_MTE0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 3U), /*!< mailbox 0 transmit error */ + CAN_FLAG_MTF2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 16U), /*!< mailbox 2 transmit finished */ + CAN_FLAG_MTF1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 8U), /*!< mailbox 1 transmit finished */ + CAN_FLAG_MTF0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 0U), /*!< mailbox 0 transmit finished */ + /* flags in RFIFO0 register */ + CAN_FLAG_RFO0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 4U), /*!< receive FIFO0 overfull */ + CAN_FLAG_RFF0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 3U), /*!< receive FIFO0 full */ + /* flags in RFIFO1 register */ + CAN_FLAG_RFO1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 4U), /*!< receive FIFO1 overfull */ + CAN_FLAG_RFF1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 3U), /*!< receive FIFO1 full */ + /* flags in ERR register */ + CAN_FLAG_BOERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 2U), /*!< bus-off error */ + CAN_FLAG_PERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 1U), /*!< passive error */ + CAN_FLAG_WERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 0U), /*!< warning error */ +} can_flag_enum; + +/* CAN interrupt flags */ +typedef enum { + /* interrupt flags in STAT register */ + CAN_INT_FLAG_SLPIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 4U, 17U), /*!< status change interrupt flag of sleep working mode entering */ + CAN_INT_FLAG_WUIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 3U, 16), /*!< status change interrupt flag of wakeup from sleep working mode */ + CAN_INT_FLAG_ERRIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 2U, 15), /*!< error interrupt flag */ + /* interrupt flags in TSTAT register */ + CAN_INT_FLAG_MTF2 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 16U, 0U), /*!< mailbox 2 transmit finished interrupt flag */ + CAN_INT_FLAG_MTF1 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 8U, 0U), /*!< mailbox 1 transmit finished interrupt flag */ + CAN_INT_FLAG_MTF0 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 0U, 0U), /*!< mailbox 0 transmit finished interrupt flag */ + /* interrupt flags in RFIFO0 register */ + CAN_INT_FLAG_RFO0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 4U, 3U), /*!< receive FIFO0 overfull interrupt flag */ + CAN_INT_FLAG_RFF0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 3U, 2U), /*!< receive FIFO0 full interrupt flag */ + /* interrupt flags in RFIFO0 register */ + CAN_INT_FLAG_RFO1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 4U, 6U), /*!< receive FIFO1 overfull interrupt flag */ + CAN_INT_FLAG_RFF1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 3U, 5U), /*!< receive FIFO1 full interrupt flag */ +} can_interrupt_flag_enum; + +/* CAN initiliaze parameters struct */ +typedef struct { + uint8_t working_mode; /*!< CAN working mode */ + uint8_t resync_jump_width; /*!< CAN resynchronization jump width */ + uint8_t time_segment_1; /*!< time segment 1 */ + uint8_t time_segment_2; /*!< time segment 2 */ + ControlStatus time_triggered; /*!< time triggered communication mode */ + ControlStatus auto_bus_off_recovery; /*!< automatic bus-off recovery */ + ControlStatus auto_wake_up; /*!< automatic wake-up mode */ + ControlStatus auto_retrans; /*!< automatic retransmission mode disable */ + ControlStatus rec_fifo_overwrite; /*!< receive FIFO overwrite mode */ + ControlStatus trans_fifo_order; /*!< transmit FIFO order */ + uint16_t prescaler; /*!< baudrate prescaler */ +} can_parameter_struct; + +/* CAN transmit message struct */ +typedef struct { + uint32_t tx_sfid; /*!< standard format frame identifier */ + uint32_t tx_efid; /*!< extended format frame identifier */ + uint8_t tx_ff; /*!< format of frame, standard or extended format */ + uint8_t tx_ft; /*!< type of frame, data or remote */ + uint8_t tx_dlen; /*!< data length */ + uint8_t tx_data[8]; /*!< transmit data */ +} can_trasnmit_message_struct; + +/* CAN receive message struct */ +typedef struct { + uint32_t rx_sfid; /*!< standard format frame identifier */ + uint32_t rx_efid; /*!< extended format frame identifier */ + uint8_t rx_ff; /*!< format of frame, standard or extended format */ + uint8_t rx_ft; /*!< type of frame, data or remote */ + uint8_t rx_dlen; /*!< data length */ + uint8_t rx_data[8]; /*!< receive data */ + uint8_t rx_fi; /*!< filtering index */ +} can_receive_message_struct; + +/* CAN filter parameters struct */ +typedef struct { + uint16_t filter_list_high; /*!< filter list number high bits*/ + uint16_t filter_list_low; /*!< filter list number low bits */ + uint16_t filter_mask_high; /*!< filter mask number high bits */ + uint16_t filter_mask_low; /*!< filter mask number low bits */ + uint16_t filter_fifo_number; /*!< receive FIFO associated with the filter */ + uint16_t filter_number; /*!< filter number */ + uint16_t filter_mode; /*!< filter mode, list or mask */ + uint16_t filter_bits; /*!< filter scale */ + ControlStatus filter_enable; /*!< filter work or not */ +} can_filter_parameter_struct; + +/* CAN errors */ +typedef enum { + CAN_ERROR_NONE = 0, /*!< no error */ + CAN_ERROR_FILL, /*!< fill error */ + CAN_ERROR_FORMATE, /*!< format error */ + CAN_ERROR_ACK, /*!< ACK error */ + CAN_ERROR_BITRECESSIVE, /*!< bit recessive error */ + CAN_ERROR_BITDOMINANTER, /*!< bit dominant error */ + CAN_ERROR_CRC, /*!< CRC error */ + CAN_ERROR_SOFTWARECFG, /*!< software configure */ +} can_error_enum; + +/* transmit states */ +typedef enum { + CAN_TRANSMIT_FAILED = 0, /*!< CAN transmitted failure */ + CAN_TRANSMIT_OK = 1, /*!< CAN transmitted success */ + CAN_TRANSMIT_PENDING = 2, /*!< CAN transmitted pending */ + CAN_TRANSMIT_NOMAILBOX = 4, /*!< no empty mailbox to be used for CAN */ +} can_transmit_state_enum; + +typedef enum { + CAN_INIT_STRUCT = 0, /* CAN initiliaze parameters struct */ + CAN_FILTER_STRUCT, /* CAN filter parameters struct */ + CAN_TX_MESSAGE_STRUCT, /* CAN transmit message struct */ + CAN_RX_MESSAGE_STRUCT, /* CAN receive message struct */ +} can_struct_type_enum; + +/* CAN baudrate prescaler*/ +#define BT_BAUDPSC(regval) (BITS(0,9) & ((uint32_t)(regval) << 0)) + +/* CAN bit segment 1*/ +#define BT_BS1(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) + +/* CAN bit segment 2*/ +#define BT_BS2(regval) (BITS(20,22) & ((uint32_t)(regval) << 20)) + +/* CAN resynchronization jump width*/ +#define BT_SJW(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) + +/* CAN communication mode*/ +#define BT_MODE(regval) (BITS(30,31) & ((uint32_t)(regval) << 30)) + +/* CAN FDATA high 16 bits */ +#define FDATA_MASK_HIGH(regval) (BITS(16,31) & ((uint32_t)(regval) << 16)) + +/* CAN FDATA low 16 bits */ +#define FDATA_MASK_LOW(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) + +/* CAN1 filter start bank_number*/ +#define FCTL_HBC1F(regval) (BITS(8,13) & ((uint32_t)(regval) << 8)) + +/* CAN transmit mailbox extended identifier*/ +#define TMI_EFID(regval) (BITS(3,31) & ((uint32_t)(regval) << 3)) + +/* CAN transmit mailbox standard identifier*/ +#define TMI_SFID(regval) (BITS(21,31) & ((uint32_t)(regval) << 21)) + +/* transmit data byte 0 */ +#define TMDATA0_DB0(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* transmit data byte 1 */ +#define TMDATA0_DB1(regval) (BITS(8,15) & ((uint32_t)(regval) << 8)) + +/* transmit data byte 2 */ +#define TMDATA0_DB2(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) + +/* transmit data byte 3 */ +#define TMDATA0_DB3(regval) (BITS(24,31) & ((uint32_t)(regval) << 24)) + +/* transmit data byte 4 */ +#define TMDATA1_DB4(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* transmit data byte 5 */ +#define TMDATA1_DB5(regval) (BITS(8,15) & ((uint32_t)(regval) << 8)) + +/* transmit data byte 6 */ +#define TMDATA1_DB6(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) + +/* transmit data byte 7 */ +#define TMDATA1_DB7(regval) (BITS(24,31) & ((uint32_t)(regval) << 24)) + +/* receive mailbox extended identifier*/ +#define GET_RFIFOMI_EFID(regval) GET_BITS((uint32_t)(regval), 3, 31) + +/* receive mailbox standrad identifier*/ +#define GET_RFIFOMI_SFID(regval) GET_BITS((uint32_t)(regval), 21, 31) + +/* receive data length */ +#define GET_RFIFOMP_DLENC(regval) GET_BITS((uint32_t)(regval), 0, 3) + +/* the index of the filter by which the frame is passed */ +#define GET_RFIFOMP_FI(regval) GET_BITS((uint32_t)(regval), 8, 15) + +/* receive data byte 0 */ +#define GET_RFIFOMDATA0_DB0(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* receive data byte 1 */ +#define GET_RFIFOMDATA0_DB1(regval) GET_BITS((uint32_t)(regval), 8, 15) + +/* receive data byte 2 */ +#define GET_RFIFOMDATA0_DB2(regval) GET_BITS((uint32_t)(regval), 16, 23) + +/* receive data byte 3 */ +#define GET_RFIFOMDATA0_DB3(regval) GET_BITS((uint32_t)(regval), 24, 31) + +/* receive data byte 4 */ +#define GET_RFIFOMDATA1_DB4(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* receive data byte 5 */ +#define GET_RFIFOMDATA1_DB5(regval) GET_BITS((uint32_t)(regval), 8, 15) + +/* receive data byte 6 */ +#define GET_RFIFOMDATA1_DB6(regval) GET_BITS((uint32_t)(regval), 16, 23) + +/* receive data byte 7 */ +#define GET_RFIFOMDATA1_DB7(regval) GET_BITS((uint32_t)(regval), 24, 31) + +/* error number */ +#define GET_ERR_ERRN(regval) GET_BITS((uint32_t)(regval), 4, 6) + +/* transmit error count */ +#define GET_ERR_TECNT(regval) GET_BITS((uint32_t)(regval), 16, 23) + +/* receive error count */ +#define GET_ERR_RECNT(regval) GET_BITS((uint32_t)(regval), 24, 31) + +/* CAN errors */ +#define ERR_ERRN(regval) (BITS(4,6) & ((uint32_t)(regval) << 4)) +#define CAN_ERRN_0 ERR_ERRN(0) /* no error */ +#define CAN_ERRN_1 ERR_ERRN(1) /*!< fill error */ +#define CAN_ERRN_2 ERR_ERRN(2) /*!< format error */ +#define CAN_ERRN_3 ERR_ERRN(3) /*!< ACK error */ +#define CAN_ERRN_4 ERR_ERRN(4) /*!< bit recessive error */ +#define CAN_ERRN_5 ERR_ERRN(5) /*!< bit dominant error */ +#define CAN_ERRN_6 ERR_ERRN(6) /*!< CRC error */ +#define CAN_ERRN_7 ERR_ERRN(7) /*!< software error */ + +#define CAN_STATE_PENDING ((uint32_t)0x00000000U) /*!< CAN pending */ + +/* CAN communication mode */ +#define CAN_NORMAL_MODE ((uint8_t)0x00U) /*!< normal communication mode */ +#define CAN_LOOPBACK_MODE ((uint8_t)0x01U) /*!< loopback communication mode */ +#define CAN_SILENT_MODE ((uint8_t)0x02U) /*!< silent communication mode */ +#define CAN_SILENT_LOOPBACK_MODE ((uint8_t)0x03U) /*!< loopback and silent communication mode */ + +/* CAN resynchronisation jump width */ +#define CAN_BT_SJW_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_SJW_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_SJW_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_SJW_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ + +/* CAN time segment 1 */ +#define CAN_BT_BS1_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_BS1_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_BS1_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_BS1_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ +#define CAN_BT_BS1_5TQ ((uint8_t)0x04U) /*!< 5 time quanta */ +#define CAN_BT_BS1_6TQ ((uint8_t)0x05U) /*!< 6 time quanta */ +#define CAN_BT_BS1_7TQ ((uint8_t)0x06U) /*!< 7 time quanta */ +#define CAN_BT_BS1_8TQ ((uint8_t)0x07U) /*!< 8 time quanta */ +#define CAN_BT_BS1_9TQ ((uint8_t)0x08U) /*!< 9 time quanta */ +#define CAN_BT_BS1_10TQ ((uint8_t)0x09U) /*!< 10 time quanta */ +#define CAN_BT_BS1_11TQ ((uint8_t)0x0AU) /*!< 11 time quanta */ +#define CAN_BT_BS1_12TQ ((uint8_t)0x0BU) /*!< 12 time quanta */ +#define CAN_BT_BS1_13TQ ((uint8_t)0x0CU) /*!< 13 time quanta */ +#define CAN_BT_BS1_14TQ ((uint8_t)0x0DU) /*!< 14 time quanta */ +#define CAN_BT_BS1_15TQ ((uint8_t)0x0EU) /*!< 15 time quanta */ +#define CAN_BT_BS1_16TQ ((uint8_t)0x0FU) /*!< 16 time quanta */ + +/* CAN time segment 2 */ +#define CAN_BT_BS2_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_BS2_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_BS2_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_BS2_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ +#define CAN_BT_BS2_5TQ ((uint8_t)0x04U) /*!< 5 time quanta */ +#define CAN_BT_BS2_6TQ ((uint8_t)0x05U) /*!< 6 time quanta */ +#define CAN_BT_BS2_7TQ ((uint8_t)0x06U) /*!< 7 time quanta */ +#define CAN_BT_BS2_8TQ ((uint8_t)0x07U) /*!< 8 time quanta */ + +/* CAN mailbox number */ +#define CAN_MAILBOX0 ((uint8_t)0x00U) /*!< mailbox0 */ +#define CAN_MAILBOX1 ((uint8_t)0x01U) /*!< mailbox1 */ +#define CAN_MAILBOX2 ((uint8_t)0x02U) /*!< mailbox2 */ +#define CAN_NOMAILBOX ((uint8_t)0x03U) /*!< no mailbox empty */ + +/* CAN frame format */ +#define CAN_FF_STANDARD ((uint32_t)0x00000000U) /*!< standard frame */ +#define CAN_FF_EXTENDED ((uint32_t)0x00000004U) /*!< extended frame */ + +/* CAN receive fifo */ +#define CAN_FIFO0 ((uint8_t)0x00U) /*!< receive FIFO0 */ +#define CAN_FIFO1 ((uint8_t)0x01U) /*!< receive FIFO1 */ + +/* frame number of receive fifo */ +#define CAN_RFIF_RFL_MASK ((uint32_t)0x00000003U) /*!< mask for frame number in receive FIFOx */ + +#define CAN_SFID_MASK ((uint32_t)0x000007FFU) /*!< mask of standard identifier */ +#define CAN_EFID_MASK ((uint32_t)0x1FFFFFFFU) /*!< mask of extended identifier */ + +/* CAN working mode */ +#define CAN_MODE_INITIALIZE ((uint8_t)0x01U) /*!< CAN initialize mode */ +#define CAN_MODE_NORMAL ((uint8_t)0x02U) /*!< CAN normal mode */ +#define CAN_MODE_SLEEP ((uint8_t)0x04U) /*!< CAN sleep mode */ + +/* filter bits */ +#define CAN_FILTERBITS_16BIT ((uint8_t)0x00U) /*!< CAN filter 16 bits */ +#define CAN_FILTERBITS_32BIT ((uint8_t)0x01U) /*!< CAN filter 32 bits */ + +/* filter mode */ +#define CAN_FILTERMODE_MASK ((uint8_t)0x00U) /*!< mask mode */ +#define CAN_FILTERMODE_LIST ((uint8_t)0x01U) /*!< list mode */ + +/* filter 16 bits mask */ +#define CAN_FILTER_MASK_16BITS ((uint32_t)0x0000FFFFU) /*!< can filter 16 bits mask */ + +/* frame type */ +#define CAN_FT_DATA ((uint32_t)0x00000000U) /*!< data frame */ +#define CAN_FT_REMOTE ((uint32_t)0x00000002U) /*!< remote frame */ + +/* CAN timeout */ +#define CAN_TIMEOUT ((uint32_t)0x0000FFFFU) /*!< timeout value */ + +/* interrupt enable bits */ +#define CAN_INT_TME CAN_INTEN_TMEIE /*!< transmit mailbox empty interrupt enable */ +#define CAN_INT_RFNE0 CAN_INTEN_RFNEIE0 /*!< receive FIFO0 not empty interrupt enable */ +#define CAN_INT_RFF0 CAN_INTEN_RFFIE0 /*!< receive FIFO0 full interrupt enable */ +#define CAN_INT_RFO0 CAN_INTEN_RFOIE0 /*!< receive FIFO0 overfull interrupt enable */ +#define CAN_INT_RFNE1 CAN_INTEN_RFNEIE1 /*!< receive FIFO1 not empty interrupt enable */ +#define CAN_INT_RFF1 CAN_INTEN_RFFIE1 /*!< receive FIFO1 full interrupt enable */ +#define CAN_INT_RFO1 CAN_INTEN_RFOIE1 /*!< receive FIFO1 overfull interrupt enable */ +#define CAN_INT_WERR CAN_INTEN_WERRIE /*!< warning error interrupt enable */ +#define CAN_INT_PERR CAN_INTEN_PERRIE /*!< passive error interrupt enable */ +#define CAN_INT_BO CAN_INTEN_BOIE /*!< bus-off interrupt enable */ +#define CAN_INT_ERRN CAN_INTEN_ERRNIE /*!< error number interrupt enable */ +#define CAN_INT_ERR CAN_INTEN_ERRIE /*!< error interrupt enable */ +#define CAN_INT_WAKEUP CAN_INTEN_WIE /*!< wakeup interrupt enable */ +#define CAN_INT_SLPW CAN_INTEN_SLPWIE /*!< sleep working interrupt enable */ + +/* function declarations */ +/* deinitialize CAN */ +void can_deinit(uint32_t can_periph); +/* initialize CAN struct */ +void can_struct_para_init(can_struct_type_enum type, void* p_struct); +/* initialize CAN */ +ErrStatus can_init(uint32_t can_periph, + can_parameter_struct* can_parameter_init); +/* CAN filter init */ +void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init); +/* set can1 fliter start bank number */ +void can1_filter_start_bank(uint8_t start_bank); +/* enable functions */ +/* CAN debug freeze enable */ +void can_debug_freeze_enable(uint32_t can_periph); +/* CAN debug freeze disable */ +void can_debug_freeze_disable(uint32_t can_periph); +/* CAN time trigger mode enable */ +void can_time_trigger_mode_enable(uint32_t can_periph); +/* CAN time trigger mode disable */ +void can_time_trigger_mode_disable(uint32_t can_periph); + +/* transmit functions */ +/* transmit CAN message */ +uint8_t can_message_transmit(uint32_t can_periph, + can_trasnmit_message_struct* transmit_message); +/* get CAN transmit state */ +can_transmit_state_enum can_transmit_states(uint32_t can_periph, + uint8_t mailbox_number); +/* stop CAN transmission */ +void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number); +/* CAN receive message */ +void can_message_receive(uint32_t can_periph, uint8_t fifo_number, + can_receive_message_struct* receive_message); +/* CAN release fifo */ +void can_fifo_release(uint32_t can_periph, uint8_t fifo_number); +/* CAN receive message length */ +uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number); +/* CAN working mode */ +ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode); +/* CAN wakeup from sleep mode */ +ErrStatus can_wakeup(uint32_t can_periph); + +/* CAN get error */ +can_error_enum can_error_get(uint32_t can_periph); +/* get CAN receive error number */ +uint8_t can_receive_error_number_get(uint32_t can_periph); +/* get CAN transmit error number */ +uint8_t can_transmit_error_number_get(uint32_t can_periph); + +/* CAN interrupt enable */ +void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt); +/* CAN interrupt disable */ +void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt); +/* CAN get flag state */ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag); +/* CAN clear flag state */ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag); +/* CAN get interrupt flag state */ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, + can_interrupt_flag_enum flag); +/* CAN clear interrupt flag state */ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag); + +#endif /* GD32VF103_CAN_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_crc.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_crc.h new file mode 100644 index 0000000000000000000000000000000000000000..c86fe995b30247413c2cf082a4aef8a189ef9d30 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_crc.h @@ -0,0 +1,78 @@ +/*! + \file gd32vf103_crc.h + \brief definitions for the CRC + + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_CRC_H +#define GD32VF103_CRC_H + +#include "gd32vf103.h" + +/* CRC definitions */ +#define CRC CRC_BASE + +/* registers definitions */ +#define CRC_DATA REG32(CRC + 0x00U) /*!< CRC data register */ +#define CRC_FDATA REG32(CRC + 0x04U) /*!< CRC free data register */ +#define CRC_CTL REG32(CRC + 0x08U) /*!< CRC control register */ + +/* bits definitions */ +/* CRC_DATA */ +#define CRC_DATA_DATA BITS(0, 31) /*!< CRC calculation result bits */ + +/* CRC_FDATA */ +#define CRC_FDATA_FDATA BITS(0, 7) /*!< CRC free data bits */ + +/* CRC_CTL */ +#define CRC_CTL_RST BIT(0) /*!< CRC reset CRC_DATA register bit */ + +/* function declarations */ +/* deinit CRC calculation unit */ +void crc_deinit(void); + +/* reset data register(CRC_DATA) to the value of 0xFFFFFFFF */ +void crc_data_register_reset(void); +/* read the value of the data register */ +uint32_t crc_data_register_read(void); + +/* read the value of the free data register */ +uint8_t crc_free_data_register_read(void); +/* write data to the free data register */ +void crc_free_data_register_write(uint8_t free_data); + +/* calculate the CRC value of a 32-bit data */ +uint32_t crc_single_data_calculate(uint32_t sdata); +/* calculate the CRC value of an array of 32-bit values */ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size); + +#endif /* GD32VF103_CRC_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_dac.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..165899f22673f2abd15cc24ed5a262d08d227ac9 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_dac.h @@ -0,0 +1,242 @@ +/*! + \file gd32vf103_dac.h + \brief definitions for the DAC + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_DAC_H +#define GD32VF103_DAC_H + +#include "gd32vf103.h" + +/* DACx(x=0,1) definitions */ +#define DAC DAC_BASE +#define DAC0 (0U) +#define DAC1 (1U) + +/* registers definitions */ +#define DAC_CTL REG32(DAC + 0x00U) /*!< DAC control register */ +#define DAC_SWT REG32(DAC + 0x04U) /*!< DAC software trigger register */ +#define DAC0_R12DH REG32(DAC + 0x08U) /*!< DAC0 12-bit right-aligned data holding register */ +#define DAC0_L12DH REG32(DAC + 0x0CU) /*!< DAC0 12-bit left-aligned data holding register */ +#define DAC0_R8DH REG32(DAC + 0x10U) /*!< DAC0 8-bit right-aligned data holding register */ +#define DAC1_R12DH REG32(DAC + 0x14U) /*!< DAC1 12-bit right-aligned data holding register */ +#define DAC1_L12DH REG32(DAC + 0x18U) /*!< DAC1 12-bit left-aligned data holding register */ +#define DAC1_R8DH REG32(DAC + 0x1CU) /*!< DAC1 8-bit right-aligned data holding register */ +#define DACC_R12DH REG32(DAC + 0x20U) /*!< DAC concurrent mode 12-bit right-aligned data holding register */ +#define DACC_L12DH REG32(DAC + 0x24U) /*!< DAC concurrent mode 12-bit left-aligned data holding register */ +#define DACC_R8DH REG32(DAC + 0x28U) /*!< DAC concurrent mode 8-bit right-aligned data holding register */ +#define DAC0_DO REG32(DAC + 0x2CU) /*!< DAC0 data output register */ +#define DAC1_DO REG32(DAC + 0x30U) /*!< DAC1 data output register */ + +/* bits definitions */ +/* DAC_CTL */ +#define DAC_CTL_DEN0 BIT(0) /*!< DAC0 enable/disable bit */ +#define DAC_CTL_DBOFF0 BIT(1) /*!< DAC0 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN0 BIT(2) /*!< DAC0 trigger enable/disable bit */ +#define DAC_CTL_DTSEL0 BITS(3,5) /*!< DAC0 trigger source selection enable/disable bits */ +#define DAC_CTL_DWM0 BITS(6,7) /*!< DAC0 noise wave mode */ +#define DAC_CTL_DWBW0 BITS(8,11) /*!< DAC0 noise wave bit width */ +#define DAC_CTL_DDMAEN0 BIT(12) /*!< DAC0 DMA enable/disable bit */ +#define DAC_CTL_DEN1 BIT(16) /*!< DAC1 enable/disable bit */ +#define DAC_CTL_DBOFF1 BIT(17) /*!< DAC1 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN1 BIT(18) /*!< DAC1 trigger enable/disable bit */ +#define DAC_CTL_DTSEL1 BITS(19,21) /*!< DAC1 trigger source selection enable/disable bits */ +#define DAC_CTL_DWM1 BITS(22,23) /*!< DAC1 noise wave mode */ +#define DAC_CTL_DWBW1 BITS(24,27) /*!< DAC1 noise wave bit width */ +#define DAC_CTL_DDMAEN1 BIT(28) /*!< DAC1 DMA enable/disable bit */ + +/* DAC_SWT */ +#define DAC_SWT_SWTR0 BIT(0) /*!< DAC0 software trigger bit, cleared by hardware */ +#define DAC_SWT_SWTR1 BIT(1) /*!< DAC1 software trigger bit, cleared by hardware */ + +/* DAC0_R12DH */ +#define DAC0_R12DH_DAC0_DH BITS(0,11) /*!< DAC0 12-bit right-aligned data bits */ + +/* DAC0_L12DH */ +#define DAC0_L12DH_DAC0_DH BITS(4,15) /*!< DAC0 12-bit left-aligned data bits */ + +/* DAC0_R8DH */ +#define DAC0_R8DH_DAC0_DH BITS(0,7) /*!< DAC0 8-bit right-aligned data bits */ + +/* DAC1_R12DH */ +#define DAC1_R12DH_DAC1_DH BITS(0,11) /*!< DAC1 12-bit right-aligned data bits */ + +/* DAC1_L12DH */ +#define DAC1_L12DH_DAC1_DH BITS(4,15) /*!< DAC1 12-bit left-aligned data bits */ + +/* DAC1_R8DH */ +#define DAC1_R8DH_DAC1_DH BITS(0,7) /*!< DAC1 8-bit right-aligned data bits */ + +/* DACC_R12DH */ +#define DACC_R12DH_DAC0_DH BITS(0,11) /*!< DAC concurrent mode DAC0 12-bit right-aligned data bits */ +#define DACC_R12DH_DAC1_DH BITS(16,27) /*!< DAC concurrent mode DAC1 12-bit right-aligned data bits */ + +/* DACC_L12DH */ +#define DACC_L12DH_DAC0_DH BITS(4,15) /*!< DAC concurrent mode DAC0 12-bit left-aligned data bits */ +#define DACC_L12DH_DAC1_DH BITS(20,31) /*!< DAC concurrent mode DAC1 12-bit left-aligned data bits */ + +/* DACC_R8DH */ +#define DACC_R8DH_DAC0_DH BITS(0,7) /*!< DAC concurrent mode DAC0 8-bit right-aligned data bits */ +#define DACC_R8DH_DAC1_DH BITS(8,15) /*!< DAC concurrent mode DAC1 8-bit right-aligned data bits */ + +/* DAC0_DO */ +#define DAC0_DO_DAC0_DO BITS(0,11) /*!< DAC0 12-bit output data bits */ + +/* DAC1_DO */ +#define DAC1_DO_DAC1_DO BITS(0,11) /*!< DAC1 12-bit output data bits */ + +/* 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_T6_TRGO CTL_DTSEL(2) /*!< TIMER6 TRGO */ +#define DAC_TRIGGER_T4_TRGO CTL_DTSEL(3) /*!< TIMER4 TRGO */ +#define DAC_TRIGGER_T1_TRGO CTL_DTSEL(4) /*!< TIMER1 TRGO */ +#define DAC_TRIGGER_T3_TRGO CTL_DTSEL(5) /*!< TIMER3 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] */ + +/* 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 */ +/* 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 */ + +/* function declarations */ +/* initialization functions */ +/* deinitialize DAC */ +void dac_deinit(void); +/* enable DAC */ +void dac_enable(uint32_t dac_periph); +/* disable DAC */ +void dac_disable(uint32_t dac_periph); +/* enable DAC DMA */ +void dac_dma_enable(uint32_t dac_periph); +/* disable DAC DMA */ +void dac_dma_disable(uint32_t dac_periph); +/* enable DAC output buffer */ +void dac_output_buffer_enable(uint32_t dac_periph); +/* disable DAC output buffer */ +void dac_output_buffer_disable(uint32_t dac_periph); +/* get the last data output value */ +uint16_t dac_output_value_get(uint32_t dac_periph); +/* set DAC data holding register value */ +void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data); + +/* DAC trigger configuration */ +/* enable DAC trigger */ +void dac_trigger_enable(uint32_t dac_periph); +/* disable DAC trigger */ +void dac_trigger_disable(uint32_t dac_periph); +/* configure DAC trigger source */ +void dac_trigger_source_config(uint32_t dac_periph, uint32_t triggersource); +/* enable DAC software trigger */ +void dac_software_trigger_enable(uint32_t dac_periph); +/* disable DAC software trigger */ +void dac_software_trigger_disable(uint32_t dac_periph); + +/* DAC wave mode configuration */ +/* configure DAC wave mode */ +void dac_wave_mode_config(uint32_t dac_periph, uint32_t wave_mode); +/* configure DAC wave bit width */ +void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width); +/* configure DAC LFSR noise mode */ +void dac_lfsr_noise_config(uint32_t dac_periph, uint32_t unmask_bits); +/* configure DAC triangle noise mode */ +void dac_triangle_noise_config(uint32_t dac_periph, uint32_t amplitude); + +/* DAC concurrent mode configuration */ +/* enable DAC concurrent mode */ +void dac_concurrent_enable(void); +/* disable DAC concurrent mode */ +void dac_concurrent_disable(void); +/* enable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_enable(void); +/* disable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_disable(void); +/* enable DAC concurrent buffer function */ +void dac_concurrent_output_buffer_enable(void); +/* disable DAC concurrent buffer function */ +void dac_concurrent_output_buffer_disable(void); +/* set DAC concurrent mode data holding register value */ +void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1); + +#endif /* GD32VF103_DAC_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_dbg.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_dbg.h new file mode 100644 index 0000000000000000000000000000000000000000..244ca291b31d19463a269b6145572ef4bd20e222 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_dbg.h @@ -0,0 +1,109 @@ +/*! + \file gd32vf103_dbg.h + \brief definitions for the DBG + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_DBG_H +#define GD32VF103_DBG_H + +#include "gd32vf103.h" + +/* DBG definitions */ +#define DBG DBG_BASE + +/* registers definitions */ +#define DBG_ID REG32(DBG + 0x00U) /*!< DBG_ID code register */ +#define DBG_CTL REG32(DBG + 0x04U) /*!< DBG control register */ + +/* bits definitions */ +/* DBG_ID */ +#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG ID code values */ + +/* DBG_CTL */ +#define DBG_CTL_SLP_HOLD BIT(0) /*!< keep debugger connection during sleep mode */ +#define DBG_CTL_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */ +#define DBG_CTL_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */ +#define DBG_CTL_FWDGT_HOLD BIT(8) /*!< debug FWDGT kept when core is halted */ +#define DBG_CTL_WWDGT_HOLD BIT(9) /*!< debug WWDGT kept when core is halted */ +#define DBG_CTL_TIMER0_HOLD BIT(10) /*!< hold TIMER0 counter when core is halted */ +#define DBG_CTL_TIMER1_HOLD BIT(11) /*!< hold TIMER1 counter when core is halted */ +#define DBG_CTL_TIMER2_HOLD BIT(12) /*!< hold TIMER2 counter when core is halted */ +#define DBG_CTL_TIMER3_HOLD BIT(13) /*!< hold TIMER3 counter when core is halted */ +#define DBG_CTL_CAN0_HOLD BIT(14) /*!< debug CAN0 kept when core is halted */ +#define DBG_CTL_I2C0_HOLD BIT(15) /*!< hold I2C0 smbus when core is halted */ +#define DBG_CTL_I2C1_HOLD BIT(16) /*!< hold I2C1 smbus when core is halted */ +#define DBG_CTL_TIMER4_HOLD BIT(18) /*!< hold TIMER4 counter when core is halted */ +#define DBG_CTL_TIMER5_HOLD BIT(19) /*!< hold TIMER5 counter when core is halted */ +#define DBG_CTL_TIMER6_HOLD BIT(20) /*!< hold TIMER6 counter when core is halted */ +#define DBG_CTL_CAN1_HOLD BIT(21) /*!< debug CAN1 kept when core is halted */ + +/* constants definitions */ +/* debug hold when core is halted */ +typedef enum +{ + DBG_FWDGT_HOLD = BIT(8), /*!< debug FWDGT kept when core is halted */ + DBG_WWDGT_HOLD = BIT(9), /*!< debug WWDGT kept when core is halted */ + DBG_TIMER0_HOLD = BIT(10), /*!< hold TIMER0 counter when core is halted */ + DBG_TIMER1_HOLD = BIT(11), /*!< hold TIMER1 counter when core is halted */ + DBG_TIMER2_HOLD = BIT(12), /*!< hold TIMER2 counter when core is halted */ + DBG_TIMER3_HOLD = BIT(13), /*!< hold TIMER3 counter when core is halted */ + DBG_CAN0_HOLD = BIT(14), /*!< debug CAN0 kept when core is halted */ + DBG_I2C0_HOLD = BIT(15), /*!< hold I2C0 smbus when core is halted */ + DBG_I2C1_HOLD = BIT(16), /*!< hold I2C1 smbus when core is halted */ + DBG_TIMER4_HOLD = BIT(17), /*!< hold TIMER4 counter when core is halted */ + DBG_TIMER5_HOLD = BIT(18), /*!< hold TIMER5 counter when core is halted */ + DBG_TIMER6_HOLD = BIT(19), /*!< hold TIMER6 counter when core is halted */ + DBG_CAN1_HOLD = BIT(21), /*!< debug CAN1 kept when core is halted */ +}dbg_periph_enum; + +/* DBG low power mode configurations */ +#define DBG_LOW_POWER_SLEEP DBG_CTL_SLP_HOLD /*!< keep debugger connection during sleep mode */ +#define DBG_LOW_POWER_DEEPSLEEP DBG_CTL_DSLP_HOLD /*!< keep debugger connection during deepsleep mode */ +#define DBG_LOW_POWER_STANDBY DBG_CTL_STB_HOLD /*!< keep debugger connection during standby mode */ + +/* function declarations */ +/* read DBG_ID code register */ +uint32_t dbg_id_get(void); + +/* low power behavior configuration */ +/* 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); + +/* peripheral behavior configuration */ +/* 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 /* GD32VF103_DBG_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_dma.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..ceeefe0dc80f3b84307b20ef0755aad1489cdd29 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_dma.h @@ -0,0 +1,282 @@ +/*! + \file gd32vf103_dma.h + \brief definitions for the DMA + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_DMA_H +#define GD32VF103_DMA_H + +#include "gd32vf103.h" + +/* DMA definitions */ +#define DMA0 (DMA_BASE) /*!< DMA0 base address */ +#define DMA1 (DMA_BASE + 0x0400U) /*!< DMA1 base address */ + +/* registers definitions */ +#define DMA_INTF(dmax) REG32((dmax) + 0x00U) /*!< DMA interrupt flag register */ +#define DMA_INTC(dmax) REG32((dmax) + 0x04U) /*!< DMA interrupt flag clear register */ + +#define DMA_CH0CTL(dmax) REG32((dmax) + 0x08U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT(dmax) REG32((dmax) + 0x0CU) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR(dmax) REG32((dmax) + 0x10U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0MADDR(dmax) REG32((dmax) + 0x14U) /*!< DMA channel 0 memory base address register */ + +#define DMA_CH1CTL(dmax) REG32((dmax) + 0x1CU) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT(dmax) REG32((dmax) + 0x20U) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR(dmax) REG32((dmax) + 0x24U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1MADDR(dmax) REG32((dmax) + 0x28U) /*!< DMA channel 1 memory base address register */ + +#define DMA_CH2CTL(dmax) REG32((dmax) + 0x30U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT(dmax) REG32((dmax) + 0x34U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR(dmax) REG32((dmax) + 0x38U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2MADDR(dmax) REG32((dmax) + 0x3CU) /*!< DMA channel 2 memory base address register */ + +#define DMA_CH3CTL(dmax) REG32((dmax) + 0x44U) /*!< DMA channel 3 control register */ +#define DMA_CH3CNT(dmax) REG32((dmax) + 0x48U) /*!< DMA channel 3 counter register */ +#define DMA_CH3PADDR(dmax) REG32((dmax) + 0x4CU) /*!< DMA channel 3 peripheral base address register */ +#define DMA_CH3MADDR(dmax) REG32((dmax) + 0x50U) /*!< DMA channel 3 memory base address register */ + +#define DMA_CH4CTL(dmax) REG32((dmax) + 0x58U) /*!< DMA channel 4 control register */ +#define DMA_CH4CNT(dmax) REG32((dmax) + 0x5CU) /*!< DMA channel 4 counter register */ +#define DMA_CH4PADDR(dmax) REG32((dmax) + 0x60U) /*!< DMA channel 4 peripheral base address register */ +#define DMA_CH4MADDR(dmax) REG32((dmax) + 0x64U) /*!< DMA channel 4 memory base address register */ + +#define DMA_CH5CTL(dmax) REG32((dmax) + 0x6CU) /*!< DMA channel 5 control register */ +#define DMA_CH5CNT(dmax) REG32((dmax) + 0x70U) /*!< DMA channel 5 counter register */ +#define DMA_CH5PADDR(dmax) REG32((dmax) + 0x74U) /*!< DMA channel 5 peripheral base address register */ +#define DMA_CH5MADDR(dmax) REG32((dmax) + 0x78U) /*!< DMA channel 5 memory base address register */ + +#define DMA_CH6CTL(dmax) REG32((dmax) + 0x80U) /*!< DMA channel 6 control register */ +#define DMA_CH6CNT(dmax) REG32((dmax) + 0x84U) /*!< DMA channel 6 counter register */ +#define DMA_CH6PADDR(dmax) REG32((dmax) + 0x88U) /*!< DMA channel 6 peripheral base address register */ +#define DMA_CH6MADDR(dmax) REG32((dmax) + 0x8CU) /*!< 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 enable */ +#define DMA_CHXCTL_FTFIE BIT(1) /*!< enable bit for channel full transfer finish interrupt */ +#define DMA_CHXCTL_HTFIE BIT(2) /*!< enable bit for channel half transfer finish interrupt */ +#define DMA_CHXCTL_ERRIE BIT(3) /*!< enable bit for channel error interrupt */ +#define DMA_CHXCTL_DIR BIT(4) /*!< transfer direction */ +#define DMA_CHXCTL_CMEN BIT(5) /*!< circular mode enable */ +#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 width of peripheral */ +#define DMA_CHXCTL_MWIDTH BITS(10,11) /*!< transfer data width of memory */ +#define DMA_CHXCTL_PRIO BITS(12,13) /*!< priority level */ +#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 */ + uint32_t memory_addr; /*!< memory base address */ + uint32_t memory_width; /*!< transfer data size of memory */ + uint32_t number; /*!< channel transfer number */ + uint32_t priority; /*!< channel priority level */ + uint8_t periph_inc; /*!< peripheral increasing mode */ + uint8_t memory_inc; /*!< memory increasing mode */ + uint8_t direction; /*!< channel data transfer direction */ + +} dma_parameter_struct; + +#define DMA_FLAG_ADD(flag, shift) ((flag) << ((shift) * 4U)) /*!< DMA channel flag shift */ + +/* DMA_register address */ +#define DMA_CHCTL(dma, channel) REG32(((dma) + 0x08U) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCTL register */ +#define DMA_CHCNT(dma, channel) REG32(((dma) + 0x0CU) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCNT register */ +#define DMA_CHPADDR(dma, channel) REG32(((dma) + 0x10U) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXPADDR register */ +#define DMA_CHMADDR(dma, channel) REG32(((dma) + 0x14U) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXMADDR register */ + +/* 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) /*!< clear DMA channel DMA_INTF 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 ((uint8_t)0x0000U) /*!< read from peripheral and write to memory */ +#define DMA_MEMORY_TO_PERIPHERAL ((uint8_t)0x0001U) /*!< read from memory and write to peripheral */ + +/* peripheral increasing mode */ +#define DMA_PERIPH_INCREASE_DISABLE ((uint8_t)0x0000U) /*!< next address of peripheral is fixed address mode */ +#define DMA_PERIPH_INCREASE_ENABLE ((uint8_t)0x0001U) /*!< next address of peripheral is increasing address mode */ + +/* memory increasing mode */ +#define DMA_MEMORY_INCREASE_DISABLE ((uint8_t)0x0000U) /*!< next address of memory is fixed address mode */ +#define DMA_MEMORY_INCREASE_ENABLE ((uint8_t)0x0001U) /*!< next address of memory is increasing address mode */ + +/* transfer data size of peripheral */ +#define CHCTL_PWIDTH(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) /*!< transfer data size of peripheral */ +#define DMA_PERIPHERAL_WIDTH_8BIT CHCTL_PWIDTH(0U) /*!< transfer data size of peripheral is 8-bit */ +#define DMA_PERIPHERAL_WIDTH_16BIT CHCTL_PWIDTH(1U) /*!< transfer data size of peripheral is 16-bit */ +#define DMA_PERIPHERAL_WIDTH_32BIT CHCTL_PWIDTH(2U) /*!< transfer data size of peripheral is 32-bit */ + +/* transfer data size of memory */ +#define CHCTL_MWIDTH(regval) (BITS(10,11) & ((uint32_t)(regval) << 10)) /*!< transfer data size of memory */ +#define DMA_MEMORY_WIDTH_8BIT CHCTL_MWIDTH(0U) /*!< transfer data size of memory is 8-bit */ +#define DMA_MEMORY_WIDTH_16BIT CHCTL_MWIDTH(1U) /*!< transfer data size of memory is 16-bit */ +#define DMA_MEMORY_WIDTH_32BIT CHCTL_MWIDTH(2U) /*!< transfer data size of memory is 32-bit */ + +/* channel priority level */ +#define CHCTL_PRIO(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) /*!< DMA channel priority level */ +#define DMA_PRIORITY_LOW CHCTL_PRIO(0U) /*!< low priority */ +#define DMA_PRIORITY_MEDIUM CHCTL_PRIO(1U) /*!< medium priority */ +#define DMA_PRIORITY_HIGH CHCTL_PRIO(2U) /*!< high priority */ +#define DMA_PRIORITY_ULTRA_HIGH CHCTL_PRIO(3U) /*!< ultra high priority */ + +/* memory to memory mode */ +#define DMA_MEMORY_TO_MEMORY_DISABLE ((uint32_t)0x00000000U) /*!< disable memory to memory mode */ +#define DMA_MEMORY_TO_MEMORY_ENABLE ((uint32_t)0x00000001U) /*!< enable memory to memory mode */ + +/* DMA_CHxCNT register */ +/* transfer counter */ +#define DMA_CHANNEL_CNT_MASK DMA_CHXCNT_CNT /*!< transfer counter mask */ + +/* function declarations */ +/* DMA deinitialization and initialization functions */ +/* deinitialize DMA a channel registers */ +void dma_deinit(uint32_t dma_periph, 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(uint32_t dma_periph, dma_channel_enum channelx, dma_parameter_struct *init_struct); +/* enable DMA circulation mode */ +void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable DMA circulation mode */ +void dma_circulation_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* enable memory to memory mode */ +void dma_memory_to_memory_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable memory to memory mode */ +void dma_memory_to_memory_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* enable DMA channel */ +void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable DMA channel */ +void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx); + +/* DMA configuration functions */ +/* set DMA peripheral base address */ +void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address); +/* set DMA memory base address */ +void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address); +/* set the number of remaining data to be transferred by the DMA */ +void dma_transfer_number_config(uint32_t dma_periph, 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(uint32_t dma_periph, dma_channel_enum channelx); +/* configure priority level of DMA channel */ +void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t priority); +/* configure transfer data size of memory */ +void dma_memory_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t mwidth); +/* configure transfer data size of peripheral */ +void dma_periph_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t pwidth); +/* enable next address increasement algorithm of memory */ +void dma_memory_increase_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable next address increasement algorithm of memory */ +void dma_memory_increase_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* enable next address increasement algorithm of peripheral */ +void dma_periph_increase_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable next address increasement algorithm of peripheral */ +void dma_periph_increase_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* configure the direction of data transfer on the channel */ +void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t direction); + +/* flag and interrupt functions */ +/* check DMA flag is set or not */ +FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); +/* clear the flag of a DMA channel */ +void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); +/* check DMA flag and interrupt enable bit is set or not */ +FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); +/* clear the interrupt flag of a DMA channel */ +void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); +/* enable DMA interrupt */ +void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source); +/* disable DMA interrupt */ +void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source); + +#endif /* GD32VF103_DMA_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_eclic.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_eclic.h new file mode 100644 index 0000000000000000000000000000000000000000..843ab4c2547ed892191734f8dfb4e47c0b5ab699 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_eclic.h @@ -0,0 +1,62 @@ +/*! + \file gd32vf103_eclic.h + \brief definitions for the ECLIC(Enhancement Core-Local Interrupt Controller) + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_ECLIC_H +#define GD32VF103_ECLIC_H + +#include "gd32vf103.h" + +/* constants definitions */ +#define ECLIC_PRIGROUP_LEVEL0_PRIO4 0 /*!< 0 bits for level 4 bits for priority */ +#define ECLIC_PRIGROUP_LEVEL1_PRIO3 1 /*!< 1 bits for level 3 bits for priority */ +#define ECLIC_PRIGROUP_LEVEL2_PRIO2 2 /*!< 2 bits for level 2 bits for priority */ +#define ECLIC_PRIGROUP_LEVEL3_PRIO1 3 /*!< 3 bits for level 1 bits for priority */ +#define ECLIC_PRIGROUP_LEVEL4_PRIO0 4 /*!< 4 bits for level 0 bits for priority */ + +#define __SEV eclic_send_event + +/* function declarations */ +/* set the priority group */ +void eclic_priority_group_set(uint32_t prigroup); +/* enable the interrupt request */ +void eclic_irq_enable(uint32_t source, uint8_t level, uint8_t priority); +/* disable the interrupt request */ +void eclic_irq_disable(uint32_t source); + +/* reset system */ +void eclic_system_reset(void); +/* send event(SEV) */ +void eclic_send_event(void); + +#endif /* GD32VF103_ECLIC_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_exmc.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_exmc.h new file mode 100644 index 0000000000000000000000000000000000000000..1c72014b497a879b77a4dc496410e79ba9f274b8 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_exmc.h @@ -0,0 +1,126 @@ +/*! + \file gd32vf103_exmc.h + \brief definitions for the EXMC + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_EXMC_H +#define GD32VF103_EXMC_H + +#include "gd32vf103.h" + +/* EXMC definitions */ +#define EXMC (EXMC_BASE) /*!< EXMC register base address */ + +/* registers definitions */ +/* NOR/PSRAM */ +#define EXMC_SNCTL0 REG32(EXMC + 0x00U) /*!< EXMC SRAM/NOR flash control register 0 */ +#define EXMC_SNTCFG0 REG32(EXMC + 0x04U) /*!< EXMC SRAM/NOR flash timing configuration register 0 */ +#define EXMC_SNWTCFG0 REG32(EXMC + 0x104U) /*!< EXMC SRAM/NOR flash write timing configuration register 0 */ + +/* bits definitions */ +/* NOR/PSRAM */ +/* EXMC_SNCTLx, x=0 */ +#define EXMC_SNCTL_NRBKEN BIT(0) /*!< NOR bank enable */ +#define EXMC_SNCTL_NRMUX BIT(1) /*!< NOR bank memory address/data multiplexing */ +#define EXMC_SNCTL_NRTP BITS(2,3) /*!< NOR bank memory type */ +#define EXMC_SNCTL_NRW BITS(4,5) /*!< NOR bank memory data bus width */ +#define EXMC_SNCTL_NREN BIT(6) /*!< NOR flash access enable */ +#define EXMC_SNCTL_NRWTPOL BIT(9) /*!< NWAIT signal polarity */ +#define EXMC_SNCTL_WREN BIT(12) /*!< write enable */ +#define EXMC_SNCTL_NRWTEN BIT(13) /*!< NWAIT signal enable */ +#define EXMC_SNCTL_ASYNCWAIT BIT(15) /*!< asynchronous wait */ + +/* EXMC_SNTCFGx, x=0 */ +#define EXMC_SNTCFG_ASET BITS(0,3) /*!< address setup time */ +#define EXMC_SNTCFG_AHLD BITS(4,7) /*!< address hold time */ +#define EXMC_SNTCFG_DSET BITS(8,15) /*!< data setup time */ +#define EXMC_SNTCFG_BUSLAT BITS(16,19) /*!< bus latency */ + +/* constants definitions */ +/* EXMC NOR/SRAM timing initialize struct */ +typedef struct +{ + uint32_t bus_latency; /*!< configure the bus latency */ + uint32_t asyn_data_setuptime; /*!< configure the data setup time,asynchronous access mode valid */ + uint32_t asyn_address_holdtime; /*!< configure the address hold time,asynchronous access mode valid */ + uint32_t asyn_address_setuptime; /*!< configure the data setup time,asynchronous access mode valid */ +}exmc_norsram_timing_parameter_struct; + +/* EXMC NOR/SRAM initialize struct */ +typedef struct +{ + uint32_t norsram_region; /*!< select the region of EXMC NOR/SRAM bank */ + uint32_t asyn_wait; /*!< enable or disable the asynchronous wait function */ + uint32_t nwait_signal; /*!< enable or disable the NWAIT signal */ + uint32_t memory_write; /*!< enable or disable the write operation */ + uint32_t nwait_polarity; /*!< specifies the polarity of NWAIT signal from memory */ + uint32_t databus_width; /*!< specifies the databus width of external memory */ + uint32_t memory_type; /*!< specifies the type of external memory */ + uint32_t address_data_mux; /*!< specifies whether the data bus and address bus are multiplexed */ + exmc_norsram_timing_parameter_struct* read_write_timing; /*!< timing parameters for read and write */ +}exmc_norsram_parameter_struct; + +/* EXMC register address */ +#define EXMC_SNCTL(region) REG32(EXMC + 0x08U * (region)) /*!< EXMC SRAM/NOR flash control register */ +#define EXMC_SNTCFG(region) REG32(EXMC + 0x04U + 0x08U * (region)) /*!< EXMC SRAM/NOR flash timing configuration register */ + +/* NOR bank memory data bus width */ +#define SNCTL_NRW(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define EXMC_NOR_DATABUS_WIDTH_8B SNCTL_NRW(0) /*!< NOR data width 8 bits */ +#define EXMC_NOR_DATABUS_WIDTH_16B SNCTL_NRW(1) /*!< NOR data width 16 bits */ + +/* NOR bank memory type */ +#define SNCTL_NRTP(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define EXMC_MEMORY_TYPE_SRAM SNCTL_NRTP(0) /*!< SRAM,ROM */ +#define EXMC_MEMORY_TYPE_PSRAM SNCTL_NRTP(1) /*!< PSRAM,CRAM */ +#define EXMC_MEMORY_TYPE_NOR SNCTL_NRTP(2) /*!< NOR flash */ + +/* EXMC NOR/SRAM bank region definition */ +#define EXMC_BANK0_NORSRAM_REGION0 ((uint32_t)0x00000000U) /*!< bank0 NOR/SRAM region0 */ + +/* EXMC NWAIT signal polarity configuration */ +#define EXMC_NWAIT_POLARITY_LOW ((uint32_t)0x00000000U) /*!< low level is active of NWAIT */ +#define EXMC_NWAIT_POLARITY_HIGH ((uint32_t)0x00000200U) /*!< high level is active of NWAIT */ + +/* function declarations */ +/* deinitialize EXMC NOR/SRAM region */ +void exmc_norsram_deinit(uint32_t norsram_region); +/* exmc_norsram_parameter_struct parameter initialize */ +void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct); +/* initialize EXMC NOR/SRAM region */ +void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct); +/* EXMC NOR/SRAM bank enable */ +void exmc_norsram_enable(uint32_t norsram_region); +/* EXMC NOR/SRAM bank disable */ +void exmc_norsram_disable(uint32_t norsram_region); + +#endif /* GD32VF103_EXMC_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_exti.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_exti.h new file mode 100644 index 0000000000000000000000000000000000000000..3a0d90901c283a22496214df67435adc4e558deb --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_exti.h @@ -0,0 +1,244 @@ +/*! + \file gd32vf103_exti.h + \brief definitions for the EXTI + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_EXTI_H +#define GD32VF103_EXTI_H + +#include "gd32vf103.h" + +/* EXTI definitions */ +#define EXTI EXTI_BASE + +/* registers definitions */ +#define EXTI_INTEN REG32(EXTI + 0x00U) /*!< interrupt enable register */ +#define EXTI_EVEN REG32(EXTI + 0x04U) /*!< event enable register */ +#define EXTI_RTEN REG32(EXTI + 0x08U) /*!< rising edge trigger enable register */ +#define EXTI_FTEN REG32(EXTI + 0x0CU) /*!< falling trigger enable register */ +#define EXTI_SWIEV REG32(EXTI + 0x10U) /*!< software interrupt event register */ +#define EXTI_PD REG32(EXTI + 0x14U) /*!< pending register */ + +/* bits definitions */ +/* EXTI_INTEN */ +#define EXTI_INTEN_INTEN0 BIT(0) /*!< interrupt from line 0 */ +#define EXTI_INTEN_INTEN1 BIT(1) /*!< interrupt from line 1 */ +#define EXTI_INTEN_INTEN2 BIT(2) /*!< interrupt from line 2 */ +#define EXTI_INTEN_INTEN3 BIT(3) /*!< interrupt from line 3 */ +#define EXTI_INTEN_INTEN4 BIT(4) /*!< interrupt from line 4 */ +#define EXTI_INTEN_INTEN5 BIT(5) /*!< interrupt from line 5 */ +#define EXTI_INTEN_INTEN6 BIT(6) /*!< interrupt from line 6 */ +#define EXTI_INTEN_INTEN7 BIT(7) /*!< interrupt from line 7 */ +#define EXTI_INTEN_INTEN8 BIT(8) /*!< interrupt from line 8 */ +#define EXTI_INTEN_INTEN9 BIT(9) /*!< interrupt from line 9 */ +#define EXTI_INTEN_INTEN10 BIT(10) /*!< interrupt from line 10 */ +#define EXTI_INTEN_INTEN11 BIT(11) /*!< interrupt from line 11 */ +#define EXTI_INTEN_INTEN12 BIT(12) /*!< interrupt from line 12 */ +#define EXTI_INTEN_INTEN13 BIT(13) /*!< interrupt from line 13 */ +#define EXTI_INTEN_INTEN14 BIT(14) /*!< interrupt from line 14 */ +#define EXTI_INTEN_INTEN15 BIT(15) /*!< interrupt from line 15 */ +#define EXTI_INTEN_INTEN16 BIT(16) /*!< interrupt from line 16 */ +#define EXTI_INTEN_INTEN17 BIT(17) /*!< interrupt from line 17 */ +#define EXTI_INTEN_INTEN18 BIT(18) /*!< interrupt from line 18 */ + +/* 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 */ + +/* 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 */ + +/* 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 */ + +/* 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 */ + +/* 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 */ + +/* 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_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 edge and falling edge trigger */ +} exti_trig_type_enum; + +/* function declarations */ +/* initialization, EXTI lines configuration functions */ +/* deinitialize the EXTI */ +void exti_deinit(void); +/* enable the configuration of EXTI initialize */ +void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type); +/* enable the interrupts from EXTI line x */ +void exti_interrupt_enable(exti_line_enum linex); +/* enable the events from EXTI line x */ +void exti_event_enable(exti_line_enum linex); +/* disable the interrupts from EXTI line x */ +void exti_interrupt_disable(exti_line_enum linex); +/* disable the events from EXTI line x */ +void exti_event_disable(exti_line_enum linex); + +/* interrupt & flag functions */ +/* get EXTI lines pending flag */ +FlagStatus exti_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_flag_clear(exti_line_enum linex); +/* get EXTI lines flag when the interrupt flag is set */ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_interrupt_flag_clear(exti_line_enum linex); +/* enable the EXTI software interrupt event */ +void exti_software_interrupt_enable(exti_line_enum linex); +/* disable the EXTI software interrupt event */ +void exti_software_interrupt_disable(exti_line_enum linex); + +#endif /* GD32VF103_EXTI_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_fmc.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_fmc.h new file mode 100644 index 0000000000000000000000000000000000000000..2e6693ab76101cc564044ad44cd1cbe707e90e02 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_fmc.h @@ -0,0 +1,311 @@ +/*! + \file gd32vf103_fmc.h + \brief definitions for the FMC + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_FMC_H +#define GD32VF103_FMC_H + +#include "gd32vf103.h" + +/* FMC and option byte definition */ +#define FMC FMC_BASE /*!< FMC register base address */ +#define OB OB_BASE /*!< option bytes base address */ + +/* registers definitions */ +#define FMC_WS REG32((FMC) + 0x00U) /*!< FMC wait state register */ +#define FMC_KEY0 REG32((FMC) + 0x04U) /*!< FMC unlock key register 0 */ +#define FMC_OBKEY REG32((FMC) + 0x08U) /*!< FMC option bytes unlock key register */ +#define FMC_STAT0 REG32((FMC) + 0x0CU) /*!< FMC status register 0 */ +#define FMC_CTL0 REG32((FMC) + 0x10U) /*!< FMC control register 0 */ +#define FMC_ADDR0 REG32((FMC) + 0x14U) /*!< FMC address register 0 */ +#define FMC_OBSTAT REG32((FMC) + 0x1CU) /*!< FMC option bytes status register */ +#define FMC_WP REG32((FMC) + 0x20U) /*!< FMC erase/program protection register */ +#define FMC_PID REG32((FMC) + 0x100U) /*!< FMC product ID register */ + +#define OB_SPC REG16((OB) + 0x00U) /*!< option byte security protection value */ +#define OB_USER REG16((OB) + 0x02U) /*!< option byte user value*/ +#define OB_WP0 REG16((OB) + 0x08U) /*!< option byte write protection 0 */ +#define OB_WP1 REG16((OB) + 0x0AU) /*!< option byte write protection 1 */ +#define OB_WP2 REG16((OB) + 0x0CU) /*!< option byte write protection 2 */ +#define OB_WP3 REG16((OB) + 0x0EU) /*!< option byte write protection 3 */ + +/* bits definitions */ +/* FMC_WS */ +#define FMC_WS_WSCNT BITS(0,2) /*!< wait state counter */ + +/* FMC_KEY0 */ +#define FMC_KEY0_KEY BITS(0,31) /*!< FMC_CTL0 unlock key bits */ + +/* FMC_OBKEY */ +#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option bytes unlock key bits */ + +/* FMC_STAT0 */ +#define FMC_STAT0_BUSY BIT(0) /*!< flash busy flag bit */ +#define FMC_STAT0_PGERR BIT(2) /*!< flash program error flag bit */ +#define FMC_STAT0_WPERR BIT(4) /*!< erase/program protection error flag bit */ +#define FMC_STAT0_ENDF BIT(5) /*!< end of operation flag bit */ + +/* FMC_CTL0 */ +#define FMC_CTL0_PG BIT(0) /*!< main flash program for bank0 command bit */ +#define FMC_CTL0_PER BIT(1) /*!< main flash page erase for bank0 command bit */ +#define FMC_CTL0_MER BIT(2) /*!< main flash mass erase for bank0 command bit */ +#define FMC_CTL0_OBPG BIT(4) /*!< option bytes program command bit */ +#define FMC_CTL0_OBER BIT(5) /*!< option bytes erase command bit */ +#define FMC_CTL0_START BIT(6) /*!< send erase command to FMC bit */ +#define FMC_CTL0_LK BIT(7) /*!< FMC_CTL0 lock bit */ +#define FMC_CTL0_OBWEN BIT(9) /*!< option bytes erase/program enable bit */ +#define FMC_CTL0_ERRIE BIT(10) /*!< error interrupt enable bit */ +#define FMC_CTL0_ENDIE BIT(12) /*!< end of operation interrupt enable bit */ + +/* FMC_ADDR0 */ +#define FMC_ADDR0_ADDR BITS(0,31) /*!< Flash erase/program command address bits */ + +/* FMC_OBSTAT */ +#define FMC_OBSTAT_OBERR BIT(0) /*!< option bytes read error bit. */ +#define FMC_OBSTAT_SPC BIT(1) /*!< option bytes security protection code */ +#define FMC_OBSTAT_USER BITS(2,9) /*!< store USER of option bytes block after system reset */ +#define FMC_OBSTAT_DATA BITS(10,25) /*!< store DATA of option bytes block after system reset. */ + +/* FMC_WP */ +#define FMC_WP_WP BITS(0,31) /*!< store WP of option bytes block after system reset */ + +/* FMC_WSEN */ +#define FMC_WSEN_WSEN BIT(0) /*!< FMC wait state enable bit */ + +/* FMC_PID */ +#define FMC_PID_PID BITS(0,31) /*!< product ID bits */ + +/* constants definitions */ +/* define the FMC bit position and its register index offset */ +#define FMC_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define FMC_REG_VAL(offset) (REG32(FMC + ((uint32_t)(offset) >> 6))) +#define FMC_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#define FMC_REGIDX_BITS(regidx, bitpos0, bitpos1) (((uint32_t)(regidx) << 12) | ((uint32_t)(bitpos0) << 6) | (uint32_t)(bitpos1)) +#define FMC_REG_VALS(offset) (REG32(FMC + ((uint32_t)(offset) >> 12))) +#define FMC_BIT_POS0(val) (((uint32_t)(val) >> 6) & 0x1FU) +#define FMC_BIT_POS1(val) ((uint32_t)(val) & 0x1FU) +#define FMC_REG_OFFSET_GET(flag) ((uint32_t)(flag) >> 12) + +/* configuration register */ +#define FMC_STAT0_REG_OFFSET 0x0CU /*!< status register 0 offset */ +#define FMC_CTL0_REG_OFFSET 0x10U /*!< control register 0 offset */ +#define FMC_OBSTAT_REG_OFFSET 0x1CU /*!< option byte status register offset */ + +/* 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_state_enum; + +/* FMC interrupt enable */ +typedef enum +{ + FMC_INT_END = FMC_REGIDX_BIT(FMC_CTL0_REG_OFFSET, 12U), /*!< enable FMC end of program interrupt */ + FMC_INT_ERR = FMC_REGIDX_BIT(FMC_CTL0_REG_OFFSET, 10U), /*!< enable FMC error interrupt */ +}fmc_int_enum; + +/* FMC flags */ +typedef enum +{ + FMC_FLAG_BUSY = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 0U), /*!< FMC busy flag */ + FMC_FLAG_PGERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 2U), /*!< FMC operation error flag bit */ + FMC_FLAG_WPERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 4U), /*!< FMC erase/program protection error flag bit */ + FMC_FLAG_END = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 5U), /*!< FMC end of operation flag bit */ + FMC_FLAG_OBERR = FMC_REGIDX_BIT(FMC_OBSTAT_REG_OFFSET, 0U), /*!< FMC option bytes read error flag */ +}fmc_flag_enum; + +/* FMC interrupt flags */ +typedef enum +{ + FMC_INT_FLAG_PGERR = FMC_REGIDX_BITS(FMC_STAT0_REG_OFFSET, 2U, 10U), /*!< FMC operation error interrupt flag bit */ + FMC_INT_FLAG_WPERR = FMC_REGIDX_BITS(FMC_STAT0_REG_OFFSET, 4U, 10U), /*!< FMC erase/program protection error interrupt flag bit */ + FMC_INT_FLAG_END = FMC_REGIDX_BITS(FMC_STAT0_REG_OFFSET, 5U, 12U), /*!< FMC end of operation interrupt flag bit */ +}fmc_interrupt_flag_enum; + +/* unlock key */ +#define UNLOCK_KEY0 ((uint32_t)0x45670123U) /*!< unlock key 0 */ +#define UNLOCK_KEY1 ((uint32_t)0xCDEF89ABU) /*!< unlock key 1 */ + +/* FMC wait state counter */ +#define WS_WSCNT(regval) (BITS(0,2) & ((uint32_t)(regval))) +#define WS_WSCNT_0 WS_WSCNT(0) /*!< FMC 0 wait */ +#define WS_WSCNT_1 WS_WSCNT(1) /*!< FMC 1 wait */ +#define WS_WSCNT_2 WS_WSCNT(2) /*!< FMC 2 wait */ + +/* option bytes software/hardware free watch dog timer */ +#define OB_FWDGT_SW ((uint8_t)0x01U) /*!< software free watchdog */ +#define OB_FWDGT_HW ((uint8_t)0x00U) /*!< hardware free watchdog */ + +/* option bytes reset or not entering deep sleep mode */ +#define OB_DEEPSLEEP_NRST ((uint8_t)0x02U) /*!< no reset when entering deepsleep mode */ +#define OB_DEEPSLEEP_RST ((uint8_t)0x00U) /*!< generate a reset instead of entering deepsleep mode */ + +/* option bytes reset or not entering standby mode */ +#define OB_STDBY_NRST ((uint8_t)0x04U) /*!< no reset when entering deepsleep mode */ +#define OB_STDBY_RST ((uint8_t)0x00U) /*!< generate a reset instead of entering standby mode */ + +/* option bytes boot bank value */ +#define OB_BOOT_B0 ((uint8_t)0x08U) /*!< boot from bank0 */ + +#define OB_USER_MASK ((uint8_t)0xF0U) /*!< MASK value */ + +/* read protect configure */ +#define FMC_NSPC ((uint8_t)0xA5U) /*!< no security protection */ +#define FMC_USPC ((uint8_t)0xBBU) /*!< under security protection */ + +/* OB_SPC */ +#define OB_SPC_SPC ((uint32_t)0x000000FFU) /*!< option byte security protection value */ +#define OB_SPC_SPC_N ((uint32_t)0x0000FF00U) /*!< option byte security protection complement value */ + +/* OB_USER */ +#define OB_USER_USER ((uint32_t)0x00FF0000U) /*!< user option value */ +#define OB_USER_USER_N ((uint32_t)0xFF000000U) /*!< user option complement value */ + +/* OB_WP0 */ +#define OB_WP0_WP0 ((uint32_t)0x000000FFU) /*!< FMC write protection option value */ + +/* OB_WP1 */ +#define OB_WP1_WP1 ((uint32_t)0x0000FF00U) /*!< FMC write protection option complement value */ + +/* OB_WP2 */ +#define OB_WP2_WP2 ((uint32_t)0x00FF0000U) /*!< FMC write protection option value */ + +/* OB_WP3 */ +#define OB_WP3_WP3 ((uint32_t)0xFF000000U) /*!< FMC write protection option complement value */ + +/* option bytes write protection */ +#define OB_WP_0 ((uint32_t)0x00000001U) /*!< erase/program protection of sector 0 */ +#define OB_WP_1 ((uint32_t)0x00000002U) /*!< erase/program protection of sector 1 */ +#define OB_WP_2 ((uint32_t)0x00000004U) /*!< erase/program protection of sector 2 */ +#define OB_WP_3 ((uint32_t)0x00000008U) /*!< erase/program protection of sector 3 */ +#define OB_WP_4 ((uint32_t)0x00000010U) /*!< erase/program protection of sector 4 */ +#define OB_WP_5 ((uint32_t)0x00000020U) /*!< erase/program protection of sector 5 */ +#define OB_WP_6 ((uint32_t)0x00000040U) /*!< erase/program protection of sector 6 */ +#define OB_WP_7 ((uint32_t)0x00000080U) /*!< erase/program protection of sector 7 */ +#define OB_WP_8 ((uint32_t)0x00000100U) /*!< erase/program protection of sector 8 */ +#define OB_WP_9 ((uint32_t)0x00000200U) /*!< erase/program protection of sector 9 */ +#define OB_WP_10 ((uint32_t)0x00000400U) /*!< erase/program protection of sector 10 */ +#define OB_WP_11 ((uint32_t)0x00000800U) /*!< erase/program protection of sector 11 */ +#define OB_WP_12 ((uint32_t)0x00001000U) /*!< erase/program protection of sector 12 */ +#define OB_WP_13 ((uint32_t)0x00002000U) /*!< erase/program protection of sector 13 */ +#define OB_WP_14 ((uint32_t)0x00004000U) /*!< erase/program protection of sector 14 */ +#define OB_WP_15 ((uint32_t)0x00008000U) /*!< erase/program protection of sector 15 */ +#define OB_WP_16 ((uint32_t)0x00010000U) /*!< erase/program protection of sector 16 */ +#define OB_WP_17 ((uint32_t)0x00020000U) /*!< erase/program protection of sector 17 */ +#define OB_WP_18 ((uint32_t)0x00040000U) /*!< erase/program protection of sector 18 */ +#define OB_WP_19 ((uint32_t)0x00080000U) /*!< erase/program protection of sector 19 */ +#define OB_WP_20 ((uint32_t)0x00100000U) /*!< erase/program protection of sector 20 */ +#define OB_WP_21 ((uint32_t)0x00200000U) /*!< erase/program protection of sector 21 */ +#define OB_WP_22 ((uint32_t)0x00400000U) /*!< erase/program protection of sector 22 */ +#define OB_WP_23 ((uint32_t)0x00800000U) /*!< erase/program protection of sector 23 */ +#define OB_WP_24 ((uint32_t)0x01000000U) /*!< erase/program protection of sector 24 */ +#define OB_WP_25 ((uint32_t)0x02000000U) /*!< erase/program protection of sector 25 */ +#define OB_WP_26 ((uint32_t)0x04000000U) /*!< erase/program protection of sector 26 */ +#define OB_WP_27 ((uint32_t)0x08000000U) /*!< erase/program protection of sector 27 */ +#define OB_WP_28 ((uint32_t)0x10000000U) /*!< erase/program protection of sector 28 */ +#define OB_WP_29 ((uint32_t)0x20000000U) /*!< erase/program protection of sector 29 */ +#define OB_WP_30 ((uint32_t)0x40000000U) /*!< erase/program protection of sector 30 */ +#define OB_WP_31 ((uint32_t)0x80000000U) /*!< erase/program protection of sector 31 */ +#define OB_WP_ALL ((uint32_t)0xFFFFFFFFU) /*!< erase/program protection of all sectors */ + +/* FMC timeout */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0x000F0000U) /*!< FMC timeout count value */ + +/* FMC BANK address */ +#define FMC_SIZE (*(uint16_t *)0x1FFFF7E0U) /*!< FMC size */ +#define SRAM_SIZE (*(uint16_t *)0x1FFFF7E2U) /*!< SRAM size*/ + +/* function declarations */ +/* FMC main memory programming functions */ +/* set the FMC wait state counter */ +void fmc_wscnt_set(uint32_t wscnt); +/* unlock the main FMC operation */ +void fmc_unlock(void); +/* lock the main FMC operation */ +void fmc_lock(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 option bytes programming functions */ +/* unlock the option byte operation */ +void ob_unlock(void); +/* lock the option byte operation */ +void ob_lock(void); +/* erase the FMC option byte */ +fmc_state_enum ob_erase(void); +/* enable write protect */ +fmc_state_enum ob_write_protection_enable(uint32_t ob_wp); +/* configure the option byte security protection */ +fmc_state_enum ob_security_protection_config(uint8_t ob_spc); +/* write the FMC option byte */ +fmc_state_enum ob_user_write(uint8_t ob_fwdgt, uint8_t ob_deepsleep, uint8_t ob_stdby, uint8_t ob_boot); +/* program option bytes data */ +fmc_state_enum ob_data_program(uint32_t address, uint8_t data); +/* get the FMC option byte user */ +uint8_t ob_user_get(void); +/* get OB_DATA in register FMC_OBSTAT */ +uint16_t ob_data_get(void); +/* get the FMC option byte write protection */ +uint32_t ob_write_protection_get(void); +/* get FMC option byte security protection code value */ +FlagStatus ob_spc_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); +/* check flag is set or not */ +FlagStatus fmc_flag_get(uint32_t flag); +/* clear the FMC flag */ +void fmc_flag_clear(uint32_t flag); +/* get FMC interrupt flag state */ +FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum flag); +/* clear FMC interrupt flag state */ +void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum flag); +/* return the FMC state */ +fmc_state_enum fmc_state_get(void); +/* check FMC ready or not */ +fmc_state_enum fmc_ready_wait(uint32_t timeout); + +#endif /* GD32VF103_FMC_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_fwdgt.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_fwdgt.h new file mode 100644 index 0000000000000000000000000000000000000000..cedfa0fbdac7b265e9497a353a3429f56492455f --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_fwdgt.h @@ -0,0 +1,104 @@ +/*! + \file gd32vf103_fwdgt.h + \brief definitions for the FWDGT + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_FWDGT_H +#define GD32VF103_FWDGT_H + +#include "gd32vf103.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE /*!< FWDGT base address */ + +/* 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 */ + +/* 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 */ + +/* constants definitions */ +/* psc register value */ +#define PSC_PSC(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define FWDGT_PSC_DIV4 ((uint8_t)PSC_PSC(0)) /*!< FWDGT prescaler set to 4 */ +#define FWDGT_PSC_DIV8 ((uint8_t)PSC_PSC(1)) /*!< FWDGT prescaler set to 8 */ +#define FWDGT_PSC_DIV16 ((uint8_t)PSC_PSC(2)) /*!< FWDGT prescaler set to 16 */ +#define FWDGT_PSC_DIV32 ((uint8_t)PSC_PSC(3)) /*!< FWDGT prescaler set to 32 */ +#define FWDGT_PSC_DIV64 ((uint8_t)PSC_PSC(4)) /*!< FWDGT prescaler set to 64 */ +#define FWDGT_PSC_DIV128 ((uint8_t)PSC_PSC(5)) /*!< FWDGT prescaler set to 128 */ +#define FWDGT_PSC_DIV256 ((uint8_t)PSC_PSC(6)) /*!< FWDGT prescaler set to 256 */ + +/* control value */ +#define FWDGT_WRITEACCESS_ENABLE ((uint16_t)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_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 /*!< FWDGT prescaler divider value update flag */ +#define FWDGT_FLAG_RUD FWDGT_STAT_RUD /*!< FWDGT counter reload value update flag */ + +/* function declarations */ +/* enable write access to FWDGT_PSC and FWDGT_RLD */ +void fwdgt_write_enable(void); +/* disable write access to FWDGT_PSC and FWDGT_RLD */ +void fwdgt_write_disable(void); +/* start the free watchdog timer counter */ +void fwdgt_enable(void); + +/* 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 /* GD32VF103_FWDGT_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_gpio.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..2583646faa5e4c704355ca904e1c08d1d07d3864 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_gpio.h @@ -0,0 +1,423 @@ +/*! + \file gd32vf103_gpio.h + \brief definitions for the GPIO + + \version 2019-06-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_GPIO_H +#define GD32VF103_GPIO_H + +#include "gd32vf103.h" + +/* GPIOx(x=A,B,C,D,E) definitions */ +#define GPIOA (GPIO_BASE + 0x00000000U) +#define GPIOB (GPIO_BASE + 0x00000400U) +#define GPIOC (GPIO_BASE + 0x00000800U) +#define GPIOD (GPIO_BASE + 0x00000C00U) +#define GPIOE (GPIO_BASE + 0x00001000U) + +/* AFIO definitions */ +#define AFIO AFIO_BASE + +/* registers definitions */ + +/* GPIO registers definitions */ +#define GPIO_CTL0(gpiox) REG32((gpiox) + 0x00U) /*!< GPIO port control register 0 */ +#define GPIO_CTL1(gpiox) REG32((gpiox) + 0x04U) /*!< GPIO port control register 1 */ +#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x08U) /*!< GPIO port input status register */ +#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x0CU) /*!< GPIO port output control register */ +#define GPIO_BOP(gpiox) REG32((gpiox) + 0x10U) /*!< GPIO port bit operation register */ +#define GPIO_BC(gpiox) REG32((gpiox) + 0x14U) /*!< GPIO bit clear register */ +#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port configuration lock register */ + +/* AFIO registers definitions */ +#define AFIO_EC REG32(AFIO + 0x00U) /*!< AFIO event control register */ +#define AFIO_PCF0 REG32(AFIO + 0x04U) /*!< AFIO port configuration register 0 */ +#define AFIO_EXTISS0 REG32(AFIO + 0x08U) /*!< AFIO port EXTI sources selection register 0 */ +#define AFIO_EXTISS1 REG32(AFIO + 0x0CU) /*!< AFIO port EXTI sources selection register 1 */ +#define AFIO_EXTISS2 REG32(AFIO + 0x10U) /*!< AFIO port EXTI sources selection register 2 */ +#define AFIO_EXTISS3 REG32(AFIO + 0x14U) /*!< AFIO port EXTI sources selection register 3 */ +#define AFIO_PCF1 REG32(AFIO + 0x1CU) /*!< AFIO port configuration register 1 */ + +/* bits definitions */ +/* GPIO_CTL0 */ +#define GPIO_CTL0_MD0 BITS(0, 1) /*!< port 0 mode bits */ +#define GPIO_CTL0_CTL0 BITS(2, 3) /*!< pin 0 configuration bits */ +#define GPIO_CTL0_MD1 BITS(4, 5) /*!< port 1 mode bits */ +#define GPIO_CTL0_CTL1 BITS(6, 7) /*!< pin 1 configuration bits */ +#define GPIO_CTL0_MD2 BITS(8, 9) /*!< port 2 mode bits */ +#define GPIO_CTL0_CTL2 BITS(10, 11) /*!< pin 2 configuration bits */ +#define GPIO_CTL0_MD3 BITS(12, 13) /*!< port 3 mode bits */ +#define GPIO_CTL0_CTL3 BITS(14, 15) /*!< pin 3 configuration bits */ +#define GPIO_CTL0_MD4 BITS(16, 17) /*!< port 4 mode bits */ +#define GPIO_CTL0_CTL4 BITS(18, 19) /*!< pin 4 configuration bits */ +#define GPIO_CTL0_MD5 BITS(20, 21) /*!< port 5 mode bits */ +#define GPIO_CTL0_CTL5 BITS(22, 23) /*!< pin 5 configuration bits */ +#define GPIO_CTL0_MD6 BITS(24, 25) /*!< port 6 mode bits */ +#define GPIO_CTL0_CTL6 BITS(26, 27) /*!< pin 6 configuration bits */ +#define GPIO_CTL0_MD7 BITS(28, 29) /*!< port 7 mode bits */ +#define GPIO_CTL0_CTL7 BITS(30, 31) /*!< pin 7 configuration bits */ + +/* GPIO_CTL1 */ +#define GPIO_CTL1_MD8 BITS(0, 1) /*!< port 8 mode bits */ +#define GPIO_CTL1_CTL8 BITS(2, 3) /*!< pin 8 configuration bits */ +#define GPIO_CTL1_MD9 BITS(4, 5) /*!< port 9 mode bits */ +#define GPIO_CTL1_CTL9 BITS(6, 7) /*!< pin 9 configuration bits */ +#define GPIO_CTL1_MD10 BITS(8, 9) /*!< port 10 mode bits */ +#define GPIO_CTL1_CTL10 BITS(10, 11) /*!< pin 10 configuration bits */ +#define GPIO_CTL1_MD11 BITS(12, 13) /*!< port 11 mode bits */ +#define GPIO_CTL1_CTL11 BITS(14, 15) /*!< pin 11 configuration bits */ +#define GPIO_CTL1_MD12 BITS(16, 17) /*!< port 12 mode bits */ +#define GPIO_CTL1_CTL12 BITS(18, 19) /*!< pin 12 configuration bits */ +#define GPIO_CTL1_MD13 BITS(20, 21) /*!< port 13 mode bits */ +#define GPIO_CTL1_CTL13 BITS(22, 23) /*!< pin 13 configuration bits */ +#define GPIO_CTL1_MD14 BITS(24, 25) /*!< port 14 mode bits */ +#define GPIO_CTL1_CTL14 BITS(26, 27) /*!< pin 14 configuration bits */ +#define GPIO_CTL1_MD15 BITS(28, 29) /*!< port 15 mode bits */ +#define GPIO_CTL1_CTL15 BITS(30, 31) /*!< pin 15 configuration 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_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_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 */ + +/* AFIO_EC */ +#define AFIO_EC_PIN BITS(0, 3) /*!< event output pin selection */ +#define AFIO_EC_PORT BITS(4, 6) /*!< event output port selection */ +#define AFIO_EC_EOE BIT(7) /*!< event output enable */ + +/* AFIO_PCF0 */ +/* memory map and bit definitions for GD32F10X_CL devices */ +#define AFIO_PCF0_SPI0_REMAP BIT(0) /*!< SPI0 remapping */ +#define AFIO_PCF0_I2C0_REMAP BIT(1) /*!< I2C0 remapping */ +#define AFIO_PCF0_USART0_REMAP BIT(2) /*!< USART0 remapping */ +#define AFIO_PCF0_USART1_REMAP BIT(3) /*!< USART1 remapping */ +#define AFIO_PCF0_USART2_REMAP BITS(4, 5) /*!< USART2 remapping */ +#define AFIO_PCF0_TIMER0_REMAP BITS(6, 7) /*!< TIMER0 remapping */ +#define AFIO_PCF0_TIMER1_REMAP BITS(8, 9) /*!< TIMER1 remapping */ +#define AFIO_PCF0_TIMER2_REMAP BITS(10, 11) /*!< TIMER2 remapping */ +#define AFIO_PCF0_TIMER3_REMAP BIT(12) /*!< TIMER3 remapping */ +#define AFIO_PCF0_CAN_REMAP BITS(13, 14) /*!< CAN remapping */ +#define AFIO_PCF0_PD01_REMAP BIT(15) /*!< port D0/port D1 mapping on OSC_IN/OSC_OUT */ +#define AFIO_PCF0_TIMER4CH3_IREMAP BIT(16) /*!< TIMER3 channel3 internal remapping */ +#define AFIO_PCF0_SWJ_CFG BITS(24, 26) /*!< serial wire JTAG configuration */ +#define AFIO_PCF0_SPI2_REMAP BIT(28) /*!< SPI2/I2S2 remapping */ +#define AFIO_PCF0_TIMER1_ITI1_REMAP BIT(29) /*!< TIMER1 internal trigger 1 remapping */ + +/* AFIO_EXTISS0 */ +#define AFIO_EXTI0_SS BITS(0, 3) /*!< EXTI 0 sources selection */ +#define AFIO_EXTI1_SS BITS(4, 7) /*!< EXTI 1 sources selection */ +#define AFIO_EXTI2_SS BITS(8, 11) /*!< EXTI 2 sources selection */ +#define AFIO_EXTI3_SS BITS(12, 15) /*!< EXTI 3 sources selection */ + +/* AFIO_EXTISS1 */ +#define AFIO_EXTI4_SS BITS(0, 3) /*!< EXTI 4 sources selection */ +#define AFIO_EXTI5_SS BITS(4, 7) /*!< EXTI 5 sources selection */ +#define AFIO_EXTI6_SS BITS(8, 11) /*!< EXTI 6 sources selection */ +#define AFIO_EXTI7_SS BITS(12, 15) /*!< EXTI 7 sources selection */ + +/* AFIO_EXTISS2 */ +#define AFIO_EXTI8_SS BITS(0, 3) /*!< EXTI 8 sources selection */ +#define AFIO_EXTI9_SS BITS(4, 7) /*!< EXTI 9 sources selection */ +#define AFIO_EXTI10_SS BITS(8, 11) /*!< EXTI 10 sources selection */ +#define AFIO_EXTI11_SS BITS(12, 15) /*!< EXTI 11 sources selection */ + +/* AFIO_EXTISS3 */ +#define AFIO_EXTI12_SS BITS(0, 3) /*!< EXTI 12 sources selection */ +#define AFIO_EXTI13_SS BITS(4, 7) /*!< EXTI 13 sources selection */ +#define AFIO_EXTI14_SS BITS(8, 11) /*!< EXTI 14 sources selection */ +#define AFIO_EXTI15_SS BITS(12, 15) /*!< EXTI 15 sources selection */ + +/* AFIO_PCF1 */ +#define AFIO_PCF1_EXMC_NADV BIT(10) /*!< EXMC_NADV connect/disconnect */ + +/* constants definitions */ +typedef FlagStatus bit_status; + +/* GPIO mode values set */ +#define GPIO_MODE_SET(n, mode) ((uint32_t)((uint32_t)(mode) << (4U * (n)))) +#define GPIO_MODE_MASK(n) (0xFU << (4U * (n))) + +/* GPIO mode definitions */ +#define GPIO_MODE_AIN ((uint8_t)0x00U) /*!< analog input mode */ +#define GPIO_MODE_IN_FLOATING ((uint8_t)0x04U) /*!< floating input mode */ +#define GPIO_MODE_IPD ((uint8_t)0x28U) /*!< pull-down input mode */ +#define GPIO_MODE_IPU ((uint8_t)0x48U) /*!< pull-up input mode */ +#define GPIO_MODE_OUT_OD ((uint8_t)0x14U) /*!< GPIO output with open-drain */ +#define GPIO_MODE_OUT_PP ((uint8_t)0x10U) /*!< GPIO output with push-pull */ +#define GPIO_MODE_AF_OD ((uint8_t)0x1CU) /*!< AFIO output with open-drain */ +#define GPIO_MODE_AF_PP ((uint8_t)0x18U) /*!< AFIO output with push-pull */ + +/* GPIO output max speed value */ +#define GPIO_OSPEED_10MHZ ((uint8_t)0x01U) /*!< output max speed 10MHz */ +#define GPIO_OSPEED_2MHZ ((uint8_t)0x02U) /*!< output max speed 2MHz */ +#define GPIO_OSPEED_50MHZ ((uint8_t)0x03U) /*!< output max speed 50MHz */ + +/* GPIO event output port definitions */ +#define GPIO_EVENT_PORT_GPIOA ((uint8_t)0x00U) /*!< event output port A */ +#define GPIO_EVENT_PORT_GPIOB ((uint8_t)0x01U) /*!< event output port B */ +#define GPIO_EVENT_PORT_GPIOC ((uint8_t)0x02U) /*!< event output port C */ +#define GPIO_EVENT_PORT_GPIOD ((uint8_t)0x03U) /*!< event output port D */ +#define GPIO_EVENT_PORT_GPIOE ((uint8_t)0x04U) /*!< event output port E */ + +/* GPIO output port source definitions */ +#define GPIO_PORT_SOURCE_GPIOA ((uint8_t)0x00U) /*!< output port source A */ +#define GPIO_PORT_SOURCE_GPIOB ((uint8_t)0x01U) /*!< output port source B */ +#define GPIO_PORT_SOURCE_GPIOC ((uint8_t)0x02U) /*!< output port source C */ +#define GPIO_PORT_SOURCE_GPIOD ((uint8_t)0x03U) /*!< output port source D */ +#define GPIO_PORT_SOURCE_GPIOE ((uint8_t)0x04U) /*!< output port source E */ + +/* GPIO event output pin definitions */ +#define GPIO_EVENT_PIN_0 ((uint8_t)0x00U) /*!< GPIO event pin 0 */ +#define GPIO_EVENT_PIN_1 ((uint8_t)0x01U) /*!< GPIO event pin 1 */ +#define GPIO_EVENT_PIN_2 ((uint8_t)0x02U) /*!< GPIO event pin 2 */ +#define GPIO_EVENT_PIN_3 ((uint8_t)0x03U) /*!< GPIO event pin 3 */ +#define GPIO_EVENT_PIN_4 ((uint8_t)0x04U) /*!< GPIO event pin 4 */ +#define GPIO_EVENT_PIN_5 ((uint8_t)0x05U) /*!< GPIO event pin 5 */ +#define GPIO_EVENT_PIN_6 ((uint8_t)0x06U) /*!< GPIO event pin 6 */ +#define GPIO_EVENT_PIN_7 ((uint8_t)0x07U) /*!< GPIO event pin 7 */ +#define GPIO_EVENT_PIN_8 ((uint8_t)0x08U) /*!< GPIO event pin 8 */ +#define GPIO_EVENT_PIN_9 ((uint8_t)0x09U) /*!< GPIO event pin 9 */ +#define GPIO_EVENT_PIN_10 ((uint8_t)0x0AU) /*!< GPIO event pin 10 */ +#define GPIO_EVENT_PIN_11 ((uint8_t)0x0BU) /*!< GPIO event pin 11 */ +#define GPIO_EVENT_PIN_12 ((uint8_t)0x0CU) /*!< GPIO event pin 12 */ +#define GPIO_EVENT_PIN_13 ((uint8_t)0x0DU) /*!< GPIO event pin 13 */ +#define GPIO_EVENT_PIN_14 ((uint8_t)0x0EU) /*!< GPIO event pin 14 */ +#define GPIO_EVENT_PIN_15 ((uint8_t)0x0FU) /*!< GPIO event pin 15 */ + +/* GPIO output pin source definitions */ +#define GPIO_PIN_SOURCE_0 ((uint8_t)0x00U) /*!< GPIO pin source 0 */ +#define GPIO_PIN_SOURCE_1 ((uint8_t)0x01U) /*!< GPIO pin source 1 */ +#define GPIO_PIN_SOURCE_2 ((uint8_t)0x02U) /*!< GPIO pin source 2 */ +#define GPIO_PIN_SOURCE_3 ((uint8_t)0x03U) /*!< GPIO pin source 3 */ +#define GPIO_PIN_SOURCE_4 ((uint8_t)0x04U) /*!< GPIO pin source 4 */ +#define GPIO_PIN_SOURCE_5 ((uint8_t)0x05U) /*!< GPIO pin source 5 */ +#define GPIO_PIN_SOURCE_6 ((uint8_t)0x06U) /*!< GPIO pin source 6 */ +#define GPIO_PIN_SOURCE_7 ((uint8_t)0x07U) /*!< GPIO pin source 7 */ +#define GPIO_PIN_SOURCE_8 ((uint8_t)0x08U) /*!< GPIO pin source 8 */ +#define GPIO_PIN_SOURCE_9 ((uint8_t)0x09U) /*!< GPIO pin source 9 */ +#define GPIO_PIN_SOURCE_10 ((uint8_t)0x0AU) /*!< GPIO pin source 10 */ +#define GPIO_PIN_SOURCE_11 ((uint8_t)0x0BU) /*!< GPIO pin source 11 */ +#define GPIO_PIN_SOURCE_12 ((uint8_t)0x0CU) /*!< GPIO pin source 12 */ +#define GPIO_PIN_SOURCE_13 ((uint8_t)0x0DU) /*!< GPIO pin source 13 */ +#define GPIO_PIN_SOURCE_14 ((uint8_t)0x0EU) /*!< GPIO pin source 14 */ +#define GPIO_PIN_SOURCE_15 ((uint8_t)0x0FU) /*!< GPIO pin source 15 */ + +/* 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 remap definitions */ +#define GPIO_SPI0_REMAP ((uint32_t)0x00000001U) /*!< SPI0 remapping */ +#define GPIO_I2C0_REMAP ((uint32_t)0x00000002U) /*!< I2C0 remapping */ +#define GPIO_USART0_REMAP ((uint32_t)0x00000004U) /*!< USART0 remapping */ +#define GPIO_USART1_REMAP ((uint32_t)0x00000008U) /*!< USART1 remapping */ +#define GPIO_USART2_PARTIAL_REMAP ((uint32_t)0x00140010U) /*!< USART2 partial remapping */ +#define GPIO_USART2_FULL_REMAP ((uint32_t)0x00140030U) /*!< USART2 full remapping */ +#define GPIO_TIMER0_PARTIAL_REMAP ((uint32_t)0x00160040U) /*!< TIMER0 partial remapping */ +#define GPIO_TIMER0_FULL_REMAP ((uint32_t)0x001600C0U) /*!< TIMER0 full remapping */ +#define GPIO_TIMER1_PARTIAL_REMAP0 ((uint32_t)0x00180100U) /*!< TIMER1 partial remapping */ +#define GPIO_TIMER1_PARTIAL_REMAP1 ((uint32_t)0x00180200U) /*!< TIMER1 partial remapping */ +#define GPIO_TIMER1_FULL_REMAP ((uint32_t)0x00180300U) /*!< TIMER1 full remapping */ +#define GPIO_TIMER2_PARTIAL_REMAP ((uint32_t)0x001A0800U) /*!< TIMER2 partial remapping */ +#define GPIO_TIMER2_FULL_REMAP ((uint32_t)0x001A0C00U) /*!< TIMER2 full remapping */ +#define GPIO_TIMER3_REMAP ((uint32_t)0x00001000U) /*!< TIMER3 remapping */ +#define GPIO_CAN0_PARTIAL_REMAP ((uint32_t)0x001D4000U) /*!< CAN0 partial remapping */ +#define GPIO_CAN0_FULL_REMAP ((uint32_t)0x001D6000U) /*!< CAN0 full remapping */ +#define GPIO_PD01_REMAP ((uint32_t)0x00008000U) /*!< PD01 remapping */ +#define GPIO_TIMER4CH3_IREMAP ((uint32_t)0x00200001U) /*!< TIMER4 channel3 internal remapping */ +#define GPIO_CAN1_REMAP ((uint32_t)0x00200040U) /*!< CAN1 remapping */ +#define GPIO_SWJ_NONJTRST_REMAP ((uint32_t)0x00300100U) /*!< full SWJ(JTAG-DP + SW-DP),but without NJTRST */ +#define GPIO_SWJ_SWDPENABLE_REMAP ((uint32_t)0x00300200U) /*!< JTAG-DP disabled */ +#define GPIO_SWJ_DISABLE_REMAP ((uint32_t)0x00300400U) /*!< JTAG-DP disabled */ +#define GPIO_SPI2_REMAP ((uint32_t)0x00201100U) /*!< SPI2 remapping */ +#define GPIO_TIMER1ITI1_REMAP ((uint32_t)0x00202000U) /*!< TIMER1 internal trigger 1 remapping */ +#define GPIO_EXMC_NADV_REMAP ((uint32_t)0x80000400U) /*!< EXMC_NADV connect/disconnect */ + +/* function declarations */ +/* reset GPIO port */ +void gpio_deinit(uint32_t gpio_periph); +/* reset alternate function I/O(AFIO) */ +void gpio_afio_deinit(void); +/* GPIO parameter initialization */ +void gpio_init(uint32_t gpio_periph,uint32_t mode,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); + +/* configure GPIO pin remap */ +void gpio_pin_remap_config(uint32_t remap, ControlStatus newvalue); + +/* select GPIO pin exti sources */ +void gpio_exti_source_select(uint8_t output_port, uint8_t output_pin); +/* configure GPIO pin event output */ +void gpio_event_output_config(uint8_t output_port, uint8_t output_pin); +/* enable GPIO pin event output */ +void gpio_event_output_enable(void); +/* disable GPIO pin event output */ +void gpio_event_output_disable(void); + +/* lock GPIO pin bit */ +void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin); + +#endif /* GD32VF103_GPIO_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_i2c.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..caba0015b07fec822cdf561c06e90c79db2c8734 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_i2c.h @@ -0,0 +1,342 @@ +/*! + \file gd32vf103_i2c.h + \brief definitions for the I2C + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_I2C_H +#define GD32VF103_I2C_H + +#include "gd32vf103.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) + 0x00U) /*!< I2C control register 0 */ +#define I2C_CTL1(i2cx) REG32((i2cx) + 0x04U) /*!< I2C control register 1 */ +#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x08U) /*!< I2C slave address register 0*/ +#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0CU) /*!< I2C slave address register */ +#define I2C_DATA(i2cx) REG32((i2cx) + 0x10U) /*!< I2C transfer buffer register */ +#define I2C_STAT0(i2cx) REG32((i2cx) + 0x14U) /*!< I2C transfer status register 0 */ +#define I2C_STAT1(i2cx) REG32((i2cx) + 0x18U) /*!< I2C transfer status register */ +#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x1CU) /*!< I2C clock configure register */ +#define I2C_RT(i2cx) REG32((i2cx) + 0x20U) /*!< I2C rise time register */ + +/* 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,5) /*!< I2CCLK[5:0] bits (peripheral clock frequency) */ +#define I2C_CTL1_ERRIE BIT(8) /*!< error interrupt enable */ +#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 (master mode) */ +#define I2C_CKCFG_DTCY BIT(14) /*!< fast mode duty cycle */ +#define I2C_CKCFG_FAST BIT(15) /*!< I2C speed selection in master mode */ + +/* I2Cx_RT */ +#define I2C_RT_RISETIME BITS(0,5) /*!< maximum rise time in fast/standard mode (Master mode) */ + +/* constants definitions */ +/* define the I2C bit position and its register index offset */ +#define I2C_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define I2C_REG_VAL(i2cx, offset) (REG32((i2cx) + (((uint32_t)(offset) & 0xFFFFU) >> 6))) +#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#define I2C_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define I2C_REG_VAL2(i2cx, offset) (REG32((i2cx) + ((uint32_t)(offset) >> 22))) +#define I2C_BIT_POS2(val) (((uint32_t)(val) & 0x1F0000U) >> 16) + +/* register offset */ +#define I2C_CTL1_REG_OFFSET 0x04U /*!< CTL1 register offset */ +#define I2C_STAT0_REG_OFFSET 0x14U /*!< STAT0 register offset */ +#define I2C_STAT1_REG_OFFSET 0x18U /*!< STAT1 register offset */ + +/* 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_DUMODF = 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 */ + +/* I2C dual-address mode switch */ +#define I2C_DUADEN_DISABLE ((uint32_t)0x00000000U) /*!< dual-address mode disabled */ +#define I2C_DUADEN_ENABLE ((uint32_t)0x00000001U) /*!< dual-address mode enabled */ + +/* whether or not to stretch SCL low */ +#define I2C_SCLSTRETCH_ENABLE ((uint32_t)0x00000000U) /*!< SCL stretching is enabled */ +#define I2C_SCLSTRETCH_DISABLE I2C_CTL0_SS /*!< 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 */ + +/* 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 */ +#define I2C_DTCY_2 ((uint32_t)0x00000000U) /*!< I2C fast mode Tlow/Thigh = 2 */ +#define I2C_DTCY_16_9 I2C_CKCFG_DTCY /*!< I2C fast mode Tlow/Thigh = 16/9 */ + +/* address mode for the I2C slave */ +#define I2C_ADDFORMAT_7BITS ((uint32_t)0x00000000U) /*!< address:7 bits */ +#define I2C_ADDFORMAT_10BITS I2C_SADDR0_ADDFORMAT /*!< address:10 bits */ + +/* function declarations */ +/* reset I2C */ +void i2c_deinit(uint32_t i2c_periph); +/* configure I2C clock */ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc); +/* configure I2C address */ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode,uint32_t addformat, uint32_t addr); +/* SMBus type selection */ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type); +/* whether or not to send an ACK */ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack); +/* configure I2C POAP position */ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos); +/* master sends slave address */ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr,uint32_t trandirection); +/* configure I2C saddress1 */ +void i2c_saddr1_config(uint32_t i2c_periph,uint32_t addr); +/* enable dual-address mode */ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t dualaddr); +/* disable dual-address mode */ +void i2c_dualaddr_disable(uint32_t i2c_periph); +/* enable I2C */ +void i2c_enable(uint32_t i2c_periph); +/* disable I2C */ +void i2c_disable(uint32_t i2c_periph); + +/* generate a START condition on I2C bus */ +void i2c_start_on_bus(uint32_t i2c_periph); +/* generate a STOP condition on I2C bus */ +void i2c_stop_on_bus(uint32_t i2c_periph); +/* I2C transmit data function */ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data); +/* I2C receive data function */ +uint8_t i2c_data_receive(uint32_t i2c_periph); +/* enable I2C DMA mode */ +void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate); +/* configure whether next DMA EOT is DMA last transfer or not */ +void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast); +/* whether to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara); +/* whether or not to response to a general call */ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara); +/* software reset I2C */ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset); + +/* I2C PEC calculation on or off */ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate); +/* I2C whether to transfer PEC value */ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara); +/* packet error checking value */ +uint8_t i2c_pec_value_get(uint32_t i2c_periph); +/* I2C issue alert through SMBA pin */ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara); +/* I2C ARP protocol in SMBus switch */ +void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate); + +/* 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 /* GD32VF103_I2C_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_pmu.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_pmu.h new file mode 100644 index 0000000000000000000000000000000000000000..244038127fbbea6f61f23f65f4568e7193922a6f --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_pmu.h @@ -0,0 +1,125 @@ +/*! + \file gd32vf103_pmu.h + \brief definitions for the PMU + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_PMU_H +#define GD32VF103_PMU_H + +#include "gd32vf103.h" + +/* PMU definitions */ +#define PMU PMU_BASE /*!< PMU base address */ + +/* registers definitions */ +#define PMU_CTL REG32((PMU) + 0x00U) /*!< PMU control register */ +#define PMU_CS REG32((PMU) + 0x04U) /*!< PMU control and status register */ + +/* bits definitions */ +/* PMU_CTL */ +#define PMU_CTL_LDOLP BIT(0) /*!< LDO low power mode */ +#define PMU_CTL_STBMOD BIT(1) /*!< standby mode */ +#define PMU_CTL_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL_LVDEN BIT(4) /*!< low voltage detector enable */ +#define PMU_CTL_LVDT BITS(5,7) /*!< low voltage detector threshold */ +#define PMU_CTL_BKPWEN BIT(8) /*!< backup domain write enable */ + +/* 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_WUPEN BIT(8) /*!< wakeup pin enable */ + +/* constants definitions */ +/* PMU low voltage detector threshold definitions */ +#define CTL_LVDT(regval) (BITS(5,7)&((uint32_t)(regval) << 5)) +#define PMU_LVDT_0 CTL_LVDT(0) /*!< voltage threshold is 2.2V */ +#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.5V */ +#define PMU_LVDT_4 CTL_LVDT(4) /*!< voltage threshold is 2.6V */ +#define PMU_LVDT_5 CTL_LVDT(5) /*!< voltage threshold is 2.7V */ +#define PMU_LVDT_6 CTL_LVDT(6) /*!< voltage threshold is 2.8V */ +#define PMU_LVDT_7 CTL_LVDT(7) /*!< voltage threshold is 2.9V */ + +/* PMU flag definitions */ +#define PMU_FLAG_WAKEUP PMU_CS_WUF /*!< wakeup flag status */ +#define PMU_FLAG_STANDBY PMU_CS_STBF /*!< standby flag status */ +#define PMU_FLAG_LVD PMU_CS_LVDF /*!< lvd flag status */ + +/* PMU ldo definitions */ +#define PMU_LDO_NORMAL ((uint32_t)0x00000000U) /*!< LDO normal work when PMU enter deepsleep mode */ +#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when PMU enter deepsleep mode */ + +/* PMU flag reset definitions */ +#define PMU_FLAG_RESET_WAKEUP ((uint8_t)0x00U) /*!< wakeup flag reset */ +#define PMU_FLAG_RESET_STANDBY ((uint8_t)0x01U) /*!< standby flag reset */ + +/* PMU command constants definitions */ +#define WFI_CMD ((uint8_t)0x00U) /*!< use WFI command */ +#define WFE_CMD ((uint8_t)0x01U) /*!< use WFE command */ + +/* function declarations */ +/* reset PMU registers */ +void pmu_deinit(void); + +/* select low voltage detector threshold */ +void pmu_lvd_select(uint32_t lvdt_n); +/* disable PMU lvd */ +void pmu_lvd_disable(void); + +/* set PMU mode */ +/* PMU work at sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* PMU work at deepsleep mode */ +void pmu_to_deepsleepmode(uint32_t ldo, uint8_t deepsleepmodecmd); +/* PMU work at standby mode */ +void pmu_to_standbymode(uint8_t standbymodecmd); +/* enable PMU wakeup pin */ +void pmu_wakeup_pin_enable(void); +/* disable PMU wakeup pin */ +void pmu_wakeup_pin_disable(void); + +/* backup related functions */ +/* enable write access to the registers in backup domain */ +void pmu_backup_write_enable(void); +/* disable write access to the registers in backup domain */ +void pmu_backup_write_disable(void); + +/* flag functions */ +/* get flag state */ +FlagStatus pmu_flag_get(uint32_t flag); +/* clear flag bit */ +void pmu_flag_clear(uint32_t flag_reset); + +#endif /* GD32VF103_PMU_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_rcu.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_rcu.h new file mode 100644 index 0000000000000000000000000000000000000000..56afb42ac74e62184e0258129d581438d44c8360 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_rcu.h @@ -0,0 +1,720 @@ +/*! + \file gd32vf103_rcu.h + \brief definitions for the RCU + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_RCU_H +#define GD32VF103_RCU_H + +#include "gd32vf103.h" + +/* RCU definitions */ +#define RCU RCU_BASE + +/* registers definitions */ + +#define RCU_CTL REG32(RCU + 0x00U) /*!< control register */ +#define RCU_CFG0 REG32(RCU + 0x04U) /*!< clock configuration register 0 */ +#define RCU_INT REG32(RCU + 0x08U) /*!< clock interrupt register */ +#define RCU_APB2RST REG32(RCU + 0x0CU) /*!< APB2 reset register */ +#define RCU_APB1RST REG32(RCU + 0x10U) /*!< APB1 reset register */ +#define RCU_AHBEN REG32(RCU + 0x14U) /*!< AHB1 enable register */ +#define RCU_APB2EN REG32(RCU + 0x18U) /*!< APB2 enable register */ +#define RCU_APB1EN REG32(RCU + 0x1CU) /*!< APB1 enable register */ +#define RCU_BDCTL REG32(RCU + 0x20U) /*!< backup domain control register */ +#define RCU_RSTSCK REG32(RCU + 0x24U) /*!< reset source / clock register */ +#define RCU_AHBRST REG32(RCU + 0x28U) /*!< AHB reset register */ +#define RCU_CFG1 REG32(RCU + 0x2CU) /*!< clock configuration register 1 */ +#define RCU_DSV REG32(RCU + 0x34U) /*!< deep-sleep mode voltage register */ + + +/* bits definitions */ +/* RCU_CTL */ +#define RCU_CTL_IRC8MEN BIT(0) /*!< internal high speed oscillator enable */ +#define RCU_CTL_IRC8MSTB BIT(1) /*!< IRC8M high speed internal oscillator stabilization flag */ +#define RCU_CTL_IRC8MADJ BITS(3,7) /*!< high speed internal oscillator clock trim adjust value */ +#define RCU_CTL_IRC8MCALIB BITS(8,15) /*!< high speed internal oscillator calibration value register */ +#define RCU_CTL_HXTALEN BIT(16) /*!< external high speed oscillator enable */ +#define RCU_CTL_HXTALSTB BIT(17) /*!< external crystal oscillator clock stabilization flag */ +#define RCU_CTL_HXTALBPS BIT(18) /*!< external crystal oscillator clock bypass mode enable */ +#define RCU_CTL_CKMEN BIT(19) /*!< HXTAL clock monitor enable */ +#define RCU_CTL_PLLEN BIT(24) /*!< PLL enable */ +#define RCU_CTL_PLLSTB BIT(25) /*!< PLL clock stabilization flag */ +#define RCU_CTL_PLL1EN BIT(26) /*!< PLL1 enable */ +#define RCU_CTL_PLL1STB BIT(27) /*!< PLL1 clock stabilization flag */ +#define RCU_CTL_PLL2EN BIT(28) /*!< PLL2 enable */ +#define RCU_CTL_PLL2STB BIT(29) /*!< PLL2 clock stabilization flag */ + + +#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 prescaler selection */ +#define RCU_CFG0_PLLSEL BIT(16) /*!< PLL clock source selection */ +#define RCU_CFG0_PREDV0_LSB BIT(17) /*!< the LSB of PREDV0 division factor */ +#define RCU_CFG0_PLLMF BITS(18,21) /*!< PLL clock multiplication factor */ +#define RCU_CFG0_USBFSPSC BITS(22,23) /*!< USBFS clock prescaler selection */ +#define RCU_CFG0_CKOUT0SEL BITS(24,27) /*!< CKOUT0 clock source selection */ +#define RCU_CFG0_ADCPSC_2 BIT(28) /*!< bit 2 of ADCPSC */ +#define RCU_CFG0_PLLMF_4 BIT(29) /*!< bit 4 of PLLMF */ + +/* 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_PLL1STBIF BIT(5) /*!< PLL1 stabilization interrupt flag */ +#define RCU_INT_PLL2STBIF BIT(6) /*!< PLL2 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_PLL1STBIE BIT(13) /*!< PLL1 stabilization interrupt enable */ +#define RCU_INT_PLL2STBIE BIT(14) /*!< PLL2 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_PLL1STBIC BIT(21) /*!< PLL1 stabilization interrupt clear */ +#define RCU_INT_PLL2STBIC BIT(22) /*!< PLL2 stabilization interrupt clear */ +#define RCU_INT_CKMIC BIT(23) /*!< HXTAL clock stuck interrupt clear */ + +/* RCU_APB2RST */ +#define RCU_APB2RST_AFRST BIT(0) /*!< alternate function I/O reset */ +#define RCU_APB2RST_PARST BIT(2) /*!< GPIO port A reset */ +#define RCU_APB2RST_PBRST BIT(3) /*!< GPIO port B reset */ +#define RCU_APB2RST_PCRST BIT(4) /*!< GPIO port C reset */ +#define RCU_APB2RST_PDRST BIT(5) /*!< GPIO port D reset */ +#define RCU_APB2RST_PERST BIT(6) /*!< GPIO port E reset */ +#define RCU_APB2RST_ADC0RST BIT(9) /*!< ADC0 reset */ +#define RCU_APB2RST_ADC1RST BIT(10) /*!< ADC1 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 */ + +/* RCU_APB1RST */ +#define RCU_APB1RST_TIMER1RST BIT(0) /*!< TIMER1 reset */ +#define RCU_APB1RST_TIMER2RST BIT(1) /*!< TIMER2 reset */ +#define RCU_APB1RST_TIMER3RST BIT(2) /*!< TIMER3 reset */ +#define RCU_APB1RST_TIMER4RST BIT(3) /*!< TIMER4 reset */ +#define RCU_APB1RST_TIMER5RST BIT(4) /*!< TIMER5 reset */ +#define RCU_APB1RST_TIMER6RST BIT(5) /*!< TIMER6 reset */ + +#define RCU_APB1RST_WWDGTRST BIT(11) /*!< WWDGT reset */ +#define RCU_APB1RST_SPI1RST BIT(14) /*!< SPI1 reset */ +#define RCU_APB1RST_SPI2RST BIT(15) /*!< SPI2 reset */ +#define RCU_APB1RST_USART1RST BIT(17) /*!< USART1 reset */ +#define RCU_APB1RST_USART2RST BIT(18) /*!< USART2 reset */ +#define RCU_APB1RST_UART3RST BIT(19) /*!< UART3 reset */ +#define RCU_APB1RST_UART4RST BIT(20) /*!< UART4 reset */ +#define RCU_APB1RST_I2C0RST BIT(21) /*!< I2C0 reset */ +#define RCU_APB1RST_I2C1RST BIT(22) /*!< I2C1 reset */ +#define RCU_APB1RST_CAN0RST BIT(25) /*!< CAN0 reset */ +#define RCU_APB1RST_CAN1RST BIT(26) /*!< CAN1 reset */ +#define RCU_APB1RST_BKPIRST BIT(27) /*!< backup interface reset */ +#define RCU_APB1RST_PMURST BIT(28) /*!< PMU reset */ +#define RCU_APB1RST_DACRST BIT(29) /*!< DAC reset */ + +/* RCU_AHBEN */ +#define RCU_AHBEN_DMA0EN BIT(0) /*!< DMA0 clock enable */ +#define RCU_AHBEN_DMA1EN BIT(1) /*!< DMA1 clock enable */ +#define RCU_AHBEN_SRAMSPEN BIT(2) /*!< SRAM clock enable when sleep mode */ +#define RCU_AHBEN_FMCSPEN BIT(4) /*!< FMC clock enable when sleep mode */ +#define RCU_AHBEN_CRCEN BIT(6) /*!< CRC clock enable */ +#define RCU_AHBEN_EXMCEN BIT(8) /*!< EXMC clock enable */ +#define RCU_AHBEN_USBFSEN BIT(12) /*!< USBFS clock enable */ + +/* RCU_APB2EN */ +#define RCU_APB2EN_AFEN BIT(0) /*!< alternate function IO clock enable */ +#define RCU_APB2EN_PAEN BIT(2) /*!< GPIO port A clock enable */ +#define RCU_APB2EN_PBEN BIT(3) /*!< GPIO port B clock enable */ +#define RCU_APB2EN_PCEN BIT(4) /*!< GPIO port C clock enable */ +#define RCU_APB2EN_PDEN BIT(5) /*!< GPIO port D clock enable */ +#define RCU_APB2EN_PEEN BIT(6) /*!< GPIO port E clock enable */ +#define RCU_APB2EN_ADC0EN BIT(9) /*!< ADC0 clock enable */ +#define RCU_APB2EN_ADC1EN BIT(10) /*!< ADC1 clock enable */ +#define RCU_APB2EN_TIMER0EN BIT(11) /*!< TIMER0 clock enable */ +#define RCU_APB2EN_SPI0EN BIT(12) /*!< SPI0 clock enable */ +#define RCU_APB2EN_USART0EN BIT(14) /*!< USART0 clock enable */ + +/* RCU_APB1EN */ +#define RCU_APB1EN_TIMER1EN BIT(0) /*!< TIMER1 clock enable */ +#define RCU_APB1EN_TIMER2EN BIT(1) /*!< TIMER2 clock enable */ +#define RCU_APB1EN_TIMER3EN BIT(2) /*!< TIMER3 clock enable */ +#define RCU_APB1EN_TIMER4EN BIT(3) /*!< TIMER4 clock enable */ +#define RCU_APB1EN_TIMER5EN BIT(4) /*!< TIMER5 clock enable */ +#define RCU_APB1EN_TIMER6EN BIT(5) /*!< TIMER6 clock enable */ +#define RCU_APB1EN_WWDGTEN BIT(11) /*!< WWDGT clock enable */ +#define RCU_APB1EN_SPI1EN BIT(14) /*!< SPI1 clock enable */ +#define RCU_APB1EN_SPI2EN BIT(15) /*!< SPI2 clock enable */ +#define RCU_APB1EN_USART1EN BIT(17) /*!< USART1 clock enable */ +#define RCU_APB1EN_USART2EN BIT(18) /*!< USART2 clock enable */ +#define RCU_APB1EN_UART3EN BIT(19) /*!< UART3 clock enable */ +#define RCU_APB1EN_UART4EN BIT(20) /*!< UART4 clock enable */ +#define RCU_APB1EN_I2C0EN BIT(21) /*!< I2C0 clock enable */ +#define RCU_APB1EN_I2C1EN BIT(22) /*!< I2C1 clock enable */ +#define RCU_APB1EN_CAN0EN BIT(25) /*!< CAN0 clock enable */ +#define RCU_APB1EN_CAN1EN BIT(26) /*!< CAN1 clock enable */ +#define RCU_APB1EN_BKPIEN BIT(27) /*!< backup interface clock enable */ +#define RCU_APB1EN_PMUEN BIT(28) /*!< PMU clock enable */ +#define RCU_APB1EN_DACEN BIT(29) /*!< DAC clock enable */ + +/* RCU_BDCTL */ +#define RCU_BDCTL_LXTALEN BIT(0) /*!< LXTAL enable */ +#define RCU_BDCTL_LXTALSTB BIT(1) /*!< low speed crystal oscillator stabilization flag */ +#define RCU_BDCTL_LXTALBPS BIT(2) /*!< LXTAL bypass mode enable */ +#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 flag */ +#define RCU_RSTSCK_RSTFC BIT(24) /*!< reset flag clear */ +#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 */ + +/* RCU_CFG1 */ +#define RCU_CFG1_PREDV0 BITS(0,3) /*!< PREDV0 division factor */ +#define RCU_CFG1_PREDV1 BITS(4,7) /*!< PREDV1 division factor */ +#define RCU_CFG1_PLL1MF BITS(8,11) /*!< PLL1 clock multiplication factor */ +#define RCU_CFG1_PLL2MF BITS(12,15) /*!< PLL2 clock multiplication factor */ +#define RCU_CFG1_PREDV0SEL BIT(16) /*!< PREDV0 input clock source selection */ +#define RCU_CFG1_I2S1SEL BIT(17) /*!< I2S1 clock source selection */ +#define RCU_CFG1_I2S2SEL BIT(18) /*!< I2S2 clock source selection */ + +/* RCU_DSV */ +#define RCU_DSV_DSLPVS BITS(0,1) /*!< deep-sleep mode voltage select */ + +/* constants definitions */ +/* define the peripheral clock enable bit position and its register index offset */ +#define RCU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph) >> 6))) +#define RCU_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +/* register offset */ +/* peripherals enable */ +#define AHBEN_REG_OFFSET 0x14U /*!< AHB enable register offset */ +#define APB1EN_REG_OFFSET 0x1CU /*!< APB1 enable register offset */ +#define APB2EN_REG_OFFSET 0x18U /*!< APB2 enable register offset */ + +/* peripherals reset */ +#define AHBRST_REG_OFFSET 0x28U /*!< AHB reset register offset */ +#define APB1RST_REG_OFFSET 0x10U /*!< APB1 reset register offset */ +#define APB2RST_REG_OFFSET 0x0CU /*!< APB2 reset register offset */ +#define RSTSCK_REG_OFFSET 0x24U /*!< reset source/clock register offset */ + +/* clock control */ +#define CTL_REG_OFFSET 0x00U /*!< control register offset */ +#define BDCTL_REG_OFFSET 0x20U /*!< backup domain control register offset */ + +/* clock stabilization and stuck interrupt */ +#define INT_REG_OFFSET 0x08U /*!< clock interrupt register offset */ + +/* configuration register */ +#define CFG0_REG_OFFSET 0x04U /*!< clock configuration register 0 offset */ +#define CFG1_REG_OFFSET 0x2CU /*!< clock configuration register 1 offset */ + +/* peripheral clock enable */ +typedef enum { + /* AHB peripherals */ + RCU_DMA0 = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 0U), /*!< DMA0 clock */ + RCU_DMA1 = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 1U), /*!< DMA1 clock */ + RCU_CRC = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 6U), /*!< CRC clock */ + RCU_EXMC = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 8U), /*!< EXMC clock */ + RCU_USBFS = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 12U), /*!< USBFS clock */ + /* APB1 peripherals */ + RCU_TIMER1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 0U), /*!< TIMER1 clock */ + RCU_TIMER2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 1U), /*!< TIMER2 clock */ + RCU_TIMER3 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 2U), /*!< TIMER3 clock */ + RCU_TIMER4 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 3U), /*!< TIMER4 clock */ + RCU_TIMER5 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 4U), /*!< TIMER5 clock */ + RCU_TIMER6 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 5U), /*!< TIMER6 clock */ + RCU_WWDGT = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 11U), /*!< WWDGT clock */ + RCU_SPI1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 14U), /*!< SPI1 clock */ + RCU_SPI2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 15U), /*!< SPI2 clock */ + RCU_USART1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 17U), /*!< USART1 clock */ + RCU_USART2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 18U), /*!< USART2 clock */ + RCU_UART3 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 19U), /*!< UART3 clock */ + RCU_UART4 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 20U), /*!< UART4 clock */ + RCU_I2C0 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 21U), /*!< I2C0 clock */ + RCU_I2C1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 22U), /*!< I2C1 clock */ + RCU_CAN0 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 25U), /*!< CAN0 clock */ + RCU_CAN1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 26U), /*!< CAN1 clock */ + RCU_BKPI = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 27U), /*!< BKPI clock */ + RCU_PMU = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 28U), /*!< PMU clock */ + RCU_DAC = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 29U), /*!< DAC clock */ + RCU_RTC = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 15U), /*!< RTC clock */ + /* APB2 peripherals */ + RCU_AF = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 0U), /*!< alternate function clock */ + RCU_GPIOA = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 2U), /*!< GPIOA clock */ + RCU_GPIOB = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 3U), /*!< GPIOB clock */ + RCU_GPIOC = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 4U), /*!< GPIOC clock */ + RCU_GPIOD = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 5U), /*!< GPIOD clock */ + RCU_GPIOE = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 6U), /*!< GPIOE clock */ + RCU_ADC0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 9U), /*!< ADC0 clock */ + RCU_ADC1 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 10U), /*!< ADC1 clock */ + RCU_TIMER0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 11U), /*!< TIMER0 clock */ + RCU_SPI0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 12U), /*!< SPI0 clock */ + RCU_USART0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 14U), /*!< USART0 clock */ +} rcu_periph_enum; + +/* peripheral clock enable when sleep mode*/ +typedef enum { +/* AHB peripherals */ + RCU_SRAM_SLP = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 2U), /*!< SRAM clock */ + RCU_FMC_SLP = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 4U), /*!< FMC clock */ +} rcu_periph_sleep_enum; + +/* peripherals reset */ +typedef enum { + /* AHB peripherals */ + RCU_USBFSRST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 12U), /*!< USBFS clock reset */ + /* APB1 peripherals */ + RCU_TIMER1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 0U), /*!< TIMER1 clock reset */ + RCU_TIMER2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 1U), /*!< TIMER2 clock reset */ + RCU_TIMER3RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 2U), /*!< TIMER3 clock reset */ + RCU_TIMER4RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 3U), /*!< TIMER4 clock reset */ + RCU_TIMER5RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 4U), /*!< TIMER5 clock reset */ + RCU_TIMER6RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 5U), /*!< TIMER6 clock reset */ + RCU_WWDGTRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 11U), /*!< WWDGT clock reset */ + RCU_SPI1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 14U), /*!< SPI1 clock reset */ + RCU_SPI2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 15U), /*!< SPI2 clock reset */ + RCU_USART1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 17U), /*!< USART1 clock reset */ + RCU_USART2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 18U), /*!< USART2 clock reset */ + RCU_UART3RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 19U), /*!< UART3 clock reset */ + RCU_UART4RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 20U), /*!< UART4 clock reset */ + RCU_I2C0RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 21U), /*!< I2C0 clock reset */ + RCU_I2C1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 22U), /*!< I2C1 clock reset */ + RCU_CAN0RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 25U), /*!< CAN0 clock reset */ + RCU_CAN1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 26U), /*!< CAN1 clock reset */ + RCU_BKPIRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 27U), /*!< BKPI clock reset */ + RCU_PMURST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 28U), /*!< PMU clock reset */ + RCU_DACRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 29U), /*!< DAC clock reset */ + /* APB2 peripherals */ + RCU_AFRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 0U), /*!< alternate function clock reset */ + RCU_GPIOARST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 2U), /*!< GPIOA clock reset */ + RCU_GPIOBRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 3U), /*!< GPIOB clock reset */ + RCU_GPIOCRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 4U), /*!< GPIOC clock reset */ + RCU_GPIODRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 5U), /*!< GPIOD clock reset */ + RCU_GPIOERST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 6U), /*!< GPIOE clock reset */ + RCU_ADC0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 9U), /*!< ADC0 clock reset */ + RCU_ADC1RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 10U), /*!< ADC1 clock reset */ + RCU_TIMER0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 11U), /*!< TIMER0 clock reset */ + RCU_SPI0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 12U), /*!< SPI0 clock reset */ + RCU_USART0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 14U), /*!< USART0 clock reset */ +} rcu_periph_reset_enum; + +/* clock stabilization and peripheral reset flags */ +typedef enum { + /* clock stabilization flags */ + RCU_FLAG_IRC8MSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 1U), /*!< IRC8M stabilization flags */ + RCU_FLAG_HXTALSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 17U), /*!< HXTAL stabilization flags */ + RCU_FLAG_PLLSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 25U), /*!< PLL stabilization flags */ + RCU_FLAG_PLL1STB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 27U), /*!< PLL1 stabilization flags */ + RCU_FLAG_PLL2STB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 29U), /*!< PLL2 stabilization flags */ + RCU_FLAG_LXTALSTB = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 1U), /*!< LXTAL stabilization flags */ + RCU_FLAG_IRC40KSTB = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 1U), /*!< IRC40K stabilization flags */ + /* reset source flags */ + RCU_FLAG_EPRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 26U), /*!< external PIN reset flags */ + RCU_FLAG_PORRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 27U), /*!< power reset flags */ + RCU_FLAG_SWRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 28U), /*!< software reset flags */ + RCU_FLAG_FWDGTRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 29U), /*!< FWDGT reset flags */ + RCU_FLAG_WWDGTRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 30U), /*!< WWDGT reset flags */ + RCU_FLAG_LPRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 31U), /*!< low-power reset flags */ +} rcu_flag_enum; + +/* clock stabilization and ckm interrupt flags */ +typedef enum { + RCU_INT_FLAG_IRC40KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 0U), /*!< IRC40K stabilization interrupt flag */ + RCU_INT_FLAG_LXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 1U), /*!< LXTAL stabilization interrupt flag */ + RCU_INT_FLAG_IRC8MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 2U), /*!< IRC8M stabilization interrupt flag */ + RCU_INT_FLAG_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 3U), /*!< HXTAL stabilization interrupt flag */ + RCU_INT_FLAG_PLLSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 4U), /*!< PLL stabilization interrupt flag */ + RCU_INT_FLAG_PLL1STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 5U), /*!< PLL1 stabilization interrupt flag */ + RCU_INT_FLAG_PLL2STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 6U), /*!< PLL2 stabilization interrupt flag */ + RCU_INT_FLAG_CKM = RCU_REGIDX_BIT(INT_REG_OFFSET, 7U), /*!< HXTAL clock stuck interrupt flag */ +} rcu_int_flag_enum; + +/* clock stabilization and stuck interrupt flags clear */ +typedef enum { + RCU_INT_FLAG_IRC40KSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 16U), /*!< IRC40K stabilization interrupt flags clear */ + RCU_INT_FLAG_LXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 17U), /*!< LXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_IRC8MSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 18U), /*!< IRC8M stabilization interrupt flags clear */ + RCU_INT_FLAG_HXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 19U), /*!< HXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 20U), /*!< PLL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLL1STB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 21U), /*!< PLL1 stabilization interrupt flags clear */ + RCU_INT_FLAG_PLL2STB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 22U), /*!< PLL2 stabilization interrupt flags clear */ + RCU_INT_FLAG_CKM_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 23U), /*!< CKM interrupt flags clear */ +} rcu_int_flag_clear_enum; + +/* clock stabilization interrupt enable or disable */ +typedef enum { + RCU_INT_IRC40KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 8U), /*!< IRC40K stabilization interrupt */ + RCU_INT_LXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 9U), /*!< LXTAL stabilization interrupt */ + RCU_INT_IRC8MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 10U), /*!< IRC8M stabilization interrupt */ + RCU_INT_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 11U), /*!< HXTAL stabilization interrupt */ + RCU_INT_PLLSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 12U), /*!< PLL stabilization interrupt */ + RCU_INT_PLL1STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 13U), /*!< PLL1 stabilization interrupt */ + RCU_INT_PLL2STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 14U), /*!< PLL2 stabilization interrupt */ +} rcu_int_enum; + +/* oscillator types */ +typedef enum { + RCU_HXTAL = RCU_REGIDX_BIT(CTL_REG_OFFSET, 16U), /*!< HXTAL */ + RCU_LXTAL = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 0U), /*!< LXTAL */ + RCU_IRC8M = RCU_REGIDX_BIT(CTL_REG_OFFSET, 0U), /*!< IRC8M */ + RCU_IRC40K = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 0U), /*!< IRC40K */ + RCU_PLL_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 24U), /*!< PLL */ + RCU_PLL1_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 26U), /*!< PLL1 */ + RCU_PLL2_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 28U), /*!< PLL2 */ +} rcu_osci_type_enum; + +/* rcu clock frequency */ +typedef enum { + CK_SYS = 0, /*!< system clock */ + CK_AHB, /*!< AHB clock */ + CK_APB1, /*!< APB1 clock */ + CK_APB2, /*!< APB2 clock */ +} rcu_clock_freq_enum; + +/* RCU_CFG0 register bit define */ +/* 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 PLLP */ + +/* 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 prescaler select */ +#define RCU_CKADC_CKAPB2_DIV2 ((uint32_t)0x00000000U) /*!< ADC prescaler select CK_APB2/2 */ +#define RCU_CKADC_CKAPB2_DIV4 ((uint32_t)0x00000001U) /*!< ADC prescaler select CK_APB2/4 */ +#define RCU_CKADC_CKAPB2_DIV6 ((uint32_t)0x00000002U) /*!< ADC prescaler select CK_APB2/6 */ +#define RCU_CKADC_CKAPB2_DIV8 ((uint32_t)0x00000003U) /*!< ADC prescaler select CK_APB2/8 */ +#define RCU_CKADC_CKAPB2_DIV12 ((uint32_t)0x00000005U) /*!< ADC prescaler select CK_APB2/12 */ +#define RCU_CKADC_CKAPB2_DIV16 ((uint32_t)0x00000007U) /*!< ADC prescaler select CK_APB2/16 */ + +/* PLL clock source selection */ +#define RCU_PLLSRC_IRC8M_DIV2 ((uint32_t)0x00000000U) /*!< IRC8M/2 clock selected as source clock of PLL */ +#define RCU_PLLSRC_HXTAL RCU_CFG0_PLLSEL /*!< HXTAL clock selected as source clock of PLL */ + +/* PLL clock multiplication factor */ +#define PLLMF_4 RCU_CFG0_PLLMF_4 /* bit 4 of PLLMF */ + +#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_MUL6_5 CFG0_PLLMF(13) /*!< PLL source clock multiply by 6.5 */ +#define RCU_PLL_MUL16 CFG0_PLLMF(14) /*!< PLL source clock multiply by 16 */ +#define RCU_PLL_MUL17 (PLLMF_4 | CFG0_PLLMF(0)) /*!< PLL source clock multiply by 17 */ +#define RCU_PLL_MUL18 (PLLMF_4 | CFG0_PLLMF(1)) /*!< PLL source clock multiply by 18 */ +#define RCU_PLL_MUL19 (PLLMF_4 | CFG0_PLLMF(2)) /*!< PLL source clock multiply by 19 */ +#define RCU_PLL_MUL20 (PLLMF_4 | CFG0_PLLMF(3)) /*!< PLL source clock multiply by 20 */ +#define RCU_PLL_MUL21 (PLLMF_4 | CFG0_PLLMF(4)) /*!< PLL source clock multiply by 21 */ +#define RCU_PLL_MUL22 (PLLMF_4 | CFG0_PLLMF(5)) /*!< PLL source clock multiply by 22 */ +#define RCU_PLL_MUL23 (PLLMF_4 | CFG0_PLLMF(6)) /*!< PLL source clock multiply by 23 */ +#define RCU_PLL_MUL24 (PLLMF_4 | CFG0_PLLMF(7)) /*!< PLL source clock multiply by 24 */ +#define RCU_PLL_MUL25 (PLLMF_4 | CFG0_PLLMF(8)) /*!< PLL source clock multiply by 25 */ +#define RCU_PLL_MUL26 (PLLMF_4 | CFG0_PLLMF(9)) /*!< PLL source clock multiply by 26 */ +#define RCU_PLL_MUL27 (PLLMF_4 | CFG0_PLLMF(10)) /*!< PLL source clock multiply by 27 */ +#define RCU_PLL_MUL28 (PLLMF_4 | CFG0_PLLMF(11)) /*!< PLL source clock multiply by 28 */ +#define RCU_PLL_MUL29 (PLLMF_4 | CFG0_PLLMF(12)) /*!< PLL source clock multiply by 29 */ +#define RCU_PLL_MUL30 (PLLMF_4 | CFG0_PLLMF(13)) /*!< PLL source clock multiply by 30 */ +#define RCU_PLL_MUL31 (PLLMF_4 | CFG0_PLLMF(14)) /*!< PLL source clock multiply by 31 */ +#define RCU_PLL_MUL32 (PLLMF_4 | CFG0_PLLMF(15)) /*!< PLL source clock multiply by 32 */ + +/* USBFS prescaler select */ +#define CFG0_USBPSC(regval) (BITS(22,23) & ((uint32_t)(regval) << 22)) +#define RCU_CKUSB_CKPLL_DIV1_5 CFG0_USBPSC(0) /*!< USBFS prescaler select CK_PLL/1.5 */ +#define RCU_CKUSB_CKPLL_DIV1 CFG0_USBPSC(1) /*!< USBFS prescaler select CK_PLL/1 */ +#define RCU_CKUSB_CKPLL_DIV2_5 CFG0_USBPSC(2) /*!< USBFS prescaler select CK_PLL/2.5 */ +#define RCU_CKUSB_CKPLL_DIV2 CFG0_USBPSC(3) /*!< USBFS prescaler select CK_PLL/2 */ + +/* CKOUT0 clock source selection */ +#define CFG0_CKOUT0SEL(regval) (BITS(24,27) & ((uint32_t)(regval) << 24)) +#define RCU_CKOUT0SRC_NONE CFG0_CKOUT0SEL(0) /*!< no clock selected */ +#define RCU_CKOUT0SRC_CKSYS CFG0_CKOUT0SEL(4) /*!< system clock selected */ +#define RCU_CKOUT0SRC_IRC8M CFG0_CKOUT0SEL(5) /*!< internal 8M RC oscillator clock selected */ +#define RCU_CKOUT0SRC_HXTAL CFG0_CKOUT0SEL(6) /*!< high speed crystal oscillator clock (HXTAL) selected */ +#define RCU_CKOUT0SRC_CKPLL_DIV2 CFG0_CKOUT0SEL(7) /*!< CK_PLL/2 clock selected */ +#define RCU_CKOUT0SRC_CKPLL1 CFG0_CKOUT0SEL(8) /*!< CK_PLL1 clock selected */ +#define RCU_CKOUT0SRC_CKPLL2_DIV2 CFG0_CKOUT0SEL(9) /*!< CK_PLL2/2 clock selected */ +#define RCU_CKOUT0SRC_EXT1 CFG0_CKOUT0SEL(10) /*!< EXT1 selected */ +#define RCU_CKOUT0SRC_CKPLL2 CFG0_CKOUT0SEL(11) /*!< CK_PLL2 clock selected */ + +/* 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) /*!< RTC source clock select LXTAL */ +#define RCU_RTCSRC_IRC40K BDCTL_RTCSRC(2) /*!< RTC source clock select IRC40K */ +#define RCU_RTCSRC_HXTAL_DIV_128 BDCTL_RTCSRC(3) /*!< RTC source clock select HXTAL/128 */ + +/* PREDV0 division factor */ +#define CFG1_PREDV0(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define RCU_PREDV0_DIV1 CFG1_PREDV0(0) /*!< PREDV0 input source clock not divided */ +#define RCU_PREDV0_DIV2 CFG1_PREDV0(1) /*!< PREDV0 input source clock divided by 2 */ +#define RCU_PREDV0_DIV3 CFG1_PREDV0(2) /*!< PREDV0 input source clock divided by 3 */ +#define RCU_PREDV0_DIV4 CFG1_PREDV0(3) /*!< PREDV0 input source clock divided by 4 */ +#define RCU_PREDV0_DIV5 CFG1_PREDV0(4) /*!< PREDV0 input source clock divided by 5 */ +#define RCU_PREDV0_DIV6 CFG1_PREDV0(5) /*!< PREDV0 input source clock divided by 6 */ +#define RCU_PREDV0_DIV7 CFG1_PREDV0(6) /*!< PREDV0 input source clock divided by 7 */ +#define RCU_PREDV0_DIV8 CFG1_PREDV0(7) /*!< PREDV0 input source clock divided by 8 */ +#define RCU_PREDV0_DIV9 CFG1_PREDV0(8) /*!< PREDV0 input source clock divided by 9 */ +#define RCU_PREDV0_DIV10 CFG1_PREDV0(9) /*!< PREDV0 input source clock divided by 10 */ +#define RCU_PREDV0_DIV11 CFG1_PREDV0(10) /*!< PREDV0 input source clock divided by 11 */ +#define RCU_PREDV0_DIV12 CFG1_PREDV0(11) /*!< PREDV0 input source clock divided by 12 */ +#define RCU_PREDV0_DIV13 CFG1_PREDV0(12) /*!< PREDV0 input source clock divided by 13 */ +#define RCU_PREDV0_DIV14 CFG1_PREDV0(13) /*!< PREDV0 input source clock divided by 14 */ +#define RCU_PREDV0_DIV15 CFG1_PREDV0(14) /*!< PREDV0 input source clock divided by 15 */ +#define RCU_PREDV0_DIV16 CFG1_PREDV0(15) /*!< PREDV0 input source clock divided by 16 */ + +/* PREDV1 division factor */ +#define CFG1_PREDV1(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define RCU_PREDV1_DIV1 CFG1_PREDV1(0) /*!< PREDV1 input source clock not divided */ +#define RCU_PREDV1_DIV2 CFG1_PREDV1(1) /*!< PREDV1 input source clock divided by 2 */ +#define RCU_PREDV1_DIV3 CFG1_PREDV1(2) /*!< PREDV1 input source clock divided by 3 */ +#define RCU_PREDV1_DIV4 CFG1_PREDV1(3) /*!< PREDV1 input source clock divided by 4 */ +#define RCU_PREDV1_DIV5 CFG1_PREDV1(4) /*!< PREDV1 input source clock divided by 5 */ +#define RCU_PREDV1_DIV6 CFG1_PREDV1(5) /*!< PREDV1 input source clock divided by 6 */ +#define RCU_PREDV1_DIV7 CFG1_PREDV1(6) /*!< PREDV1 input source clock divided by 7 */ +#define RCU_PREDV1_DIV8 CFG1_PREDV1(7) /*!< PREDV1 input source clock divided by 8 */ +#define RCU_PREDV1_DIV9 CFG1_PREDV1(8) /*!< PREDV1 input source clock divided by 9 */ +#define RCU_PREDV1_DIV10 CFG1_PREDV1(9) /*!< PREDV1 input source clock divided by 10 */ +#define RCU_PREDV1_DIV11 CFG1_PREDV1(10) /*!< PREDV1 input source clock divided by 11 */ +#define RCU_PREDV1_DIV12 CFG1_PREDV1(11) /*!< PREDV1 input source clock divided by 12 */ +#define RCU_PREDV1_DIV13 CFG1_PREDV1(12) /*!< PREDV1 input source clock divided by 13 */ +#define RCU_PREDV1_DIV14 CFG1_PREDV1(13) /*!< PREDV1 input source clock divided by 14 */ +#define RCU_PREDV1_DIV15 CFG1_PREDV1(14) /*!< PREDV1 input source clock divided by 15 */ +#define RCU_PREDV1_DIV16 CFG1_PREDV1(15) /*!< PREDV1 input source clock divided by 16 */ + +/* PLL1 clock multiplication factor */ +#define CFG1_PLL1MF(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) +#define RCU_PLL1_MUL8 CFG1_PLL1MF(6) /*!< PLL1 source clock multiply by 8 */ +#define RCU_PLL1_MUL9 CFG1_PLL1MF(7) /*!< PLL1 source clock multiply by 9 */ +#define RCU_PLL1_MUL10 CFG1_PLL1MF(8) /*!< PLL1 source clock multiply by 10 */ +#define RCU_PLL1_MUL11 CFG1_PLL1MF(9) /*!< PLL1 source clock multiply by 11 */ +#define RCU_PLL1_MUL12 CFG1_PLL1MF(10) /*!< PLL1 source clock multiply by 12 */ +#define RCU_PLL1_MUL13 CFG1_PLL1MF(11) /*!< PLL1 source clock multiply by 13 */ +#define RCU_PLL1_MUL14 CFG1_PLL1MF(12) /*!< PLL1 source clock multiply by 14 */ +#define RCU_PLL1_MUL15 CFG1_PLL1MF(13) /*!< PLL1 source clock multiply by 15 */ +#define RCU_PLL1_MUL16 CFG1_PLL1MF(14) /*!< PLL1 source clock multiply by 16 */ +#define RCU_PLL1_MUL20 CFG1_PLL1MF(15) /*!< PLL1 source clock multiply by 20 */ + +/* PLL2 clock multiplication factor */ +#define CFG1_PLL2MF(regval) (BITS(12,15) & ((uint32_t)(regval) << 12)) +#define RCU_PLL2_MUL8 CFG1_PLL2MF(6) /*!< PLL2 source clock multiply by 8 */ +#define RCU_PLL2_MUL9 CFG1_PLL2MF(7) /*!< PLL2 source clock multiply by 9 */ +#define RCU_PLL2_MUL10 CFG1_PLL2MF(8) /*!< PLL2 source clock multiply by 10 */ +#define RCU_PLL2_MUL11 CFG1_PLL2MF(9) /*!< PLL2 source clock multiply by 11 */ +#define RCU_PLL2_MUL12 CFG1_PLL2MF(10) /*!< PLL2 source clock multiply by 12 */ +#define RCU_PLL2_MUL13 CFG1_PLL2MF(11) /*!< PLL2 source clock multiply by 13 */ +#define RCU_PLL2_MUL14 CFG1_PLL2MF(12) /*!< PLL2 source clock multiply by 14 */ +#define RCU_PLL2_MUL15 CFG1_PLL2MF(13) /*!< PLL2 source clock multiply by 15 */ +#define RCU_PLL2_MUL16 CFG1_PLL2MF(14) /*!< PLL2 source clock multiply by 16 */ +#define RCU_PLL2_MUL20 CFG1_PLL2MF(15) /*!< PLL2 source clock multiply by 20 */ + + +/* PREDV0 input clock source selection */ +#define RCU_PREDV0SRC_HXTAL ((uint32_t)0x00000000U) /*!< HXTAL selected as PREDV0 input source clock */ +#define RCU_PREDV0SRC_CKPLL1 RCU_CFG1_PREDV0SEL /*!< CK_PLL1 selected as PREDV0 input source clock */ + +/* I2S1 clock source selection */ +#define RCU_I2S1SRC_CKSYS ((uint32_t)0x00000000U) /*!< system clock selected as I2S1 source clock */ +#define RCU_I2S1SRC_CKPLL2_MUL2 RCU_CFG1_I2S1SEL /*!< (CK_PLL2 x 2) selected as I2S1 source clock */ + +/* I2S2 clock source selection */ +#define RCU_I2S2SRC_CKSYS ((uint32_t)0x00000000U) /*!< system clock selected as I2S2 source clock */ +#define RCU_I2S2SRC_CKPLL2_MUL2 RCU_CFG1_I2S2SEL /*!< (CK_PLL2 x 2) selected as I2S2 source clock */ + + +/* deep-sleep mode voltage */ +#define DSV_DSLPVS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_DEEPSLEEP_V_1_2 DSV_DSLPVS(0) /*!< core voltage is 1.2V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_1 DSV_DSLPVS(1) /*!< core voltage is 1.1V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_0 DSV_DSLPVS(2) /*!< core voltage is 1.0V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0_9 DSV_DSLPVS(3) /*!< core voltage is 0.9V in deep-sleep mode */ + +/* function declarations */ +/* initialization, peripheral clock enable/disable functions */ +/* 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 domain */ +void rcu_bkp_reset_enable(void); +/* disable the BKP domain reset */ +void rcu_bkp_reset_disable(void); + +/* clock configuration functions */ +/* 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 CK_OUT0 clock source and divider */ +void rcu_ckout0_config(uint32_t ckout0_src); +/* configure the PLL clock source selection and PLL multiply factor */ +void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul); + +/* configure the PREDV0 division factor and clock source */ +void rcu_predv0_config(uint32_t predv0_source, uint32_t predv0_div); +/* configure the PREDV1 division factor */ +void rcu_predv1_config(uint32_t predv1_div); +/* configure the PLL1 clock */ +void rcu_pll1_config(uint32_t pll_mul); +/* configure the PLL2 clock */ +void rcu_pll2_config(uint32_t pll_mul); + +/* peripheral clock configuration functions */ +/* configure the ADC division factor */ +void rcu_adc_clock_config(uint32_t adc_psc); +/* configure the USBD/USBFS prescaler factor */ +void rcu_usb_clock_config(uint32_t usb_psc); +/* configure the RTC clock source selection */ +void rcu_rtc_clock_config(uint32_t rtc_clock_source); + +/* configure the I2S1 clock source selection */ +void rcu_i2s1_clock_config(uint32_t i2s_clock_source); +/* configure the I2S2 clock source selection */ +void rcu_i2s2_clock_config(uint32_t i2s_clock_source); + +/* interrupt & flag functions */ +/* 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); + +/* oscillator configuration functions */ +/* wait for oscillator stabilization flags is SET or oscillator startup is timeout */ +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, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci); +/* disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +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(uint32_t irc8m_adjval); +/* 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 /* GD32VF103_RCU_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_rtc.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..e17cdaa62d079632a490bdf2f8b9e9d2d38c9dfc --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_rtc.h @@ -0,0 +1,148 @@ +/*! + \file gd32vf103_rtc.h + \brief definitions for the RTC + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_RTC_H +#define GD32VF103_RTC_H + +#include "gd32vf103.h" + +/* RTC definitions */ +#define RTC RTC_BASE + +/* registers definitions */ +#define RTC_INTEN REG32(RTC + 0x00U) /*!< interrupt enable register */ +#define RTC_CTL REG32(RTC + 0x04U) /*!< control register */ +#define RTC_PSCH REG32(RTC + 0x08U) /*!< prescaler high register */ +#define RTC_PSCL REG32(RTC + 0x0CU) /*!< prescaler low register */ +#define RTC_DIVH REG32(RTC + 0x10U) /*!< divider high register */ +#define RTC_DIVL REG32(RTC + 0x14U) /*!< divider low register */ +#define RTC_CNTH REG32(RTC + 0x18U) /*!< counter high register */ +#define RTC_CNTL REG32(RTC + 0x1CU) /*!< counter low register */ +#define RTC_ALRMH REG32(RTC + 0x20U) /*!< alarm high register */ +#define RTC_ALRML REG32(RTC + 0x24U) /*!< alarm low register */ + +/* bits definitions */ +/* RTC_INTEN */ +#define RTC_INTEN_SCIE BIT(0) /*!< second interrupt enable */ +#define RTC_INTEN_ALRMIE BIT(1) /*!< alarm interrupt enable */ +#define RTC_INTEN_OVIE BIT(2) /*!< overflow interrupt enable */ + +/* RTC_CTL */ +#define RTC_CTL_SCIF BIT(0) /*!< second interrupt flag */ +#define RTC_CTL_ALRMIF BIT(1) /*!< alarm interrupt flag */ +#define RTC_CTL_OVIF BIT(2) /*!< overflow interrupt flag */ +#define RTC_CTL_RSYNF BIT(3) /*!< registers synchronized flag */ +#define RTC_CTL_CMF BIT(4) /*!< configuration mode flag */ +#define RTC_CTL_LWOFF BIT(5) /*!< last write operation finished flag */ + +/* RTC_PSCH */ +#define RTC_PSCH_PSC BITS(0,3) /*!< prescaler high value */ + +/* RTC_PSCL */ +#define RTC_PSCL_PSC BITS(0,15) /*!< prescaler low value */ + +/* RTC_DIVH */ +#define RTC_DIVH_DIV BITS(0,3) /*!< divider high value */ + +/* RTC_DIVL */ +#define RTC_DIVL_DIV BITS(0,15) /*!< divider low value */ + +/* RTC_CNTH */ +#define RTC_CNTH_CNT BITS(0,15) /*!< counter high value */ + +/* RTC_CNTL */ +#define RTC_CNTL_CNT BITS(0,15) /*!< counter low value */ + +/* RTC_ALRMH */ +#define RTC_ALRMH_ALRM BITS(0,15) /*!< alarm high value */ + +/* RTC_ALRML */ +#define RTC_ALRML_ALRM BITS(0,15) /*!< alarm low value */ + +/* constants definitions */ +/* RTC interrupt enable or disable definitions */ +#define RTC_INT_SECOND RTC_INTEN_SCIE /*!< second interrupt enable */ +#define RTC_INT_ALARM RTC_INTEN_ALRMIE /*!< alarm interrupt enable */ +#define RTC_INT_OVERFLOW RTC_INTEN_OVIE /*!< overflow interrupt enable */ + +/* RTC interrupt flag definitions */ +#define RTC_INT_FLAG_SECOND RTC_CTL_SCIF /*!< second interrupt flag */ +#define RTC_INT_FLAG_ALARM RTC_CTL_ALRMIF /*!< alarm interrupt flag */ +#define RTC_INT_FLAG_OVERFLOW RTC_CTL_OVIF /*!< overflow interrupt flag */ + +/* RTC flag definitions */ +#define RTC_FLAG_SECOND RTC_CTL_SCIF /*!< second interrupt flag */ +#define RTC_FLAG_ALARM RTC_CTL_ALRMIF /*!< alarm interrupt flag */ +#define RTC_FLAG_OVERFLOW RTC_CTL_OVIF /*!< overflow interrupt flag */ +#define RTC_FLAG_RSYN RTC_CTL_RSYNF /*!< registers synchronized flag */ +#define RTC_FLAG_LWOF RTC_CTL_LWOFF /*!< last write operation finished flag */ + +/* function declarations */ +/* initialization functions */ +/* enter RTC configuration mode */ +void rtc_configuration_mode_enter(void); +/* exit RTC configuration mode */ +void rtc_configuration_mode_exit(void); +/* set RTC counter value */ +void rtc_counter_set(uint32_t cnt); +/* set RTC prescaler value */ +void rtc_prescaler_set(uint32_t psc); + +/* operation functions */ +/* wait RTC last write operation finished flag set */ +void rtc_lwoff_wait(void); +/* wait RTC registers synchronized flag set */ +void rtc_register_sync_wait(void); +/* set RTC alarm value */ +void rtc_alarm_config(uint32_t alarm); +/* get RTC counter value */ +uint32_t rtc_counter_get(void); +/* get RTC divider value */ +uint32_t rtc_divider_get(void); + +/* flag & interrupt functions */ +/* get RTC flag status */ +FlagStatus rtc_flag_get(uint32_t flag); +/* clear RTC flag status */ +void rtc_flag_clear(uint32_t flag); +/* get RTC interrupt flag status */ +FlagStatus rtc_interrupt_flag_get(uint32_t flag); +/* clear RTC interrupt flag status */ +void rtc_interrupt_flag_clear(uint32_t flag); +/* enable RTC interrupt */ +void rtc_interrupt_enable(uint32_t interrupt); +/* disable RTC interrupt */ +void rtc_interrupt_disable(uint32_t interrupt); + +#endif /* GD32VF103_RTC_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_spi.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..29c81808834386fa5e9b401ccf66cb594378865a --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_spi.h @@ -0,0 +1,341 @@ +/*! + \file gd32vf103_spi.h + \brief definitions for the SPI + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF10X_SPI_H +#define GD32VF10X_SPI_H + +#include "gd32vf103.h" + +/* SPIx(x=0,1,2) definitions */ +#define SPI0 (SPI_BASE + 0x0000F800U) +#define SPI1 SPI_BASE +#define SPI2 (SPI_BASE + 0x00000400U) + +/* SPI registers definitions */ +#define SPI_CTL0(spix) REG32((spix) + 0x00U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x04U) /*!< SPI control register 1*/ +#define SPI_STAT(spix) REG32((spix) + 0x08U) /*!< SPI status register */ +#define SPI_DATA(spix) REG32((spix) + 0x0CU) /*!< SPI data register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x10U) /*!< SPI CRC polynomial register */ +#define SPI_RCRC(spix) REG32((spix) + 0x14U) /*!< SPI receive CRC register */ +#define SPI_TCRC(spix) REG32((spix) + 0x18U) /*!< SPI transmit CRC register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x1CU) /*!< SPI I2S control register */ +#define SPI_I2SPSC(spix) REG32((spix) + 0x20U) /*!< SPI I2S clock prescaler register */ + +/* 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 */ + +/* 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 software */ +#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 */ + +/* I2S audio sample rate */ +#define I2S_AUDIOSAMPLE_8K ((uint32_t)8000U) /*!< I2S audio sample rate is 8KHz */ +#define I2S_AUDIOSAMPLE_11K ((uint32_t)11025U) /*!< I2S audio sample rate is 11KHz */ +#define I2S_AUDIOSAMPLE_16K ((uint32_t)16000U) /*!< I2S audio sample rate is 16KHz */ +#define I2S_AUDIOSAMPLE_22K ((uint32_t)22050U) /*!< I2S audio sample rate is 22KHz */ +#define I2S_AUDIOSAMPLE_32K ((uint32_t)32000U) /*!< I2S audio sample rate is 32KHz */ +#define I2S_AUDIOSAMPLE_44K ((uint32_t)44100U) /*!< I2S audio sample rate is 44KHz */ +#define I2S_AUDIOSAMPLE_48K ((uint32_t)48000U) /*!< I2S audio sample rate is 48KHz */ +#define I2S_AUDIOSAMPLE_96K ((uint32_t)96000U) /*!< I2S audio sample rate is 96KHz */ +#define I2S_AUDIOSAMPLE_192K ((uint32_t)192000U) /*!< I2S audio sample rate is 192KHz */ + +/* I2S frame format */ +#define I2SCTL_DTLEN(regval) (BITS(1,2) & ((uint32_t)(regval) << 1)) +#define I2S_FRAMEFORMAT_DT16B_CH16B I2SCTL_DTLEN(0) /*!< I2S data length is 16 bit and channel length is 16 bit */ +#define I2S_FRAMEFORMAT_DT16B_CH32B (I2SCTL_DTLEN(0) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 16 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT24B_CH32B (I2SCTL_DTLEN(1) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 24 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT32B_CH32B (I2SCTL_DTLEN(2) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 32 bit and channel length is 32 bit */ + +/* I2S master clock output */ +#define I2S_MCKOUT_DISABLE ((uint32_t)0x00000000U) /*!< I2S master clock output disable */ +#define I2S_MCKOUT_ENABLE SPI_I2SPSC_MCKOEN /*!< I2S master clock output enable */ + +/* I2S operation mode */ +#define I2SCTL_I2SOPMOD(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define I2S_MODE_SLAVETX I2SCTL_I2SOPMOD(0) /*!< I2S slave transmit mode */ +#define I2S_MODE_SLAVERX I2SCTL_I2SOPMOD(1) /*!< I2S slave receive mode */ +#define I2S_MODE_MASTERTX I2SCTL_I2SOPMOD(2) /*!< I2S master transmit mode */ +#define I2S_MODE_MASTERRX I2SCTL_I2SOPMOD(3) /*!< I2S master receive mode */ + +/* I2S standard */ +#define I2SCTL_I2SSTD(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define I2S_STD_PHILLIPS I2SCTL_I2SSTD(0) /*!< I2S phillips standard */ +#define I2S_STD_MSB I2SCTL_I2SSTD(1) /*!< I2S MSB standard */ +#define I2S_STD_LSB I2SCTL_I2SSTD(2) /*!< I2S LSB standard */ +#define I2S_STD_PCMSHORT I2SCTL_I2SSTD(3) /*!< I2S PCM short standard */ +#define I2S_STD_PCMLONG (I2SCTL_I2SSTD(3) | SPI_I2SCTL_PCMSMOD) /*!< I2S PCM long standard */ + +/* I2S clock polarity */ +#define I2S_CKPL_LOW ((uint32_t)0x00000000U) /*!< I2S clock polarity low level */ +#define I2S_CKPL_HIGH SPI_I2SCTL_CKPL /*!< I2S clock polarity high level */ + +/* SPI DMA constants definitions */ +#define SPI_DMA_TRANSMIT ((uint8_t)0x00U) /*!< SPI transmit data use DMA */ +#define SPI_DMA_RECEIVE ((uint8_t)0x01U) /*!< SPI receive data use DMA */ + +/* SPI CRC constants definitions */ +#define SPI_CRC_TX ((uint8_t)0x00U) /*!< SPI transmit CRC value */ +#define SPI_CRC_RX ((uint8_t)0x01U) /*!< SPI receive CRC value */ + +/* SPI/I2S interrupt enable/disable constants definitions */ +#define SPI_I2S_INT_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt */ +#define SPI_I2S_INT_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt */ +#define SPI_I2S_INT_ERR ((uint8_t)0x02U) /*!< error interrupt */ + +/* SPI/I2S interrupt flag constants definitions */ +#define SPI_I2S_INT_FLAG_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt flag */ +#define SPI_I2S_INT_FLAG_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt flag */ +#define SPI_I2S_INT_FLAG_RXORERR ((uint8_t)0x02U) /*!< overrun interrupt flag */ +#define SPI_INT_FLAG_CONFERR ((uint8_t)0x03U) /*!< config error interrupt flag */ +#define SPI_INT_FLAG_CRCERR ((uint8_t)0x04U) /*!< CRC error interrupt flag */ +#define I2S_INT_FLAG_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt flag */ +#define SPI_I2S_INT_FLAG_FERR ((uint8_t)0x06U) /*!< format error interrupt flag */ + +/* SPI/I2S flag definitions */ +#define SPI_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define SPI_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define SPI_FLAG_CRCERR SPI_STAT_CRCERR /*!< CRC error flag */ +#define SPI_FLAG_CONFERR SPI_STAT_CONFERR /*!< mode config error flag */ +#define SPI_FLAG_RXORERR SPI_STAT_RXORERR /*!< receive overrun error flag */ +#define SPI_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define SPI_FLAG_FERR SPI_STAT_FERR /*!< format error interrupt flag */ +#define I2S_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define I2S_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define I2S_FLAG_CH SPI_STAT_I2SCH /*!< channel side flag */ +#define I2S_FLAG_TXURERR SPI_STAT_TXURERR /*!< underrun error flag */ +#define I2S_FLAG_RXORERR SPI_STAT_RXORERR /*!< overrun error flag */ +#define I2S_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define I2S_FLAG_FERR SPI_STAT_FERR /*!< format error interrupt flag */ + +/* function declarations */ +/* SPI/I2S deinitialization and initialization functions */ +/* reset SPI and I2S */ +void spi_i2s_deinit(uint32_t spi_periph); +/* initialize the parameters of SPI struct with the default values */ +void spi_struct_para_init(spi_parameter_struct* spi_struct); +/* initialize SPI parameter */ +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); + +/* initialize I2S parameter */ +void i2s_init(uint32_t spi_periph, uint32_t mode, uint32_t standard, uint32_t ckpl); +/* configure I2S prescaler */ +void i2s_psc_config(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout); +/* enable I2S */ +void i2s_enable(uint32_t spi_periph); +/* disable I2S */ +void i2s_disable(uint32_t spi_periph); + +/* NSS functions */ +/* enable SPI NSS output */ +void spi_nss_output_enable(uint32_t spi_periph); +/* disable SPI NSS output */ +void spi_nss_output_disable(uint32_t spi_periph); +/* SPI NSS pin high level in software mode */ +void spi_nss_internal_high(uint32_t spi_periph); +/* SPI NSS pin low level in software mode */ +void spi_nss_internal_low(uint32_t spi_periph); + +/* DMA communication */ +/* 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); + +/* normal mode communication */ +/* 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); +/* 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 /* GD32VF103_SPI_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_timer.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..e9b475c37c6304e6f180212891e577ba278b74dc --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_timer.h @@ -0,0 +1,722 @@ +/*! + \file gd32vf103_timer.h + \brief definitions for the TIMER + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_TIMER_H +#define GD32VF103_TIMER_H + +#include "gd32vf103.h" + +/* TIMERx(x=0..13) definitions */ +#define TIMER0 (TIMER_BASE + 0x00012C00U) +#define TIMER1 (TIMER_BASE + 0x00000000U) +#define TIMER2 (TIMER_BASE + 0x00000400U) +#define TIMER3 (TIMER_BASE + 0x00000800U) +#define TIMER4 (TIMER_BASE + 0x00000C00U) +#define TIMER5 (TIMER_BASE + 0x00001000U) +#define TIMER6 (TIMER_BASE + 0x00001400U) + +/* registers definitions */ +#define TIMER_CTL0(timerx) REG32((timerx) + 0x00U) /*!< TIMER control register 0 */ +#define TIMER_CTL1(timerx) REG32((timerx) + 0x04U) /*!< TIMER control register 1 */ +#define TIMER_SMCFG(timerx) REG32((timerx) + 0x08U) /*!< TIMER slave mode configuration register */ +#define TIMER_DMAINTEN(timerx) REG32((timerx) + 0x0CU) /*!< TIMER DMA and interrupt enable register */ +#define TIMER_INTF(timerx) REG32((timerx) + 0x10U) /*!< TIMER interrupt flag register */ +#define TIMER_SWEVG(timerx) REG32((timerx) + 0x14U) /*!< TIMER software event generation register */ +#define TIMER_CHCTL0(timerx) REG32((timerx) + 0x18U) /*!< TIMER channel control register 0 */ +#define TIMER_CHCTL1(timerx) REG32((timerx) + 0x1CU) /*!< TIMER channel control register 1 */ +#define TIMER_CHCTL2(timerx) REG32((timerx) + 0x20U) /*!< TIMER channel control register 2 */ +#define TIMER_CNT(timerx) REG32((timerx) + 0x24U) /*!< TIMER counter register */ +#define TIMER_PSC(timerx) REG32((timerx) + 0x28U) /*!< TIMER prescaler register */ +#define TIMER_CAR(timerx) REG32((timerx) + 0x2CU) /*!< TIMER counter auto reload register */ +#define TIMER_CREP(timerx) REG32((timerx) + 0x30U) /*!< TIMER counter repetition register */ +#define TIMER_CH0CV(timerx) REG32((timerx) + 0x34U) /*!< TIMER channel 0 capture/compare value register */ +#define TIMER_CH1CV(timerx) REG32((timerx) + 0x38U) /*!< TIMER channel 1 capture/compare value register */ +#define TIMER_CH2CV(timerx) REG32((timerx) + 0x3CU) /*!< TIMER channel 2 capture/compare value register */ +#define TIMER_CH3CV(timerx) REG32((timerx) + 0x40U) /*!< TIMER channel 3 capture/compare value register */ +#define TIMER_CCHP(timerx) REG32((timerx) + 0x44U) /*!< TIMER channel complementary protection register */ +#define TIMER_DMACFG(timerx) REG32((timerx) + 0x48U) /*!< TIMER DMA configuration register */ +#define TIMER_DMATB(timerx) REG32((timerx) + 0x4CU) /*!< TIMER DMA transfer buffer register */ + +/* 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_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 capture/compare DMA request enable */ +#define TIMER_DMAINTEN_CH1DEN BIT(10) /*!< channel 1 capture/compare DMA request enable */ +#define TIMER_DMAINTEN_CH2DEN BIT(11) /*!< channel 2 capture/compare DMA request enable */ +#define TIMER_DMAINTEN_CH3DEN BIT(12) /*!< channel 3 capture/compare 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 over capture flag */ +#define TIMER_INTF_CH1OF BIT(10) /*!< channel 1 over capture flag */ +#define TIMER_INTF_CH2OF BIT(11) /*!< channel 2 over capture flag */ +#define TIMER_INTF_CH3OF BIT(12) /*!< channel 3 over capture 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 control */ +#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 control */ +#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 control */ +#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 control */ +#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 */ + +/* TIMER_CNT */ +#define TIMER_CNT_CNT BITS(0,15) /*!< 16 bit timer counter */ + +/* TIMER_PSC */ +#define TIMER_PSC_PSC BITS(0,15) /*!< prescaler value of the counter clock */ + +/* TIMER_CAR */ +#define TIMER_CAR_CARL BITS(0,15) /*!< 16 bit counter auto reload value */ + +/* TIMER_CREP */ +#define TIMER_CREP_CREP BITS(0,7) /*!< counter repetition value */ + +/* TIMER_CH0CV */ +#define TIMER_CH0CV_CH0VAL BITS(0,15) /*!< 16 bit capture/compare value of channel 0 */ + +/* TIMER_CH1CV */ +#define TIMER_CH1CV_CH1VAL BITS(0,15) /*!< 16 bit capture/compare value of channel 1 */ + +/* TIMER_CH2CV */ +#define TIMER_CH2CV_CH2VAL BITS(0,15) /*!< 16 bit capture/compare value of channel 2 */ + +/* TIMER_CH3CV */ +#define TIMER_CH3CV_CH3VAL BITS(0,15) /*!< 16 bit capture/compare value of channel 3 */ + +/* TIMER_CCHP */ +#define TIMER_CCHP_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_CCHP_PROT BITS(8,9) /*!< complementary register protect control */ +#define TIMER_CCHP_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_CCHP_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_CCHP_BRKEN BIT(12) /*!< break enable */ +#define TIMER_CCHP_BRKP BIT(13) /*!< break polarity */ +#define TIMER_CCHP_OAEN BIT(14) /*!< output automatic enable */ +#define TIMER_CCHP_POEN BIT(15) /*!< primary output enable */ + +/* TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA BITS(0,4) /*!< DMA transfer access start address */ +#define TIMER_DMACFG_DMATC BITS(8,12) /*!< DMA transfer count */ + +/* TIMER_DMATB */ +#define TIMER_DMATB_DMATB BITS(0,15) /*!< DMA transfer buffer address */ + +/* constants definitions */ +/* TIMER init parameter struct definitions */ +typedef struct +{ + uint16_t prescaler; /*!< prescaler value */ + uint16_t alignedmode; /*!< aligned mode */ + uint16_t counterdirection; /*!< counter direction */ + uint32_t period; /*!< period value */ + uint16_t clockdivision; /*!< clock division value */ + uint8_t repetitioncounter; /*!< the counter repetition value */ +}timer_parameter_struct; + +/* break parameter struct definitions */ +typedef struct +{ + uint16_t runoffstate; /*!< run mode off-state */ + uint16_t ideloffstate; /*!< idle mode off-state */ + uint16_t deadtime; /*!< dead time */ + uint16_t breakpolarity; /*!< break polarity */ + uint16_t outputautostate; /*!< output automatic enable */ + uint16_t protectmode; /*!< complementary register protect control */ + uint16_t breakstate; /*!< break enable */ +}timer_break_parameter_struct; + +/* channel output parameter struct definitions */ +typedef struct +{ + uint16_t outputstate; /*!< channel output state */ + uint16_t outputnstate; /*!< channel complementary output state */ + uint16_t ocpolarity; /*!< channel output polarity */ + uint16_t ocnpolarity; /*!< channel complementary output polarity */ + uint16_t ocidlestate; /*!< idle state of channel output */ + uint16_t ocnidlestate; /*!< idle state of channel complementary output */ +}timer_oc_parameter_struct; + +/* channel input parameter struct definitions */ +typedef struct +{ + uint16_t icpolarity; /*!< channel input polarity */ + uint16_t icselection; /*!< channel input mode selection */ + uint16_t icprescaler; /*!< channel input capture prescaler */ + uint16_t icfilter; /*!< channel input capture filter control */ +}timer_ic_parameter_struct; + +/* TIMER interrupt enable or disable */ +#define TIMER_INT_UP TIMER_DMAINTEN_UPIE /*!< update interrupt */ +#define TIMER_INT_CH0 TIMER_DMAINTEN_CH0IE /*!< channel 0 interrupt */ +#define TIMER_INT_CH1 TIMER_DMAINTEN_CH1IE /*!< channel 1 interrupt */ +#define TIMER_INT_CH2 TIMER_DMAINTEN_CH2IE /*!< channel 2 interrupt */ +#define TIMER_INT_CH3 TIMER_DMAINTEN_CH3IE /*!< channel 3 interrupt */ +#define TIMER_INT_CMT TIMER_DMAINTEN_CMTIE /*!< channel commutation interrupt flag */ +#define TIMER_INT_TRG TIMER_DMAINTEN_TRGIE /*!< trigger interrupt */ +#define TIMER_INT_BRK TIMER_DMAINTEN_BRKIE /*!< break interrupt */ + +/* TIMER interrupt flag */ +#define TIMER_INT_FLAG_UP TIMER_INT_UP /*!< update interrupt */ +#define TIMER_INT_FLAG_CH0 TIMER_INT_CH0 /*!< channel 0 interrupt */ +#define TIMER_INT_FLAG_CH1 TIMER_INT_CH1 /*!< channel 1 interrupt */ +#define TIMER_INT_FLAG_CH2 TIMER_INT_CH2 /*!< channel 2 interrupt */ +#define TIMER_INT_FLAG_CH3 TIMER_INT_CH3 /*!< channel 3 interrupt */ +#define TIMER_INT_FLAG_CMT TIMER_INT_CMT /*!< channel commutation interrupt flag */ +#define TIMER_INT_FLAG_TRG TIMER_INT_TRG /*!< trigger interrupt */ +#define TIMER_INT_FLAG_BRK TIMER_INT_BRK + +/* 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 control update 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 DMA source enable */ +#define TIMER_DMA_UPD ((uint16_t)TIMER_DMAINTEN_UPDEN) /*!< update DMA enable */ +#define TIMER_DMA_CH0D ((uint16_t)TIMER_DMAINTEN_CH0DEN) /*!< channel 0 DMA enable */ +#define TIMER_DMA_CH1D ((uint16_t)TIMER_DMAINTEN_CH1DEN) /*!< channel 1 DMA enable */ +#define TIMER_DMA_CH2D ((uint16_t)TIMER_DMAINTEN_CH2DEN) /*!< channel 2 DMA enable */ +#define TIMER_DMA_CH3D ((uint16_t)TIMER_DMAINTEN_CH3DEN) /*!< channel 3 DMA enable */ +#define TIMER_DMA_CMTD ((uint16_t)TIMER_DMAINTEN_CMTDEN) /*!< commutation DMA request enable */ +#define TIMER_DMA_TRGD ((uint16_t)TIMER_DMAINTEN_TRGDEN) /*!< trigger DMA enable */ + +/* channel DMA request source selection */ +#define TIMER_DMAREQUEST_UPDATEEVENT TIMER_CTL1_DMAS /*!< DMA request of channel n is sent when update event occurs */ +#define TIMER_DMAREQUEST_CHANNELEVENT ((uint32_t)0x00000000U) /*!< DMA request of channel n is sent when channel n event occurs */ + +/* DMA access base address */ +#define DMACFG_DMATA(regval) (BITS(0, 4) & ((uint32_t)(regval) << 0U)) +#define TIMER_DMACFG_DMATA_CTL0 DMACFG_DMATA(0) /*!< DMA transfer address is TIMER_CTL0 */ +#define TIMER_DMACFG_DMATA_CTL1 DMACFG_DMATA(1) /*!< DMA transfer address is TIMER_CTL1 */ +#define TIMER_DMACFG_DMATA_SMCFG DMACFG_DMATA(2) /*!< DMA transfer address is TIMER_SMCFG */ +#define TIMER_DMACFG_DMATA_DMAINTEN DMACFG_DMATA(3) /*!< DMA transfer address is TIMER_DMAINTEN */ +#define TIMER_DMACFG_DMATA_INTF DMACFG_DMATA(4) /*!< DMA transfer address is TIMER_INTF */ +#define TIMER_DMACFG_DMATA_SWEVG DMACFG_DMATA(5) /*!< DMA transfer address is TIMER_SWEVG */ +#define TIMER_DMACFG_DMATA_CHCTL0 DMACFG_DMATA(6) /*!< DMA transfer address is TIMER_CHCTL0 */ +#define TIMER_DMACFG_DMATA_CHCTL1 DMACFG_DMATA(7) /*!< DMA transfer address is TIMER_CHCTL1 */ +#define TIMER_DMACFG_DMATA_CHCTL2 DMACFG_DMATA(8) /*!< DMA transfer address is TIMER_CHCTL2 */ +#define TIMER_DMACFG_DMATA_CNT DMACFG_DMATA(9) /*!< DMA transfer address is TIMER_CNT */ +#define TIMER_DMACFG_DMATA_PSC DMACFG_DMATA(10) /*!< DMA transfer address is TIMER_PSC */ +#define TIMER_DMACFG_DMATA_CAR DMACFG_DMATA(11) /*!< DMA transfer address is TIMER_CAR */ +#define TIMER_DMACFG_DMATA_CREP DMACFG_DMATA(12) /*!< DMA transfer address is TIMER_CREP */ +#define TIMER_DMACFG_DMATA_CH0CV DMACFG_DMATA(13) /*!< DMA transfer address is TIMER_CH0CV */ +#define TIMER_DMACFG_DMATA_CH1CV DMACFG_DMATA(14) /*!< DMA transfer address is TIMER_CH1CV */ +#define TIMER_DMACFG_DMATA_CH2CV DMACFG_DMATA(15) /*!< DMA transfer address is TIMER_CH2CV */ +#define TIMER_DMACFG_DMATA_CH3CV DMACFG_DMATA(16) /*!< DMA transfer address is TIMER_CH3CV */ +#define TIMER_DMACFG_DMATA_CCHP DMACFG_DMATA(17) /*!< DMA transfer address is TIMER_CCHP */ +#define TIMER_DMACFG_DMATA_DMACFG DMACFG_DMATA(18) /*!< DMA transfer address is TIMER_DMACFG */ + +/* DMA access burst length */ +#define DMACFG_DMATC(regval) (BITS(8, 12) & ((uint32_t)(regval) << 8U)) +#define TIMER_DMACFG_DMATC_1TRANSFER DMACFG_DMATC(0) /*!< DMA transfer 1 time */ +#define TIMER_DMACFG_DMATC_2TRANSFER DMACFG_DMATC(1) /*!< DMA transfer 2 times */ +#define TIMER_DMACFG_DMATC_3TRANSFER DMACFG_DMATC(2) /*!< DMA transfer 3 times */ +#define TIMER_DMACFG_DMATC_4TRANSFER DMACFG_DMATC(3) /*!< DMA transfer 4 times */ +#define TIMER_DMACFG_DMATC_5TRANSFER DMACFG_DMATC(4) /*!< DMA transfer 5 times */ +#define TIMER_DMACFG_DMATC_6TRANSFER DMACFG_DMATC(5) /*!< DMA transfer 6 times */ +#define TIMER_DMACFG_DMATC_7TRANSFER DMACFG_DMATC(6) /*!< DMA transfer 7 times */ +#define TIMER_DMACFG_DMATC_8TRANSFER DMACFG_DMATC(7) /*!< DMA transfer 8 times */ +#define TIMER_DMACFG_DMATC_9TRANSFER DMACFG_DMATC(8) /*!< DMA transfer 9 times */ +#define TIMER_DMACFG_DMATC_10TRANSFER DMACFG_DMATC(9) /*!< DMA transfer 10 times */ +#define TIMER_DMACFG_DMATC_11TRANSFER DMACFG_DMATC(10) /*!< DMA transfer 11 times */ +#define TIMER_DMACFG_DMATC_12TRANSFER DMACFG_DMATC(11) /*!< DMA transfer 12 times */ +#define TIMER_DMACFG_DMATC_13TRANSFER DMACFG_DMATC(12) /*!< DMA transfer 13 times */ +#define TIMER_DMACFG_DMATC_14TRANSFER DMACFG_DMATC(13) /*!< DMA transfer 14 times */ +#define TIMER_DMACFG_DMATC_15TRANSFER DMACFG_DMATC(14) /*!< DMA transfer 15 times */ +#define TIMER_DMACFG_DMATC_16TRANSFER DMACFG_DMATC(15) /*!< DMA transfer 16 times */ +#define TIMER_DMACFG_DMATC_17TRANSFER DMACFG_DMATC(16) /*!< DMA transfer 17 times */ +#define TIMER_DMACFG_DMATC_18TRANSFER DMACFG_DMATC(17) /*!< DMA transfer 18 times */ + +/* TIMER software event generation source */ +#define TIMER_EVENT_SRC_UPG ((uint16_t)0x0001U) /*!< update event generation */ +#define TIMER_EVENT_SRC_CH0G ((uint16_t)0x0002U) /*!< channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH1G ((uint16_t)0x0004U) /*!< channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH2G ((uint16_t)0x0008U) /*!< channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH3G ((uint16_t)0x0010U) /*!< channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CMTG ((uint16_t)0x0020U) /*!< channel commutation event generation */ +#define TIMER_EVENT_SRC_TRGG ((uint16_t)0x0040U) /*!< trigger event generation */ +#define TIMER_EVENT_SRC_BRKG ((uint16_t)0x0080U) /*!< break event generation */ + +/* center-aligned mode selection */ +#define CTL0_CAM(regval) ((uint16_t)(BITS(5, 6) & ((uint32_t)(regval) << 5U))) +#define TIMER_COUNTER_EDGE CTL0_CAM(0) /*!< edge-aligned mode */ +#define TIMER_COUNTER_CENTER_DOWN CTL0_CAM(1) /*!< center-aligned and counting down assert mode */ +#define TIMER_COUNTER_CENTER_UP CTL0_CAM(2) /*!< center-aligned and counting up assert mode */ +#define TIMER_COUNTER_CENTER_BOTH CTL0_CAM(3) /*!< center-aligned and counting up/down assert mode */ + +/* TIMER prescaler reload mode */ +#define TIMER_PSC_RELOAD_NOW TIMER_SWEVG_UPG /*!< the prescaler is loaded right now */ +#define TIMER_PSC_RELOAD_UPDATE ((uint32_t)0x00000000U) /*!< the prescaler is loaded at the next update event */ + +/* count direction */ +#define TIMER_COUNTER_UP ((uint16_t)0x0000U) /*!< counter up direction */ +#define TIMER_COUNTER_DOWN ((uint16_t)TIMER_CTL0_DIR) /*!< counter down direction */ + +/* specify division ratio between TIMER clock and dead-time and sampling clock */ +#define CTL0_CKDIV(regval) ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CKDIV_DIV1 CTL0_CKDIV(0) /*!< clock division value is 1,fDTS=fTIMER_CK */ +#define TIMER_CKDIV_DIV2 CTL0_CKDIV(1) /*!< clock division value is 2,fDTS= fTIMER_CK/2 */ +#define TIMER_CKDIV_DIV4 CTL0_CKDIV(2) /*!< clock division value is 4, fDTS= fTIMER_CK/4 */ + +/* single pulse mode */ +#define TIMER_SP_MODE_SINGLE TIMER_CTL0_SPM /*!< single pulse mode */ +#define TIMER_SP_MODE_REPETITIVE ((uint32_t)0x00000000U) /*!< repetitive pulse mode */ + +/* update source */ +#define TIMER_UPDATE_SRC_REGULAR TIMER_CTL0_UPS /*!< update generate only by counter overflow/underflow */ +#define TIMER_UPDATE_SRC_GLOBAL ((uint32_t)0x00000000U) /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */ + +/* run mode off-state configure */ +#define TIMER_ROS_STATE_ENABLE ((uint16_t)TIMER_CCHP_ROS) /*!< when POEN bit is set, the channel output signals(CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_ROS_STATE_DISABLE ((uint16_t)0x0000U) /*!< when POEN bit is set, the channel output signals(CHx_O/CHx_ON) are disabled */ + + +/* idle mode off-state configure */ +#define TIMER_IOS_STATE_ENABLE ((uint16_t)TIMER_CCHP_IOS) /*!< when POEN bit is reset, he channel output signals(CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_IOS_STATE_DISABLE ((uint16_t)0x0000U) /*!< when POEN bit is reset, the channel output signals(CHx_O/CHx_ON) are disabled */ + +/* break input polarity */ +#define TIMER_BREAK_POLARITY_LOW ((uint16_t)0x0000U) /*!< break input polarity is low */ +#define TIMER_BREAK_POLARITY_HIGH ((uint16_t)TIMER_CCHP_BRKP) /*!< break input polarity is high */ + +/* output automatic enable */ +#define TIMER_OUTAUTO_ENABLE ((uint16_t)TIMER_CCHP_OAEN) /*!< output automatic enable */ +#define TIMER_OUTAUTO_DISABLE ((uint16_t)0x0000U) /*!< output automatic disable */ + +/* complementary register protect control */ +#define CCHP_PROT(regval) ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CCHP_PROT_OFF CCHP_PROT(0) /*!< protect disable */ +#define TIMER_CCHP_PROT_0 CCHP_PROT(1) /*!< PROT mode 0 */ +#define TIMER_CCHP_PROT_1 CCHP_PROT(2) /*!< PROT mode 1 */ +#define TIMER_CCHP_PROT_2 CCHP_PROT(3) /*!< PROT mode 2 */ + +/* break input enable */ +#define TIMER_BREAK_ENABLE ((uint16_t)TIMER_CCHP_BRKEN) /*!< break input enable */ +#define TIMER_BREAK_DISABLE ((uint16_t)0x0000U) /*!< break input disable */ + +/* TIMER channel n(n=0,1,2,3) */ +#define TIMER_CH_0 ((uint16_t)0x0000U) /*!< TIMER channel 0(TIMERx(x=0..4)) */ +#define TIMER_CH_1 ((uint16_t)0x0001U) /*!< TIMER channel 1(TIMERx(x=0..4)) */ +#define TIMER_CH_2 ((uint16_t)0x0002U) /*!< TIMER channel 2(TIMERx(x=0..4)) */ +#define TIMER_CH_3 ((uint16_t)0x0003U) /*!< TIMER channel 3(TIMERx(x=0..4)) */ + +/* channel enable state */ +#define TIMER_CCX_ENABLE ((uint16_t)0x0001U) /*!< channel enable */ +#define TIMER_CCX_DISABLE ((uint16_t)0x0000U) /*!< channel disable */ + +/* channel complementary output enable state */ +#define TIMER_CCXN_ENABLE ((uint16_t)0x0004U) /*!< channel complementary enable */ +#define TIMER_CCXN_DISABLE ((uint16_t)0x0000U) /*!< channel complementary disable */ + +/* channel output polarity */ +#define TIMER_OC_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel output polarity is high */ +#define TIMER_OC_POLARITY_LOW ((uint16_t)0x0002U) /*!< channel output polarity is low */ + +/* channel complementary output polarity */ +#define TIMER_OCN_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel complementary output polarity is high */ +#define TIMER_OCN_POLARITY_LOW ((uint16_t)0x0008U) /*!< channel complementary output polarity is low */ + +/* idle state of channel output */ +#define TIMER_OC_IDLE_STATE_HIGH ((uint16_t)0x0100) /*!< idle state of channel output is high */ +#define TIMER_OC_IDLE_STATE_LOW ((uint16_t)0x0000) /*!< idle state of channel output is low */ + +/* idle state of channel complementary output */ +#define TIMER_OCN_IDLE_STATE_HIGH ((uint16_t)0x0200U) /*!< idle state of channel complementary output is high */ +#define TIMER_OCN_IDLE_STATE_LOW ((uint16_t)0x0000U) /*!< idle state of channel complementary output is low */ + +/* channel output compare mode */ +#define TIMER_OC_MODE_TIMING ((uint16_t)0x0000U) /*!< timing mode */ +#define TIMER_OC_MODE_ACTIVE ((uint16_t)0x0010U) /*!< active mode */ +#define TIMER_OC_MODE_INACTIVE ((uint16_t)0x0020U) /*!< inactive mode */ +#define TIMER_OC_MODE_TOGGLE ((uint16_t)0x0030U) /*!< toggle mode */ +#define TIMER_OC_MODE_LOW ((uint16_t)0x0040U) /*!< force low mode */ +#define TIMER_OC_MODE_HIGH ((uint16_t)0x0050U) /*!< force high mode */ +#define TIMER_OC_MODE_PWM0 ((uint16_t)0x0060U) /*!< PWM0 mode */ +#define TIMER_OC_MODE_PWM1 ((uint16_t)0x0070U) /*!< PWM1 mode */ + +/* channel output compare shadow enable */ +#define TIMER_OC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< channel output shadow state enable */ +#define TIMER_OC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel output shadow state disable */ + +/* channel output compare fast enable */ +#define TIMER_OC_FAST_ENABLE ((uint16_t)0x0004) /*!< channel output fast function enable */ +#define TIMER_OC_FAST_DISABLE ((uint16_t)0x0000) /*!< channel output fast function disable */ + +/* channel output compare clear enable */ +#define TIMER_OC_CLEAR_ENABLE ((uint16_t)0x0080U) /*!< channel output clear function enable */ +#define TIMER_OC_CLEAR_DISABLE ((uint16_t)0x0000U) /*!< channel output clear function disable */ + +/* channel control shadow register update control */ +#define TIMER_UPDATECTL_CCU ((uint32_t)0x00000000U) /*!< the shadow registers update by when CMTG bit is set */ +#define TIMER_UPDATECTL_CCUTRI TIMER_CTL1_CCUC /*!< 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 n is configured as input and icy is mapped on CIy */ +#define TIMER_IC_SELECTION_INDIRECTTI ((uint16_t)0x0002U) /*!< channel n is configured as input and icy is mapped on opposite input */ +#define TIMER_IC_SELECTION_ITS ((uint16_t)0x0003U) /*!< channel n 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) /*!< filtered external trigger input */ + +/* 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 channel 0 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 */ + +/* master slave mode selection */ +#define TIMER_MASTER_SLAVE_MODE_ENABLE TIMER_SMCFG_MSM /*!< master slave mode enable */ +#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint32_t)0x00000000U) /*!< master slave mode disable */ + +/* external trigger prescaler */ +#define SMCFG_ETPSC(regval) (BITS(12, 13) & ((uint32_t)(regval) << 12U)) +#define TIMER_EXT_TRI_PSC_OFF SMCFG_ETPSC(0) /*!< no divided */ +#define TIMER_EXT_TRI_PSC_DIV2 SMCFG_ETPSC(1) /*!< divided by 2 */ +#define TIMER_EXT_TRI_PSC_DIV4 SMCFG_ETPSC(2) /*!< divided by 4 */ +#define TIMER_EXT_TRI_PSC_DIV8 SMCFG_ETPSC(3) /*!< divided by 8 */ + +/* external trigger polarity */ +#define TIMER_ETP_FALLING TIMER_SMCFG_ETP /*!< active low or falling edge active */ +#define TIMER_ETP_RISING ((uint32_t)0x00000000U) /*!< active high or rising edge active */ + +/* channel 0 trigger input selection */ +#define TIMER_HALLINTERFACE_ENABLE TIMER_CTL1_TI0S /*!< TIMER hall sensor mode enable */ +#define TIMER_HALLINTERFACE_DISABLE ((uint32_t)0x00000000U) /*!< TIMER hall sensor mode disable */ + +/* TIMERx(x=0..4) write CHxVAL register selection */ +#define TIMER_CHVSEL_ENABLE ((uint16_t)TIMER_CFG_OUTSEL) /*!< write CHxVAL register selection enable */ +#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CHxVAL register selection disable */ + +/* 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, uint32_t pscreload); +/* configure TIMER repetition register value */ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition); +/* configure TIMER autoreload register value */ +void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload); +/* configure TIMER counter register value */ +void timer_counter_value_config(uint32_t timer_periph, uint16_t counter); +/* read TIMER counter value */ +uint32_t timer_counter_read(uint32_t timer_periph); +/* read TIMER prescaler value */ +uint16_t timer_prescaler_read(uint32_t timer_periph); +/* configure TIMER single pulse mode */ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode); +/* configure TIMER update source */ +void timer_update_source_config(uint32_t timer_periph, uint32_t update); + +/* 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, uint32_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, uint32_t ccuctl); + +/* TIMER channel output */ +/* initialize TIMER channel output parameter struct */ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara); +/* configure TIMER channel output function */ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct* ocpara); +/* configure TIMER channel output compare mode */ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode); +/* configure TIMER channel output pulse value */ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse); +/* configure TIMER channel output shadow function */ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow); +/* configure TIMER channel output fast function */ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast); +/* configure TIMER channel output clear function */ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear); +/* configure TIMER channel output polarity */ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity); +/* configure TIMER channel complementary output polarity */ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity); +/* configure TIMER channel enable state */ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state); +/* configure TIMER channel complementary output enable state */ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate); + +/* TIMER channel input */ +/* initialize TIMER channel input parameter struct */ +void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara); +/* configure TIMER input capture parameter */ +void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpara); +/* configure TIMER channel input capture prescaler value */ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler); +/* read TIMER channel capture compare register value */ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel); +/* configure TIMER input pwm capture function */ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm); +/* configure TIMER hall sensor mode */ +void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode); + +/* TIMER master and slave mode */ +/* select TIMER input trigger source */ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger); +/* select TIMER master mode output trigger source */ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger); +/* select TIMER slave mode */ +void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode); +/* configure TIMER master slave mode */ +void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave); +/* configure TIMER external trigger input */ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* configure TIMER quadrature decoder mode */ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity); +/* configure TIMER internal clock mode */ +void timer_internal_clock_config(uint32_t timer_periph); +/* configure TIMER the internal trigger as external clock input */ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger); +/* configure TIMER the external trigger as external clock input */ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity, uint32_t extfilter); +/* configure TIMER the external clock mode 0 */ +void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* configure TIMER the external clock mode 1 */ +void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* disable TIMER the external clock mode 1 */ +void timer_external_clock_mode1_disable(uint32_t timer_periph); + +/* 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 flag */ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag); +/* clear TIMER flag */ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag); + +#endif /* GD32VF103_TIMER_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_usart.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_usart.h new file mode 100644 index 0000000000000000000000000000000000000000..5caf7d81f593070e937ee9286be13fe360afd81e --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_usart.h @@ -0,0 +1,374 @@ +/*! + \file gd32vf103_usart.h + \brief definitions for the USART + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + Copyright (c) 2018, 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 GD32VF103_USART_H +#define GD32VF103_USART_H + +#include "gd32vf103.h" + +/* USARTx(x=0,1,2)/UARTx(x=3,4) definitions */ +#define USART1 USART_BASE /*!< USART1 base address */ +#define USART2 (USART_BASE+(0x00000400U)) /*!< USART2 base address */ +#define UART3 (USART_BASE+(0x00000800U)) /*!< UART3 base address */ +#define UART4 (USART_BASE+(0x00000C00U)) /*!< UART4 base address */ +#define USART0 (USART_BASE+(0x0000F400U)) /*!< USART0 base address */ + +/* registers definitions */ +#define USART_STAT(usartx) REG32((usartx) + (0x00000000U)) /*!< USART status register */ +#define USART_DATA(usartx) REG32((usartx) + (0x00000004U)) /*!< USART data register */ +#define USART_BAUD(usartx) REG32((usartx) + (0x00000008U)) /*!< USART baud rate register */ +#define USART_CTL0(usartx) REG32((usartx) + (0x0000000CU)) /*!< USART control register 0 */ +#define USART_CTL1(usartx) REG32((usartx) + (0x00000010U)) /*!< USART control register 1 */ +#define USART_CTL2(usartx) REG32((usartx) + (0x00000014U)) /*!< USART control register 2 */ +#define USART_GP(usartx) REG32((usartx) + (0x00000018U)) /*!< USART guard time and prescaler register */ + +/* bits definitions */ +/* 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 frame detected flag */ +#define USART_STAT_RBNE BIT(5) /*!< read data buffer not empty */ +#define USART_STAT_TC BIT(6) /*!< transmission complete */ +#define USART_STAT_TBE BIT(7) /*!< transmit data buffer empty */ +#define USART_STAT_LBDF BIT(8) /*!< LIN break detected flag */ +#define USART_STAT_CTSF BIT(9) /*!< CTS change flag */ + +/* USARTx_DATA */ +#define USART_DATA_DATA BITS(0,8) /*!< transmit or read data value */ + +/* USARTx_BAUD */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction part of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer part of baud-rate divider */ + +/* USARTx_CTL0 */ +#define USART_CTL0_SBKCMD BIT(0) /*!< send break command */ +#define USART_CTL0_RWU BIT(1) /*!< receiver wakeup from mute 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 buffer 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 check function enable */ +#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL BIT(12) /*!< word length */ +#define USART_CTL0_UEN BIT(13) /*!< USART enable */ + +/* USARTx_CTL1 */ +#define USART_CTL1_ADDR BITS(0,3) /*!< address of USART */ +#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ +#define USART_CTL1_LBDIE BIT(6) /*!< LIN break detected interrupt eanble */ +#define USART_CTL1_CLEN BIT(8) /*!< CK length */ +#define USART_CTL1_CPH BIT(9) /*!< CK phase */ +#define USART_CTL1_CPL BIT(10) /*!< CK 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 */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< error interrupt enable */ +#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 request enable for reception */ +#define USART_CTL2_DENT BIT(7) /*!< DMA request 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 */ + +/* 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 */ + +/* 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_STAT_REG_OFFSET (0x00000000U) /*!< STAT register offset */ +#define USART_CTL0_REG_OFFSET (0x0000000CU) /*!< CTL0 register offset */ +#define USART_CTL1_REG_OFFSET (0x00000010U) /*!< CTL1 register offset */ +#define USART_CTL2_REG_OFFSET (0x00000014U) /*!< CTL2 register offset */ + +/* USART flags */ +typedef enum +{ + /* flags in STAT register */ + USART_FLAG_CTSF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 9U), /*!< CTS change flag */ + USART_FLAG_LBDF = 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_IDLEF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 4U), /*!< IDLE frame 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 */ +}usart_flag_enum; + +/* USART interrupt flags */ +typedef enum +{ + /* interrupt flags in CTL0 register */ + USART_INT_FLAG_PERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 8U, USART_STAT_REG_OFFSET, 0U), /*!< parity error interrupt and flag */ + USART_INT_FLAG_TBE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt and flag */ + USART_INT_FLAG_TC = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 6U), /*!< transmission complete interrupt and flag */ + USART_INT_FLAG_RBNE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and flag */ + USART_INT_FLAG_RBNE_ORERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 3U), /*!< read data buffer not empty interrupt and overrun error flag */ + USART_INT_FLAG_IDLE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 4U, USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected interrupt and flag */ + /* interrupt flags in CTL1 register */ + USART_INT_FLAG_LBD = USART_REGIDX_BIT2(USART_CTL1_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected interrupt and flag */ + /* interrupt flags in CTL2 register */ + USART_INT_FLAG_CTS = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 10U, USART_STAT_REG_OFFSET, 9U), /*!< CTS interrupt and flag */ + USART_INT_FLAG_ERR_ORERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 3U), /*!< error interrupt and overrun error */ + USART_INT_FLAG_ERR_NERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 2U), /*!< error interrupt and noise error flag */ + USART_INT_FLAG_ERR_FERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 1U), /*!< error interrupt and frame error flag */ +}usart_interrupt_flag_enum; + +/* USART interrupt enable or disable */ +typedef enum +{ + /* interrupt in CTL0 register */ + 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_CTS = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 10U), /*!< CTS interrupt */ + USART_INT_ERR = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 0U), /*!< error interrupt */ +}usart_interrupt_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 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 LIN break frame length */ +#define CTL1_LBLEN(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define USART_LBLEN_10B CTL1_LBLEN(0) /*!< 10 bits */ +#define USART_LBLEN_11B CTL1_LBLEN(1) /*!< 11 bits */ + +/* USART CK length */ +#define CTL1_CLEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_CLEN_NONE CTL1_CLEN(0) /*!< there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame */ +#define USART_CLEN_EN CTL1_CLEN(1) /*!< there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame */ + +/* 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 DMA request for receive configure */ +#define CLT2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define USART_DENR_ENABLE CLT2_DENR(1) /*!< DMA request enable for reception */ +#define USART_DENR_DISABLE CLT2_DENR(0) /*!< DMA request disable for reception */ + +/* USART DMA request for transmission configure */ +#define CLT2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_DENT_ENABLE CLT2_DENT(1) /*!< DMA request enable for transmission */ +#define USART_DENT_DISABLE CLT2_DENT(0) /*!< DMA request disable for transmission */ + +/* USART RTS configure */ +#define CLT2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CLT2_RTSEN(1) /*!< RTS enable */ +#define USART_RTS_DISABLE CLT2_RTSEN(0) /*!< RTS disable */ + +/* USART CTS configure */ +#define CLT2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CLT2_CTSEN(1) /*!< CTS enable */ +#define USART_CTS_DISABLE CLT2_CTSEN(0) /*!< CTS disable */ + +/* 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 */ + +/* 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); + +/* USART normal mode communication */ +/* 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 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); + +/* multi-processor communication */ +/* configure address of the USART */ +void usart_address_config(uint32_t usart_periph, uint8_t addr); +/* 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 */ +/* LIN mode enable */ +void usart_lin_mode_enable(uint32_t usart_periph); +/* LIN mode disable */ +void usart_lin_mode_disable(uint32_t usart_periph); +/* LIN break detection length */ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen); +/* send break frame */ +void usart_send_break(uint32_t usart_periph); + +/* half-duplex communication */ +/* half-duplex enable */ +void usart_halfduplex_enable(uint32_t usart_periph); +/* half-duplex disable */ +void usart_halfduplex_disable(uint32_t usart_periph); + +/* synchronous communication */ +/* clock enable */ +void usart_synchronous_clock_enable(uint32_t usart_periph); +/* clock disable */ +void usart_synchronous_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 */ +/* guard time value configure in smartcard mode */ +void usart_guard_time_config(uint32_t usart_periph, uint32_t gaut); +/* smartcard mode enable */ +void usart_smartcard_mode_enable(uint32_t usart_periph); +/* smartcard mode disable */ +void usart_smartcard_mode_disable(uint32_t usart_periph); +/* NACK enable in smartcard mode */ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph); +/* NACK disable in smartcard mode */ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph); + +/* IrDA communication */ +/* enable IrDA mode */ +void usart_irda_mode_enable(uint32_t usart_periph); +/* disable IrDA mode */ +void usart_irda_mode_disable(uint32_t usart_periph); +/* configure the peripheral clock prescaler */ +void usart_prescaler_config(uint32_t usart_periph, uint8_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); + +/* 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); + +/* flag functions */ +/* get flag in STAT 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); + +/* interrupt functions */ +/* enable USART interrupt */ +void usart_interrupt_enable(uint32_t usart_periph, uint32_t int_flag); +/* disable USART interrupt */ +void usart_interrupt_disable(uint32_t usart_periph, uint32_t int_flag); +/* get USART interrupt and flag status */ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag); +/* clear interrupt flag in STAT register */ +void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t flag); +#endif /* GD32VF103_USART_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_wwdgt.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_wwdgt.h new file mode 100644 index 0000000000000000000000000000000000000000..b972bba4580ecb54784f9e3cb525f51ff1e1e6fa --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Include/gd32vf103_wwdgt.h @@ -0,0 +1,86 @@ +/*! + \file gd32vf103_wwdgt.h + \brief definitions for the WWDGT + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_WWDGT_H +#define GD32VF103_WWDGT_H + +#include "gd32vf103.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE /*!< WWDGT base address */ + +/* 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) /*!< early wakeup interrupt enable */ + +/* WWDGT_STAT */ +#define WWDGT_STAT_EWIF BIT(0) /*!< early wakeup interrupt flag */ + +/* constants definitions */ +#define CFG_PSC(regval) (BITS(7,8) & ((uint32_t)(regval) << 7)) /*!< write value to WWDGT_CFG_PSC bit field */ +#define WWDGT_CFG_PSC_DIV1 CFG_PSC(0) /*!< the time base of WWDGT = (PCLK1/4096)/1 */ +#define WWDGT_CFG_PSC_DIV2 CFG_PSC(1) /*!< the time base of WWDGT = (PCLK1/4096)/2 */ +#define WWDGT_CFG_PSC_DIV4 CFG_PSC(2) /*!< the time base of WWDGT = (PCLK1/4096)/4 */ +#define WWDGT_CFG_PSC_DIV8 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 /* GD32VF103_WWDGT_H */ diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_adc.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..8a48676bc4ce117080d7d3107869110c098f570a --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_adc.c @@ -0,0 +1,992 @@ +/*! + \file gd32vf103_adc.c + \brief ADC driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_adc.h" + +/* discontinuous mode macro*/ +#define ADC_CHANNEL_LENGTH_SUBTRACT_ONE ((uint8_t)1U) + +/* ADC regular channel macro */ +#define ADC_REGULAR_CHANNEL_RANK_SIX ((uint8_t)6U) +#define ADC_REGULAR_CHANNEL_RANK_TWELVE ((uint8_t)12U) +#define ADC_REGULAR_CHANNEL_RANK_SIXTEEN ((uint8_t)16U) +#define ADC_REGULAR_CHANNEL_RANK_LENGTH ((uint8_t)5U) + +/* ADC sampling time macro */ +#define ADC_CHANNEL_SAMPLE_TEN ((uint8_t)10U) +#define ADC_CHANNEL_SAMPLE_EIGHTEEN ((uint8_t)18U) +#define ADC_CHANNEL_SAMPLE_LENGTH ((uint8_t)3U) + +/* ADC inserted channel macro */ +#define ADC_INSERTED_CHANNEL_RANK_LENGTH ((uint8_t)5U) +#define ADC_INSERTED_CHANNEL_SHIFT_LENGTH ((uint8_t)15U) + +/* ADC inserted channel offset macro */ +#define ADC_OFFSET_LENGTH ((uint8_t)3U) +#define ADC_OFFSET_SHIFT_LENGTH ((uint8_t)4U) + +/*! + \brief reset ADC + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_deinit(uint32_t adc_periph) +{ + switch(adc_periph){ + case ADC0: + /* reset ADC0 */ + rcu_periph_reset_enable(RCU_ADC0RST); + rcu_periph_reset_disable(RCU_ADC0RST); + break; + case ADC1: + /* reset ADC1 */ + rcu_periph_reset_enable(RCU_ADC1RST); + rcu_periph_reset_disable(RCU_ADC1RST); + break; + default: + break; + } +} + +/*! + \brief configure the ADC sync mode + \param[in] mode: ADC mode + only one parameter can be selected which is shown as below: + \arg ADC_MODE_FREE: all the ADCs work independently + \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined regular parallel + inserted parallel mode + \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined regular parallel + trigger rotation mode + \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode + \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode + \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode only + \arg ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode only + \arg ADC_DAUL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in follow-up fast mode only + \arg ADC_DAUL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in follow-up slow mode only + \arg ADC_DAUL_INSERTED_TRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode only + \param[out] none + \retval none +*/ +void adc_mode_config(uint32_t mode) +{ + ADC_CTL0(ADC0) &= ~(ADC_CTL0_SYNCM); + ADC_CTL0(ADC0) |= mode; +} + +/*! + \brief enable or disable ADC special function + \param[in] adc_periph: ADCx, x=0,1 + \param[in] function: the function to config + only one parameter 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 adc_periph, uint32_t function, ControlStatus newvalue) +{ + if(newvalue){ + if(0U != (function & ADC_SCAN_MODE)){ + /* enable scan mode */ + ADC_CTL0(adc_periph) |= ADC_SCAN_MODE; + } + if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)){ + /* enable inserted channel group convert automatically */ + ADC_CTL0(adc_periph) |= ADC_INSERTED_CHANNEL_AUTO; + } + if(0U != (function & ADC_CONTINUOUS_MODE)){ + /* enable continuous mode */ + ADC_CTL1(adc_periph) |= ADC_CONTINUOUS_MODE; + } + }else{ + if(0U != (function & ADC_SCAN_MODE)){ + /* disable scan mode */ + ADC_CTL0(adc_periph) &= ~ADC_SCAN_MODE; + } + if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)){ + /* disable inserted channel group convert automatically */ + ADC_CTL0(adc_periph) &= ~ADC_INSERTED_CHANNEL_AUTO; + } + if(0U != (function & ADC_CONTINUOUS_MODE)){ + /* disable continuous mode */ + ADC_CTL1(adc_periph) &= ~ADC_CONTINUOUS_MODE; + } + } +} + +/*! + \brief configure ADC data alignment + \param[in] adc_periph: ADCx, x=0,1 + \param[in] data_alignment: data alignment select + only one parameter can be selected which is shown as below: + \arg ADC_DATAALIGN_RIGHT: LSB alignment + \arg ADC_DATAALIGN_LEFT: MSB alignment + \param[out] none + \retval none +*/ +void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment) +{ + if(ADC_DATAALIGN_RIGHT != data_alignment){ + /* MSB alignment */ + ADC_CTL1(adc_periph) |= ADC_CTL1_DAL; + }else{ + /* LSB alignment */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL); + } +} + +/*! + \brief enable ADC interface + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_enable(uint32_t adc_periph) +{ + if(RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)){ + /* enable ADC */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON; + } +} + +/*! + \brief disable ADC interface + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_disable(uint32_t adc_periph) +{ + /* disable ADC */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ADCON); +} + +/*! + \brief ADC calibration and reset calibration + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_calibration_enable(uint32_t adc_periph) +{ + /* reset the selected ADC1 calibration registers */ + ADC_CTL1(adc_periph) |= (uint32_t) ADC_CTL1_RSTCLB; + /* check the RSTCLB bit state */ + while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)){ + } + /* enable ADC calibration process */ + ADC_CTL1(adc_periph) |= ADC_CTL1_CLB; + /* check the CLB bit state */ + while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)){ + } +} + +/*! + \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(ADC0) |= 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(ADC0) &= ~ADC_CTL1_TSVREN; +} + +/*! + \brief enable DMA request + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_dma_mode_enable(uint32_t adc_periph) +{ + /* enable DMA request */ + ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DMA); +} + +/*! + \brief disable DMA request + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_dma_mode_disable(uint32_t adc_periph) +{ + /* disable DMA request */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DMA); +} + +/*! + \brief configure ADC discontinuous mode + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_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 & 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(uint32_t adc_periph, uint8_t adc_channel_group, uint8_t length) +{ + /* disable discontinuous mode of regular & inserted channel */ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC)); + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* config the number of conversions in discontinuous mode */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM); + ADC_CTL0(adc_periph) |= CTL0_DISNUM(((uint32_t)length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + /* enable regular channel group discontinuous mode */ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + /* enable inserted channel group discontinuous mode */ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC; + break; + case ADC_CHANNEL_DISCON_DISABLE: + /* disable discontinuous mode of regular & inserted channel */ + default: + break; + } +} + +/*! + \brief configure the length of regular channel group or inserted channel group + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_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(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* configure the length of regular channel group */ + ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL); + ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length-ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + break; + case ADC_INSERTED_CHANNEL: + /* configure the length of inserted channel group */ + ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL); + ADC_ISQ(adc_periph) |= ISQ_IL((uint32_t)(length-ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + break; + default: + break; + } +} + +/*! + \brief configure ADC regular channel + \param[in] adc_periph: ADCx, x=0,1 + \param[in] rank: the regular group sequence rank,this parameter must be between 0 to 15 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): 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(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) +{ + uint32_t rsq,sampt; + + /* ADC regular sequence config */ + if(rank < ADC_REGULAR_CHANNEL_RANK_SIX){ + /* the regular group sequence rank is smaller than six */ + rsq = ADC_RSQ2(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH*rank))); + /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ + rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH*rank)); + ADC_RSQ2(adc_periph) = rsq; + }else if(rank < ADC_REGULAR_CHANNEL_RANK_TWELVE){ + /* the regular group sequence rank is smaller than twelve */ + rsq = ADC_RSQ1(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_SIX)))); + /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ + rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_SIX))); + ADC_RSQ1(adc_periph) = rsq; + }else if(rank < ADC_REGULAR_CHANNEL_RANK_SIXTEEN){ + /* the regular group sequence rank is smaller than sixteen */ + rsq = ADC_RSQ0(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_TWELVE)))); + /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ + rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_TWELVE))); + ADC_RSQ0(adc_periph) = rsq; + }else{ + } + + /* ADC sampling time config */ + if(adc_channel < ADC_CHANNEL_SAMPLE_TEN){ + /* the regular group sequence rank is smaller than ten */ + sampt = ADC_SAMPT1(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH*adc_channel))); + /* channel sample time set*/ + sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH*adc_channel)); + ADC_SAMPT1(adc_periph) = sampt; + }else if(adc_channel < ADC_CHANNEL_SAMPLE_EIGHTEEN){ + /* the regular group sequence rank is smaller than eighteen */ + sampt = ADC_SAMPT0(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH*(adc_channel-ADC_CHANNEL_SAMPLE_TEN)))); + /* channel sample time set*/ + sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH*(adc_channel-ADC_CHANNEL_SAMPLE_TEN))); + ADC_SAMPT0(adc_periph) = sampt; + }else{ + } +} + +/*! + \brief configure ADC inserted channel + \param[in] adc_periph: ADCx, x=0,1 + \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): 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(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) +{ + uint8_t inserted_length; + uint32_t isq,sampt; + /* get inserted channel group length */ + inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph) , 20U , 21U); + /* the channel number is written to these bits to select a channel as the nth conversion in the inserted channel group */ + isq = ADC_ISQ(adc_periph); + isq &= ~((uint32_t)(ADC_ISQ_ISQN << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH-(inserted_length-rank)*ADC_INSERTED_CHANNEL_RANK_LENGTH))); + isq |= ((uint32_t)adc_channel << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH-(inserted_length-rank)*ADC_INSERTED_CHANNEL_RANK_LENGTH)); + ADC_ISQ(adc_periph) = isq; + + /* ADC sampling time config */ + if(adc_channel < ADC_CHANNEL_SAMPLE_TEN){ + /* the inserted group sequence rank is smaller than ten */ + sampt = ADC_SAMPT1(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH*adc_channel))); + /* channel sample time set*/ + sampt |= (uint32_t) sample_time << (ADC_CHANNEL_SAMPLE_LENGTH*adc_channel); + ADC_SAMPT1(adc_periph) = sampt; + }else if(adc_channel < ADC_CHANNEL_SAMPLE_EIGHTEEN){ + /* the inserted group sequence rank is smaller than eighteen */ + sampt = ADC_SAMPT0(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH*(adc_channel-ADC_CHANNEL_SAMPLE_TEN)))); + /* channel sample time set*/ + sampt |= ((uint32_t)sample_time << (ADC_CHANNEL_SAMPLE_LENGTH*(adc_channel-ADC_CHANNEL_SAMPLE_TEN))); + ADC_SAMPT0(adc_periph) = sampt; + }else{ + } +} + +/*! + \brief configure ADC inserted channel offset + \param[in] adc_periph: ADCx, x=0,1 + \param[in] inserted_channel: insert channel select + only one parameter can be selected + \arg ADC_INSERTED_CHANNEL_0: inserted channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted channel3 + \param[in] offset: the offset data + \param[out] none + \retval none +*/ +void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset) +{ + uint8_t inserted_length; + uint32_t num = 0U; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph) , 20U , 21U); + num = ((uint32_t)ADC_OFFSET_LENGTH - ((uint32_t)inserted_length - (uint32_t)inserted_channel)); + + if(num <= ADC_OFFSET_LENGTH){ + /* calculate the offset of the register */ + num = num * ADC_OFFSET_SHIFT_LENGTH; + /* config the offset of the selected channels */ + REG32((adc_periph) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset); + } +} + +/*! + \brief configure ADC external trigger source + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_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 + for regular channel: + \arg ADC0_1_EXTTRIG_REGULAR_T0_CH0: TIMER0 CH0 event select + \arg ADC0_1_EXTTRIG_REGULAR_T0_CH1: TIMER0 CH1 event select + \arg ADC0_1_EXTTRIG_REGULAR_T0_CH2: TIMER0 CH2 event select + \arg ADC0_1_EXTTRIG_REGULAR_T1_CH1: TIMER1 CH1 event select + \arg ADC0_1_EXTTRIG_REGULAR_T2_TRGO: TIMER2 TRGO event select + \arg ADC0_1_EXTTRIG_REGULAR_T3_CH3: TIMER3 CH3 event select + \arg ADC0_1_EXTTRIG_REGULAR_EXTI_11: external interrupt line 11 + \arg ADC0_1_EXTTRIG_REGULAR_NONE: software trigger + for inserted channel: + \arg ADC0_1_EXTTRIG_INSERTED_T0_TRGO: TIMER0 TRGO event select + \arg ADC0_1_EXTTRIG_INSERTED_T0_CH3: TIMER0 CH3 event select + \arg ADC0_1_EXTTRIG_INSERTED_T1_TRGO: TIMER1 TRGO event select + \arg ADC0_1_EXTTRIG_INSERTED_T1_CH0: TIMER1 CH0 event select + \arg ADC0_1_EXTTRIG_INSERTED_T2_CH3: TIMER2 CH3 event select + \arg ADC0_1_EXTTRIG_INSERTED_T3_TRGO: TIMER3 TRGO event select + \arg ADC0_1_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15 + \arg ADC0_1_EXTTRIG_INSERTED_NONE: software trigger + \param[out] none + \retval none +*/ +void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* configure ADC regular group external trigger source */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC); + ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; + break; + case ADC_INSERTED_CHANNEL: + /* configure ADC inserted group external trigger source */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC); + ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; + break; + default: + break; + } +} + +/*! + \brief configure ADC external trigger + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel_group: select the channel group + one or more parameters can be selected which are 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(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue) +{ + if(newvalue){ + if(0U != (adc_channel_group & ADC_REGULAR_CHANNEL)){ + /* enable ADC regular channel group external trigger */ + ADC_CTL1(adc_periph) |= ADC_CTL1_ETERC; + } + if(0U != (adc_channel_group & ADC_INSERTED_CHANNEL)){ + /* enable ADC inserted channel group external trigger */ + ADC_CTL1(adc_periph) |= ADC_CTL1_ETEIC; + } + }else{ + if(0U != (adc_channel_group & ADC_REGULAR_CHANNEL)){ + /* disable ADC regular channel group external trigger */ + ADC_CTL1(adc_periph) &= ~ADC_CTL1_ETERC; + } + if(0U != (adc_channel_group & ADC_INSERTED_CHANNEL)){ + /* disable ADC regular channel group external trigger */ + ADC_CTL1(adc_periph) &= ~ADC_CTL1_ETEIC; + } + } +} + +/*! + \brief enable ADC software trigger + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel_group: select the channel group + one or more parameters can be selected which are 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(uint32_t adc_periph, uint8_t adc_channel_group) +{ + if(0U != (adc_channel_group & ADC_REGULAR_CHANNEL)){ + /* enable ADC regular channel group software trigger */ + ADC_CTL1(adc_periph) |= ADC_CTL1_SWRCST; + } + if(0U != (adc_channel_group & ADC_INSERTED_CHANNEL)){ + /* enable ADC inserted channel group software trigger */ + ADC_CTL1(adc_periph) |= ADC_CTL1_SWICST; + } +} + +/*! + \brief read ADC regular group data register + \param[in] adc_periph: ADCx, x=0,1 + \param[in] none + \param[out] none + \retval the conversion value +*/ +uint16_t adc_regular_data_read(uint32_t adc_periph) +{ + return (uint16_t)(ADC_RDATA(adc_periph)); +} + +/*! + \brief read ADC inserted group data register + \param[in] adc_periph: ADCx, x=0,1 + \param[in] inserted_channel: insert channel select + only one parameter can be selected + \arg ADC_INSERTED_CHANNEL_0: inserted Channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted Channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted Channel3 + \param[out] none + \retval the conversion value +*/ +uint16_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel) +{ + uint32_t idata; + /* read the data of the selected channel */ + switch(inserted_channel){ + case ADC_INSERTED_CHANNEL_0: + /* read the data of channel 0 */ + idata = ADC_IDATA0(adc_periph); + break; + case ADC_INSERTED_CHANNEL_1: + /* read the data of channel 1 */ + idata = ADC_IDATA1(adc_periph); + break; + case ADC_INSERTED_CHANNEL_2: + /* read the data of channel 2 */ + idata = ADC_IDATA2(adc_periph); + break; + case ADC_INSERTED_CHANNEL_3: + /* read the data of channel 3 */ + idata = ADC_IDATA3(adc_periph); + break; + default: + idata = 0U; + break; + } + return (uint16_t)idata; +} + +/*! + \brief read the last ADC0 and ADC1 conversion result data in sync mode + \param[in] none + \param[out] none + \retval the conversion value +*/ +uint32_t adc_sync_mode_convert_value_read(void) +{ + /* return conversion value */ + return ADC_RDATA(ADC0); +} + + +/*! + \brief configure ADC analog watchdog single channel + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x: ADC Channelx(x=0..17)(x=16 and x=17 are only for ADC0) + \param[out] none + \retval none +*/ +void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel) +{ + ADC_CTL0(adc_periph) &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); + /* analog watchdog channel select */ + ADC_CTL0(adc_periph) |= (uint32_t)adc_channel; + ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); +} + +/*! + \brief configure ADC analog watchdog group channel + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_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(uint32_t adc_periph, uint8_t adc_channel_group) +{ + ADC_CTL0(adc_periph) &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); + /* select the group */ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* regular channel analog watchdog enable */ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_RWDEN; + break; + case ADC_INSERTED_CHANNEL: + /* inserted channel analog watchdog enable */ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_IWDEN; + break; + case ADC_REGULAR_INSERTED_CHANNEL: + /* regular and inserted channel analog watchdog enable */ + ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN); + break; + default: + break; + } +} + +/*! + \brief disable ADC analog watchdog + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_watchdog_disable(uint32_t adc_periph) +{ + ADC_CTL0(adc_periph) &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); +} + +/*! + \brief configure ADC analog watchdog threshold + \param[in] adc_periph: ADCx, x=0,1 + \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(uint32_t adc_periph, uint16_t low_threshold, uint16_t high_threshold) +{ + ADC_WDLT(adc_periph) = (uint32_t)WDLT_WDLT(low_threshold); + ADC_WDHT(adc_periph) = (uint32_t)WDHT_WDHT(high_threshold); +} + +/*! + \brief get the ADC flag bits + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_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 adc_periph, uint32_t adc_flag) +{ + FlagStatus reval = RESET; + if(ADC_STAT(adc_periph) & adc_flag){ + reval = SET; + } + return reval; +} + +/*! + \brief clear the ADC flag bits + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_flag: the adc flag bits + one or more parameters can be selected which are 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 adc_periph, uint32_t adc_flag) +{ + ADC_STAT(adc_periph) &= ~((uint32_t)adc_flag); +} + +/*! + \brief get the bit state of ADCx software start conversion + \param[in] adc_periph: ADCx, x=0,1 + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph) +{ + FlagStatus reval = RESET; + if((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_SWRCST)){ + reval = SET; + } + return reval; +} + +/*! + \brief get the bit state of ADCx software inserted channel start conversion + \param[in] adc_periph: ADCx, x=0,1 + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph) +{ + FlagStatus reval = RESET; + if((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_SWICST)){ + reval = SET; + } + return reval; +} + +/*! + \brief get the ADC interrupt bits + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_interrupt: the adc interrupt bits + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE: analog watchdog interrupt + \arg ADC_INT_FLAG_EOC: end of group conversion interrupt + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t adc_interrupt) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + /* check the interrupt bits */ + switch(adc_interrupt){ + case ADC_INT_FLAG_WDE: + /* get the ADC analog watchdog interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_WDE; + if((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOC: + /* get the ADC end of group conversion interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_EOC; + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOIC: + /* get the ADC end of inserted group conversion interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_EOIC; + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state){ + interrupt_flag = SET; + } + break; + default: + break; + } + return interrupt_flag; +} + +/*! + \brief clear the ADC flag + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_interrupt: the adc status flag + one or more parameters can be selected which are shown as below: + \arg ADC_INT_FLAG_WDE: analog watchdog interrupt + \arg ADC_INT_FLAG_EOC: end of group conversion interrupt + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t adc_interrupt) +{ + ADC_STAT(adc_periph) &= ~((uint32_t)adc_interrupt); +} + +/*! + \brief enable ADC interrupt + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_interrupt: the adc interrupt + one or more parameters can be selected which are shown as below: + \arg ADC_INT_WDE: analog watchdog interrupt flag + \arg ADC_INT_EOC: end of group conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt) +{ + /* enable ADC analog watchdog interrupt */ + if(0U != (adc_interrupt & ADC_INT_WDE)){ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDEIE; + } + /* enable ADC end of group conversion interrupt */ + if(0U != (adc_interrupt & ADC_INT_EOC)){ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOCIE; + } + /* enable ADC end of inserted group conversion interrupt */ + if(0U != (adc_interrupt & ADC_INT_EOIC)){ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOICIE; + } +} + +/*! + \brief disable ADC interrupt + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_interrupt: the adc interrupt flag + one or more parameters can be selected which are shown as below: + \arg ADC_INT_WDE: analog watchdog interrupt flag + \arg ADC_INT_EOC: end of group conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt) +{ + /* disable ADC analog watchdog interrupt */ + if(0U != (adc_interrupt & ADC_INT_WDE)){ + ADC_CTL0(adc_periph) &= ~(uint32_t) ADC_CTL0_WDEIE; + } + /* disable ADC end of group conversion interrupt */ + if(0U != (adc_interrupt & ADC_INT_EOC)){ + ADC_CTL0(adc_periph) &= ~(uint32_t) ADC_CTL0_EOCIE; + } + /* disable ADC end of inserted group conversion interrupt */ + if(0U != (adc_interrupt & ADC_INT_EOIC)){ + ADC_CTL0(adc_periph) &= ~(uint32_t) ADC_CTL0_EOICIE; + } +} + +/*! + \brief adc resolution config + \param[in] adc_periph: ADCx, x=0,1 + \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 adc_periph, uint32_t resolution) +{ + ADC_OVSCR(adc_periph) &= ~((uint32_t)ADC_OVSCR_DRES); + ADC_OVSCR(adc_periph) |= (uint32_t)resolution; +} + +/*! + \brief adc oversample mode config + \param[in] adc_periph: ADCx, x=0,1 + \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 X2 + \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio X4 + \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio X8 + \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio X16 + \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio X32 + \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio X64 + \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio X128 + \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio X256 + \param[out] none + \retval none +*/ +void adc_oversample_mode_config(uint32_t adc_periph, uint8_t mode, uint16_t shift,uint8_t ratio) +{ + if(mode){ + ADC_OVSCR(adc_periph) |= (uint32_t)ADC_OVSCR_TOVS; + }else{ + ADC_OVSCR(adc_periph) &= ~((uint32_t)ADC_OVSCR_TOVS); + } + /* config the shift and ratio */ + ADC_OVSCR(adc_periph) &= ~((uint32_t)(ADC_OVSCR_OVSR | ADC_OVSCR_OVSS)); + ADC_OVSCR(adc_periph) |= ((uint32_t)shift | (uint32_t)ratio); +} + +/*! + \brief enable ADC oversample mode + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_oversample_mode_enable(uint32_t adc_periph) +{ + ADC_OVSCR(adc_periph) |= ADC_OVSCR_OVSEN; +} + +/*! + \brief disable ADC oversample mode + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_oversample_mode_disable(uint32_t adc_periph) +{ + ADC_OVSCR(adc_periph) &= ~((uint32_t)ADC_OVSCR_OVSEN); +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_bkp.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_bkp.c new file mode 100644 index 0000000000000000000000000000000000000000..e3b01e4c665663e3e73faee427a652c1eace8c95 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_bkp.c @@ -0,0 +1,292 @@ +/*! + \file gd32vf103_bkp.c + \brief BKP driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_bkp.h" + +/* BKP register bits offset */ +#define BKP_TAMPER_BITS_OFFSET ((uint32_t)8U) + +/*! + \brief reset BKP registers + \param[in] none + \param[out] none + \retval none +*/ +void bkp_deinit(void) +{ + /* reset BKP domain register*/ + rcu_bkp_reset_enable(); + rcu_bkp_reset_disable(); +} + +/*! + \brief write BKP data register + \param[in] register_number: refer to bkp_data_register_enum + only one parameter can be selected which is shown as below: + \arg BKP_DATA_x(x = 0..41): bkp data register number x + \param[in] data: the data to be write in BKP data register + \param[out] none + \retval none +*/ +void bkp_data_write(bkp_data_register_enum register_number, uint16_t data) +{ + if((register_number >= BKP_DATA_10) && (register_number <= BKP_DATA_41)){ + BKP_DATA10_41(register_number - 1U) = data; + }else if((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)){ + BKP_DATA0_9(register_number - 1U) = data; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief read BKP data register + \param[in] register_number: refer to bkp_data_register_enum + only one parameter can be selected which is shown as below: + \arg BKP_DATA_x(x = 0..41): bkp data register number x + \param[out] none + \retval data of BKP data register +*/ +uint16_t bkp_data_read(bkp_data_register_enum register_number) +{ + uint16_t data = 0U; + + /* get the data from the BKP data register */ + if((register_number >= BKP_DATA_10) && (register_number <= BKP_DATA_41)){ + data = BKP_DATA10_41(register_number - 1U); + }else if((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)){ + data = BKP_DATA0_9(register_number - 1U); + }else{ + /* illegal parameters */ + } + return data; +} + +/*! + \brief enable RTC clock calibration output + \param[in] none + \param[out] none + \retval none +*/ +void bkp_rtc_calibration_output_enable(void) +{ + BKP_OCTL |= (uint16_t)BKP_OCTL_COEN; +} + +/*! + \brief disable RTC clock calibration output + \param[in] none + \param[out] none + \retval none +*/ +void bkp_rtc_calibration_output_disable(void) +{ + BKP_OCTL &= (uint16_t)~BKP_OCTL_COEN; +} + +/*! + \brief enable RTC alarm or second signal output + \param[in] none + \param[out] none + \retval none +*/ +void bkp_rtc_signal_output_enable(void) +{ + BKP_OCTL |= (uint16_t)BKP_OCTL_ASOEN; +} + +/*! + \brief disable RTC alarm or second signal output + \param[in] none + \param[out] none + \retval none +*/ +void bkp_rtc_signal_output_disable(void) +{ + BKP_OCTL &= (uint16_t)~BKP_OCTL_ASOEN; +} + +/*! + \brief select RTC output + \param[in] outputsel: RTC output selection + only one parameter can be selected which is shown as below: + \arg RTC_OUTPUT_ALARM_PULSE: RTC alarm pulse is selected as the RTC output + \arg RTC_OUTPUT_SECOND_PULSE: RTC second pulse is selected as the RTC output + \param[out] none + \retval none +*/ +void bkp_rtc_output_select(uint16_t outputsel) +{ + uint16_t ctl = 0U; + + /* configure BKP_OCTL_ROSEL with outputsel */ + ctl = BKP_OCTL; + ctl &= (uint16_t)~BKP_OCTL_ROSEL; + ctl |= outputsel; + BKP_OCTL = ctl; +} + +/*! + \brief set RTC clock calibration value + \param[in] value: RTC clock calibration value + \arg 0x00 - 0x7F + \param[out] none + \retval none +*/ +void bkp_rtc_calibration_value_set(uint8_t value) +{ + uint16_t ctl; + + /* configure BKP_OCTL_RCCV with value */ + ctl = BKP_OCTL; + ctl &= (uint16_t)~BKP_OCTL_RCCV; + ctl |= (uint16_t)OCTL_RCCV(value); + BKP_OCTL = ctl; +} + +/*! + \brief enable tamper detection + \param[in] none + \param[out] none + \retval none +*/ +void bkp_tamper_detection_enable(void) +{ + BKP_TPCTL |= (uint16_t)BKP_TPCTL_TPEN; +} + +/*! + \brief disable tamper detection + \param[in] none + \param[out] none + \retval none +*/ +void bkp_tamper_detection_disable(void) +{ + BKP_TPCTL &= (uint16_t)~BKP_TPCTL_TPEN; +} + +/*! + \brief set tamper pin active level + \param[in] level: tamper active level + only one parameter can be selected which is shown as below: + \arg TAMPER_PIN_ACTIVE_HIGH: the tamper pin is active high + \arg TAMPER_PIN_ACTIVE_LOW: the tamper pin is active low + \param[out] none + \retval none +*/ +void bkp_tamper_active_level_set(uint16_t level) +{ + uint16_t ctl = 0U; + + /* configure BKP_TPCTL_TPAL with level */ + ctl = BKP_TPCTL; + ctl &= (uint16_t)~BKP_TPCTL_TPAL; + ctl |= level; + BKP_TPCTL = ctl; +} + +/*! + \brief enable tamper interrupt + \param[in] none + \param[out] none + \retval none +*/ +void bkp_interrupt_enable(void) +{ + BKP_TPCS |= (uint16_t)BKP_TPCS_TPIE; +} + +/*! + \brief disable tamper interrupt + \param[in] none + \param[out] none + \retval none +*/ +void bkp_interrupt_disable(void) +{ + BKP_TPCS &= (uint16_t)~BKP_TPCS_TPIE; +} + +/*! + \brief get tamper flag state + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus bkp_flag_get(void) +{ + if(RESET != (BKP_TPCS & BKP_FLAG_TAMPER)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear tamper flag state + \param[in] none + \param[out] none + \retval none +*/ +void bkp_flag_clear(void) +{ + BKP_TPCS |= (uint16_t)(BKP_FLAG_TAMPER >> BKP_TAMPER_BITS_OFFSET); +} + +/*! + \brief get tamper interrupt flag state + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus bkp_interrupt_flag_get(void) +{ + if(RESET != (BKP_TPCS & BKP_INT_FLAG_TAMPER)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear tamper interrupt flag state + \param[in] none + \param[out] none + \retval none +*/ +void bkp_interrupt_flag_clear(void) +{ + BKP_TPCS |= (uint16_t)(BKP_INT_FLAG_TAMPER >> BKP_TAMPER_BITS_OFFSET); +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_can.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_can.c new file mode 100644 index 0000000000000000000000000000000000000000..b90131ab60d0c77077e95c7911489ec3234bdb5f --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_can.c @@ -0,0 +1,989 @@ +/*! + \file gd32vf103_can.c + \brief CAN driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_can.h" + +#define CAN_ERROR_HANDLE(s) do{}while(1) + +/*! + \brief deinitialize CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_deinit(uint32_t can_periph) +{ + if(CAN0 == can_periph){ + rcu_periph_reset_enable(RCU_CAN0RST); + rcu_periph_reset_disable(RCU_CAN0RST); + }else{ + rcu_periph_reset_enable(RCU_CAN1RST); + rcu_periph_reset_disable(RCU_CAN1RST); + } +} + +/*! + \brief initialize CAN parameter struct with a default value + \param[in] type: the type of CAN parameter struct + only one parameter can be selected which is shown as below: + \arg CAN_INIT_STRUCT: the CAN initial struct + \arg CAN_FILTER_STRUCT: the CAN filter struct + \arg CAN_TX_MESSAGE_STRUCT: the CAN TX message struct + \arg CAN_RX_MESSAGE_STRUCT: the CAN RX message struct + \param[in] p_struct: the pointer of the specific struct + \param[out] none + \retval none +*/ +void can_struct_para_init(can_struct_type_enum type, void* p_struct) +{ + uint8_t i; + + /* get type of the struct */ + switch(type){ + /* used for can_init() */ + case CAN_INIT_STRUCT: + ((can_parameter_struct*)p_struct)->auto_bus_off_recovery = DISABLE; + ((can_parameter_struct*)p_struct)->auto_retrans = DISABLE; + ((can_parameter_struct*)p_struct)->auto_wake_up = DISABLE; + ((can_parameter_struct*)p_struct)->prescaler = 0x03FFU; + ((can_parameter_struct*)p_struct)->rec_fifo_overwrite = DISABLE; + ((can_parameter_struct*)p_struct)->resync_jump_width = CAN_BT_SJW_1TQ; + ((can_parameter_struct*)p_struct)->time_segment_1 = CAN_BT_BS1_3TQ; + ((can_parameter_struct*)p_struct)->time_segment_2 = CAN_BT_BS2_1TQ; + ((can_parameter_struct*)p_struct)->time_triggered = DISABLE; + ((can_parameter_struct*)p_struct)->trans_fifo_order = DISABLE; + ((can_parameter_struct*)p_struct)->working_mode = CAN_NORMAL_MODE; + + break; + /* used for can_filter_init() */ + case CAN_FILTER_STRUCT: + ((can_filter_parameter_struct*)p_struct)->filter_bits = CAN_FILTERBITS_32BIT; + ((can_filter_parameter_struct*)p_struct)->filter_enable = DISABLE; + ((can_filter_parameter_struct*)p_struct)->filter_fifo_number = CAN_FIFO0; + ((can_filter_parameter_struct*)p_struct)->filter_list_high = 0x0000U; + ((can_filter_parameter_struct*)p_struct)->filter_list_low = 0x0000U; + ((can_filter_parameter_struct*)p_struct)->filter_mask_high = 0x0000U; + ((can_filter_parameter_struct*)p_struct)->filter_mask_low = 0x0000U; + ((can_filter_parameter_struct*)p_struct)->filter_mode = CAN_FILTERMODE_MASK; + ((can_filter_parameter_struct*)p_struct)->filter_number = 0U; + + break; + /* used for can_message_transmit() */ + case CAN_TX_MESSAGE_STRUCT: + for(i = 0U; i < 8U; i++){ + ((can_trasnmit_message_struct*)p_struct)->tx_data[i] = 0U; + } + + ((can_trasnmit_message_struct*)p_struct)->tx_dlen = 0u; + ((can_trasnmit_message_struct*)p_struct)->tx_efid = 0U; + ((can_trasnmit_message_struct*)p_struct)->tx_ff = (uint8_t)CAN_FF_STANDARD; + ((can_trasnmit_message_struct*)p_struct)->tx_ft = (uint8_t)CAN_FT_DATA; + ((can_trasnmit_message_struct*)p_struct)->tx_sfid = 0U; + + break; + /* used for can_message_receive() */ + case CAN_RX_MESSAGE_STRUCT: + for(i = 0U; i < 8U; i++){ + ((can_receive_message_struct*)p_struct)->rx_data[i] = 0U; + } + + ((can_receive_message_struct*)p_struct)->rx_dlen = 0U; + ((can_receive_message_struct*)p_struct)->rx_efid = 0U; + ((can_receive_message_struct*)p_struct)->rx_ff = (uint8_t)CAN_FF_STANDARD; + ((can_receive_message_struct*)p_struct)->rx_fi = 0U; + ((can_receive_message_struct*)p_struct)->rx_ft = (uint8_t)CAN_FT_DATA; + ((can_receive_message_struct*)p_struct)->rx_sfid = 0U; + + break; + + default: + CAN_ERROR_HANDLE("parameter is invalid \r\n"); + } +} + +/*! + \brief initialize CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_parameter_init: parameters for CAN initializtion + \arg working_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE + \arg resync_jump_width: CAN_BT_SJW_xTQ(x=1, 2, 3, 4) + \arg time_segment_1: CAN_BT_BS1_xTQ(1..16) + \arg time_segment_2: CAN_BT_BS2_xTQ(1..8) + \arg time_triggered: ENABLE or DISABLE + \arg auto_bus_off_recovery: ENABLE or DISABLE + \arg auto_wake_up: ENABLE or DISABLE + \arg auto_retrans: ENABLE or DISABLE + \arg rec_fifo_overwrite: ENABLE or DISABLE + \arg trans_fifo_order: ENABLE or DISABLE + \arg prescaler: 0x0000 - 0x03FF + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init) +{ + uint32_t timeout = CAN_TIMEOUT; + ErrStatus flag = ERROR; + + /* disable sleep mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; + /* enable initialize mode */ + CAN_CTL(can_periph) |= CAN_CTL_IWMOD; + /* wait ACK */ + while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){ + timeout--; + } + /* check initialize working success */ + if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + flag = ERROR; + }else{ + /* set the bit timing register */ + CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \ + BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \ + BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \ + BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \ + BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U))); + + /* time trigger communication mode */ + if(ENABLE == can_parameter_init->time_triggered){ + CAN_CTL(can_periph) |= CAN_CTL_TTC; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_TTC; + } + /* automatic bus-off managment */ + if(ENABLE == can_parameter_init->auto_bus_off_recovery){ + CAN_CTL(can_periph) |= CAN_CTL_ABOR; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_ABOR; + } + /* automatic wakeup mode */ + if(ENABLE == can_parameter_init->auto_wake_up){ + CAN_CTL(can_periph) |= CAN_CTL_AWU; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_AWU; + } + /* automatic retransmission mode disable*/ + if(ENABLE == can_parameter_init->auto_retrans){ + CAN_CTL(can_periph) |= CAN_CTL_ARD; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_ARD; + } + /* receive fifo overwrite mode */ + if(ENABLE == can_parameter_init->rec_fifo_overwrite){ + CAN_CTL(can_periph) |= CAN_CTL_RFOD; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_RFOD; + } + /* transmit fifo order */ + if(ENABLE == can_parameter_init->trans_fifo_order){ + CAN_CTL(can_periph) |= CAN_CTL_TFO; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_TFO; + } + /* disable initialize mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD; + timeout = CAN_TIMEOUT; + /* wait the ACK */ + while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){ + timeout--; + } + /* check exit initialize mode */ + if(0U != timeout){ + flag = SUCCESS; + } + } + CAN_TMI0(can_periph) = 0x0; + CAN_TMI1(can_periph) = 0x0; + CAN_TMI2(can_periph) = 0x0; + CAN_TMP0(can_periph) = 0x0; + CAN_TMP1(can_periph) = 0x0; + CAN_TMP2(can_periph) = 0x0; + CAN_TMDATA00(can_periph) = 0x0; + CAN_TMDATA01(can_periph) = 0x0; + CAN_TMDATA02(can_periph) = 0x0; + CAN_TMDATA10(can_periph) = 0x0; + CAN_TMDATA11(can_periph) = 0x0; + CAN_TMDATA12(can_periph) = 0x0; + + return flag; +} + +/*! + \brief initialize CAN filter + \param[in] can_filter_parameter_init: struct for CAN filter initialization + \arg filter_list_high: 0x0000 - 0xFFFF + \arg filter_list_low: 0x0000 - 0xFFFF + \arg filter_mask_high: 0x0000 - 0xFFFF + \arg filter_mask_low: 0x0000 - 0xFFFF + \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1 + \arg filter_number: 0 - 27 + \arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST + \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT + \arg filter_enable: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init) +{ + uint32_t val = 0U; + + val = ((uint32_t)1) << (can_filter_parameter_init->filter_number); + /* filter lock disable */ + CAN_FCTL(CAN0) |= CAN_FCTL_FLD; + /* disable filter */ + CAN_FW(CAN0) &= ~(uint32_t)val; + + /* filter 16 bits */ + if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){ + /* set filter 16 bits */ + CAN_FSCFG(CAN0) &= ~(uint32_t)val; + /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */ + CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */ + CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS); + } + /* filter 32 bits */ + if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){ + /* set filter 32 bits */ + CAN_FSCFG(CAN0) |= (uint32_t)val; + /* 32 bits list or first 32 bits list */ + CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + /* 32 bits mask or second 32 bits list */ + CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS); + } + + /* filter mode */ + if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){ + /* mask mode */ + CAN_FMCFG(CAN0) &= ~(uint32_t)val; + }else{ + /* list mode */ + CAN_FMCFG(CAN0) |= (uint32_t)val; + } + + /* filter FIFO */ + if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){ + /* FIFO0 */ + CAN_FAFIFO(CAN0) &= ~(uint32_t)val; + }else{ + /* FIFO1 */ + CAN_FAFIFO(CAN0) |= (uint32_t)val; + } + + /* filter working */ + if(ENABLE == can_filter_parameter_init->filter_enable){ + + CAN_FW(CAN0) |= (uint32_t)val; + } + + /* filter lock enable */ + CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; +} + +/*! + \brief set CAN1 fliter start bank number + \param[in] start_bank: CAN1 start bank number + only one parameter can be selected which is shown as below: + \arg (1..27) + \param[out] none + \retval none +*/ +void can1_filter_start_bank(uint8_t start_bank) +{ + /* filter lock disable */ + CAN_FCTL(CAN0) |= CAN_FCTL_FLD; + /* set CAN1 filter start number */ + CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F; + CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank); + /* filter lock enaable */ + CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; +} + +/*! + \brief enable CAN debug freeze + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_debug_freeze_enable(uint32_t can_periph) +{ + /* set DFZ bit */ + CAN_CTL(can_periph) |= CAN_CTL_DFZ; + if(CAN0 == can_periph){ + dbg_periph_enable(DBG_CAN0_HOLD); + }else{ + dbg_periph_enable(DBG_CAN1_HOLD); + } +} + +/*! + \brief disable CAN debug freeze + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_debug_freeze_disable(uint32_t can_periph) +{ + /* set DFZ bit */ + CAN_CTL(can_periph) &= ~CAN_CTL_DFZ; + if(CAN0 == can_periph){ + dbg_periph_disable(DBG_CAN0_HOLD); + }else{ + dbg_periph_disable(DBG_CAN1_HOLD); + } +} + +/*! + \brief enable CAN time trigger mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_trigger_mode_enable(uint32_t can_periph) +{ + uint8_t mailbox_number; + + /* enable the tcc mode */ + CAN_CTL(can_periph) |= CAN_CTL_TTC; + /* enable time stamp */ + for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++){ + CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN; + } +} + +/*! + \brief disable CAN time trigger mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_trigger_mode_disable(uint32_t can_periph) +{ + uint8_t mailbox_number; + + /* disable the TCC mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_TTC; + /* reset TSEN bits */ + for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++){ + CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN; + } +} + +/*! + \brief transmit CAN message + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] transmit_message: struct for CAN transmit message + \arg tx_sfid: 0x00000000 - 0x000007FF + \arg tx_efid: 0x00000000 - 0x1FFFFFFF + \arg tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED + \arg tx_ft: CAN_FT_DATA, CAN_FT_REMOTE + \arg tx_dlenc: 1 - 7 + \arg tx_data[]: 0x00 - 0xFF + \param[out] none + \retval mailbox_number +*/ +uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message) +{ + uint8_t mailbox_number = CAN_MAILBOX0; + + /* select one empty mailbox */ + if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){ + mailbox_number = CAN_MAILBOX0; + }else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){ + mailbox_number = CAN_MAILBOX1; + }else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){ + mailbox_number = CAN_MAILBOX2; + }else{ + mailbox_number = CAN_NOMAILBOX; + } + /* return no mailbox empty */ + if(CAN_NOMAILBOX == mailbox_number){ + return CAN_NOMAILBOX; + } + + CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN; + if(CAN_FF_STANDARD == transmit_message->tx_ff){ + /* set transmit mailbox standard identifier */ + CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \ + transmit_message->tx_ft); + }else{ + /* set transmit mailbox extended identifier */ + CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \ + transmit_message->tx_ff | \ + transmit_message->tx_ft); + } + /* set the data length */ + CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_DLENC; + CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen; + /* set the data */ + CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \ + TMDATA0_DB2(transmit_message->tx_data[2]) | \ + TMDATA0_DB1(transmit_message->tx_data[1]) | \ + TMDATA0_DB0(transmit_message->tx_data[0]); + CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \ + TMDATA1_DB6(transmit_message->tx_data[6]) | \ + TMDATA1_DB5(transmit_message->tx_data[5]) | \ + TMDATA1_DB4(transmit_message->tx_data[4]); + /* enable transmission */ + CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN; + + return mailbox_number; +} + +/*! + \brief get CAN transmit state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] mailbox_number + only one parameter can be selected which is shown as below: + \arg CAN_MAILBOX(x=0,1,2) + \param[out] none + \retval can_transmit_state_enum +*/ +can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number) +{ + can_transmit_state_enum state = CAN_TRANSMIT_FAILED; + uint32_t val = 0U; + + /* check selected mailbox state */ + switch(mailbox_number){ + /* mailbox0 */ + case CAN_MAILBOX0: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0); + break; + /* mailbox1 */ + case CAN_MAILBOX1: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1); + break; + /* mailbox2 */ + case CAN_MAILBOX2: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2); + break; + default: + val = CAN_TRANSMIT_FAILED; + break; + } + + switch(val){ + /* transmit pending */ + case (CAN_STATE_PENDING): + state = CAN_TRANSMIT_PENDING; + break; + /* mailbox0 transmit succeeded */ + case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0): + state = CAN_TRANSMIT_OK; + break; + /* mailbox1 transmit succeeded */ + case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1): + state = CAN_TRANSMIT_OK; + break; + /* mailbox2 transmit succeeded */ + case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2): + state = CAN_TRANSMIT_OK; + break; + /* transmit failed */ + default: + state = CAN_TRANSMIT_FAILED; + break; + } + return state; +} + +/*! + \brief stop CAN transmission + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] mailbox_number + only one parameter can be selected which is shown as below: + \arg CAN_MAILBOXx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number) +{ + if(CAN_MAILBOX0 == mailbox_number){ + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0; + while(CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)){ + } + }else if(CAN_MAILBOX1 == mailbox_number){ + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1; + while(CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)){ + } + }else if(CAN_MAILBOX2 == mailbox_number){ + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2; + while(CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)){ + } + }else{ + /* illegal parameters */ + } +} + +/*! + \brief CAN receive message + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + \arg CAN_FIFOx(x=0,1) + \param[out] receive_message: struct for CAN receive message + \arg rx_sfid: 0x00000000 - 0x000007FF + \arg rx_efid: 0x00000000 - 0x1FFFFFFF + \arg rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED + \arg rx_ft: CAN_FT_DATA, CAN_FT_REMOTE + \arg rx_dlenc: 1 - 7 + \arg rx_data[]: 0x00 - 0xFF + \arg rx_fi: 0 - 27 + \retval none +*/ +void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message) +{ + /* get the frame format */ + receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number)); + if(CAN_FF_STANDARD == receive_message->rx_ff){ + /* get standard identifier */ + receive_message->rx_sfid = (uint32_t)(GET_RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number))); + }else{ + /* get extended identifier */ + receive_message->rx_efid = (uint32_t)(GET_RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number))); + } + + /* get frame type */ + receive_message->rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number)); + /* filtering index */ + receive_message->rx_fi = (uint8_t)(GET_RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number))); + /* get recevie data length */ + receive_message->rx_dlen = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number))); + + /* receive data */ + receive_message -> rx_data[0] = (uint8_t)(GET_RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[1] = (uint8_t)(GET_RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[2] = (uint8_t)(GET_RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[3] = (uint8_t)(GET_RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[4] = (uint8_t)(GET_RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[5] = (uint8_t)(GET_RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[6] = (uint8_t)(GET_RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number))); + + /* release FIFO */ + if(CAN_FIFO0 == fifo_number){ + CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0; + }else{ + CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1; + } +} + +/*! + \brief release FIFO0 + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + only one parameter can be selected which is shown as below: + \arg CAN_FIFOx(x=0,1) + \param[out] none + \retval none +*/ +void can_fifo_release(uint32_t can_periph, uint8_t fifo_number) +{ + if(CAN_FIFO0 == fifo_number){ + CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0; + }else if(CAN_FIFO1 == fifo_number){ + CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1; + }else{ + /* illegal parameters */ + CAN_ERROR_HANDLE("CAN FIFO NUM is invalid \r\n"); + } +} + +/*! + \brief CAN receive message length + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + only one parameter can be selected which is shown as below: + \arg CAN_FIFOx(x=0,1) + \param[out] none + \retval message length +*/ +uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number) +{ + uint8_t val = 0U; + + if(CAN_FIFO0 == fifo_number){ + /* FIFO0 */ + val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK); + }else if(CAN_FIFO1 == fifo_number){ + /* FIFO1 */ + val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK); + }else{ + /* illegal parameters */ + } + return val; +} + +/*! + \brief set CAN working mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_working_mode + only one parameter can be selected which is shown as below: + \arg CAN_MODE_INITIALIZE + \arg CAN_MODE_NORMAL + \arg CAN_MODE_SLEEP + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode) +{ + ErrStatus flag = ERROR; + /* timeout for IWS or also for SLPWS bits */ + uint32_t timeout = CAN_TIMEOUT; + + if(CAN_MODE_INITIALIZE == working_mode){ + /* disable sleep mode */ + CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD); + /* set initialize mode */ + CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD; + /* wait the acknowledge */ + while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){ + timeout--; + } + if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + }else if(CAN_MODE_NORMAL == working_mode){ + /* enter normal mode */ + CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD); + /* wait the acknowledge */ + while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)){ + timeout--; + } + if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + }else if(CAN_MODE_SLEEP == working_mode){ + /* disable initialize mode */ + CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD); + /* set sleep mode */ + CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD; + /* wait the acknowledge */ + while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)){ + timeout--; + } + if(CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + }else{ + flag = ERROR; + } + return flag; +} + +/*! + \brief wake up CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus can_wakeup(uint32_t can_periph) +{ + ErrStatus flag = ERROR; + uint32_t timeout = CAN_TIMEOUT; + + /* wakeup */ + CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; + + while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)){ + timeout--; + } + /* check state */ + if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + return flag; +} + +/*! + \brief get CAN error type + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval can_error_enum + \arg CAN_ERROR_NONE: no error + \arg CAN_ERROR_FILL: fill error + \arg CAN_ERROR_FORMATE: format error + \arg CAN_ERROR_ACK: ACK error + \arg CAN_ERROR_BITRECESSIVE: bit recessive + \arg CAN_ERROR_BITDOMINANTER: bit dominant error + \arg CAN_ERROR_CRC: CRC error + \arg CAN_ERROR_SOFTWARECFG: software configure +*/ +can_error_enum can_error_get(uint32_t can_periph) +{ + can_error_enum error; + error = CAN_ERROR_NONE; + + /* get error type */ + error = (can_error_enum)(GET_ERR_ERRN(CAN_ERR(can_periph))); + return error; +} + +/*! + \brief get CAN receive error number + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval error number +*/ +uint8_t can_receive_error_number_get(uint32_t can_periph) +{ + uint8_t val; + + /* get error count */ + val = (uint8_t)(GET_ERR_RECNT(CAN_ERR(can_periph))); + return val; +} + +/*! + \brief get CAN transmit error number + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval error number +*/ +uint8_t can_transmit_error_number_get(uint32_t can_periph) +{ + uint8_t val; + + val = (uint8_t)(GET_ERR_TECNT(CAN_ERR(can_periph))); + return val; +} + +/*! + \brief enable CAN interrupt + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] interrupt + one or more parameters can be selected which are shown as below: + \arg CAN_INT_TME: transmit mailbox empty interrupt enable + \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable + \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable + \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable + \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable + \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable + \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable + \arg CAN_INT_WERR: warning error interrupt enable + \arg CAN_INT_PERR: passive error interrupt enable + \arg CAN_INT_BO: bus-off interrupt enable + \arg CAN_INT_ERRN: error number interrupt enable + \arg CAN_INT_ERR: error interrupt enable + \arg CAN_INT_WU: wakeup interrupt enable + \arg CAN_INT_SLPW: sleep working interrupt enable + \param[out] none + \retval none +*/ +void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt) +{ + CAN_INTEN(can_periph) |= interrupt; +} + +/*! + \brief disable CAN interrupt + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] interrupt + one or more parameters can be selected which are shown as below: + \arg CAN_INT_TME: transmit mailbox empty interrupt enable + \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable + \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable + \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable + \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable + \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable + \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable + \arg CAN_INT_WERR: warning error interrupt enable + \arg CAN_INT_PERR: passive error interrupt enable + \arg CAN_INT_BO: bus-off interrupt enable + \arg CAN_INT_ERRN: error number interrupt enable + \arg CAN_INT_ERR: error interrupt enable + \arg CAN_INT_WU: wakeup interrupt enable + \arg CAN_INT_SLPW: sleep working interrupt enable + \param[out] none + \retval none +*/ +void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt) +{ + CAN_INTEN(can_periph) &= ~interrupt; +} + +/*! + \brief get CAN flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_MTE2: mailbox 2 transmit error + \arg CAN_FLAG_MTE1: mailbox 1 transmit error + \arg CAN_FLAG_MTE0: mailbox 0 transmit error + \arg CAN_FLAG_MTF2: mailbox 2 transmit finished + \arg CAN_FLAG_MTF1: mailbox 1 transmit finished + \arg CAN_FLAG_MTF0: mailbox 0 transmit finished + \arg CAN_FLAG_RFO0: receive FIFO0 overfull + \arg CAN_FLAG_RFF0: receive FIFO0 full + \arg CAN_FLAG_RFO1: receive FIFO1 overfull + \arg CAN_FLAG_RFF1: receive FIFO1 full + \arg CAN_FLAG_BOERR: bus-off error + \arg CAN_FLAG_PERR: passive error + \arg CAN_FLAG_WERR: warning error + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag) +{ + /* get flag and interrupt enable state */ + if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CAN flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_MTE2: mailbox 2 transmit error + \arg CAN_FLAG_MTE1: mailbox 1 transmit error + \arg CAN_FLAG_MTE0: mailbox 0 transmit error + \arg CAN_FLAG_MTF2: mailbox 2 transmit finished + \arg CAN_FLAG_MTF1: mailbox 1 transmit finished + \arg CAN_FLAG_MTF0: mailbox 0 transmit finished + \arg CAN_FLAG_RFO0: receive FIFO0 overfull + \arg CAN_FLAG_RFF0: receive FIFO0 full + \arg CAN_FLAG_RFO1: receive FIFO1 overfull + \arg CAN_FLAG_RFF1: receive FIFO1 full + \arg CAN_FLAG_BOERR: bus-off error + \arg CAN_FLAG_PERR: passive error + \arg CAN_FLAG_WERR: warning error + \param[out] none + \retval none +*/ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag) +{ + CAN_REG_VAL(can_periph, flag) = BIT(CAN_BIT_POS(flag)); +} + +/*! + \brief get CAN interrupt flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering + \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode + \arg CAN_INT_FLAG_ERRIF: error interrupt flag + \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag + \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag + \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag + \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag + \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag) +{ + uint32_t ret1 = RESET; + uint32_t ret2 = RESET; + + /* get the staus of interrupt flag */ + ret1 = CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag)); + /* get the staus of interrupt enale bit */ + ret2 = CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag)); + if(ret1 && ret2){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CAN interrupt flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering + \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode + \arg CAN_INT_FLAG_ERRIF: error interrupt flag + \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag + \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag + \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag + \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag + \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag + \arg CAN_FLAG_BOERR: bus-off error + \arg CAN_FLAG_PERR: passive error + \arg CAN_FLAG_WERR: warning error + \param[out] none + \retval none +*/ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag) +{ + CAN_REG_VALS(can_periph, flag) = BIT(CAN_BIT_POS0(flag)); +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_crc.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_crc.c new file mode 100644 index 0000000000000000000000000000000000000000..5753485a5870f6e2f6c37da1a35473df71b143b1 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_crc.c @@ -0,0 +1,127 @@ +/*! + \file gd32vf103_crc.c + \brief CRC driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_crc.h" + +#define CRC_DATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU) +#define CRC_FDATA_RESET_VALUE ((uint32_t)0x00000000U) + +/*! + \brief deinit CRC calculation unit + \param[in] none + \param[out] none + \retval none +*/ +void crc_deinit(void) +{ + CRC_DATA = CRC_DATA_RESET_VALUE; + CRC_FDATA = CRC_FDATA_RESET_VALUE; + CRC_CTL = (uint32_t)CRC_CTL_RST; +} + +/*! + \brief reset data register(CRC_DATA) to the value of 0xFFFFFFFF + \param[in] none + \param[out] none + \retval none +*/ +void crc_data_register_reset(void) +{ + CRC_CTL |= (uint32_t)CRC_CTL_RST; +} + +/*! + \brief read the value of 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 value of 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 data to the free data register + \param[in] free_data: specified 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 calculate the CRC value of a 32-bit data + \param[in] sdata: specified 32-bit data + \param[out] none + \retval 32-bit value calculated by CRC +*/ +uint32_t crc_single_data_calculate(uint32_t sdata) +{ + CRC_DATA = sdata; + return (CRC_DATA); +} + +/*! + \brief calculate the CRC value of an array of 32-bit values + \param[in] array: pointer to an array of 32-bit values + \param[in] size: size of the array + \param[out] none + \retval 32-bit value calculated by CRC +*/ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size) +{ + uint32_t index; + for(index = 0U; index < size; index++){ + CRC_DATA = array[index]; + } + return (CRC_DATA); +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_dac.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_dac.c new file mode 100644 index 0000000000000000000000000000000000000000..4ec51bf96001b780186e8134d9723edc8d1bdf89 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_dac.c @@ -0,0 +1,537 @@ +/*! + \file gd32vf103_dac.c + \brief DAC driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_dac.h" + +/* DAC register bit offset */ +#define DAC1_REG_OFFSET ((uint32_t)16U) +#define DH_12BIT_OFFSET ((uint32_t)16U) +#define DH_8BIT_OFFSET ((uint32_t)8U) + +/*! + \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] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DEN0; + }else{ + DAC_CTL |= DAC_CTL_DEN1; + } +} + +/*! + \brief disable DAC + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DEN0; + }else{ + DAC_CTL &= ~DAC_CTL_DEN1; + } +} + +/*! + \brief enable DAC DMA function + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_dma_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DDMAEN0; + }else{ + DAC_CTL |= DAC_CTL_DDMAEN1; + } +} + +/*! + \brief disable DAC DMA function + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_dma_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DDMAEN0; + }else{ + DAC_CTL &= ~DAC_CTL_DDMAEN1; + } +} + +/*! + \brief enable DAC output buffer + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_output_buffer_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DBOFF0; + }else{ + DAC_CTL &= ~DAC_CTL_DBOFF1; + } +} + +/*! + \brief disable DAC output buffer + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_output_buffer_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DBOFF0; + }else{ + DAC_CTL |= DAC_CTL_DBOFF1; + } +} + +/*! + \brief get DAC output value + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval DAC output data +*/ +uint16_t dac_output_value_get(uint32_t dac_periph) +{ + uint16_t data = 0U; + if(DAC0 == dac_periph){ + /* store the DAC0 output value */ + data = (uint16_t)DAC0_DO; + }else{ + /* store the DAC1 output value */ + data = (uint16_t)DAC1_DO; + } + return data; +} + +/*! + \brief set the DAC specified data holding register value + \param[in] dac_periph: DACx(x = 0,1) + \param[in] dac_align: data alignment + only one parameter can be selected which is shown as below: + \arg DAC_ALIGN_8B_R: data right 8 bit alignment + \arg DAC_ALIGN_12B_R: data right 12 bit alignment + \arg DAC_ALIGN_12B_L: data left 12 bit alignment + \param[in] data: data to be loaded + \param[out] none + \retval none +*/ +void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data) +{ + if(DAC0 == dac_periph){ + switch(dac_align){ + /* data right 12 bit alignment */ + case DAC_ALIGN_12B_R: + DAC0_R12DH = data; + break; + /* data left 12 bit alignment */ + case DAC_ALIGN_12B_L: + DAC0_L12DH = data; + break; + /* data right 8 bit alignment */ + case DAC_ALIGN_8B_R: + DAC0_R8DH = data; + break; + default: + break; + } + }else{ + switch(dac_align){ + /* data right 12 bit alignment */ + case DAC_ALIGN_12B_R: + DAC1_R12DH = data; + break; + /* data left 12 bit alignment */ + case DAC_ALIGN_12B_L: + DAC1_L12DH = data; + break; + /* data right 8 bit alignment */ + case DAC_ALIGN_8B_R: + DAC1_R8DH = data; + break; + default: + break; + } + } +} + +/*! + \brief enable DAC trigger + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_trigger_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DTEN0; + }else{ + DAC_CTL |= DAC_CTL_DTEN1; + } +} + +/*! + \brief disable DAC trigger + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_trigger_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DTEN0; + }else{ + DAC_CTL &= ~DAC_CTL_DTEN1; + } +} + +/*! + \brief set DAC trigger source + \param[in] dac_periph: DACx(x = 0,1) + \param[in] triggersource: external triggers of DAC + only one parameter can be selected which is shown as below: + \arg DAC_TRIGGER_T1_TRGO: TIMER1 TRGO + \arg DAC_TRIGGER_T2_TRGO: TIMER2 TRGO + \arg DAC_TRIGGER_T3_TRGO: TIMER3 TRGO + \arg DAC_TRIGGER_T4_TRGO: TIMER4 TRGO + \arg DAC_TRIGGER_T5_TRGO: TIMER5 TRGO + \arg DAC_TRIGGER_T6_TRGO: TIMER6 TRGO + \arg DAC_TRIGGER_EXTI_9: EXTI interrupt line9 event + \arg DAC_TRIGGER_SOFTWARE: software trigger + \param[out] none + \retval none +*/ +void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource) +{ + if(DAC0 == dac_periph){ + /* configure DAC0 trigger source */ + DAC_CTL &= ~DAC_CTL_DTSEL0; + DAC_CTL |= triggersource; + }else{ + /* configure DAC1 trigger source */ + DAC_CTL &= ~DAC_CTL_DTSEL1; + DAC_CTL |= (triggersource << DAC1_REG_OFFSET); + } +} + +/*! + \brief enable DAC software trigger + \param[in] dac_periph: DACx(x = 0,1) + \retval none +*/ +void dac_software_trigger_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_SWT |= DAC_SWT_SWTR0; + }else{ + DAC_SWT |= DAC_SWT_SWTR1; + } +} + +/*! + \brief disable DAC software trigger + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_software_trigger_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_SWT &= ~DAC_SWT_SWTR0; + }else{ + DAC_SWT &= ~DAC_SWT_SWTR1; + } +} + +/*! + \brief configure DAC wave mode + \param[in] dac_periph: DACx(x = 0,1) + \param[in] wave_mode: noise wave mode + only one parameter can be selected which is shown as below: + \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 dac_periph, uint32_t wave_mode) +{ + if(DAC0 == dac_periph){ + /* configure DAC0 wave mode */ + DAC_CTL &= ~DAC_CTL_DWM0; + DAC_CTL |= wave_mode; + }else{ + /* configure DAC1 wave mode */ + DAC_CTL &= ~DAC_CTL_DWM1; + DAC_CTL |= (wave_mode << DAC1_REG_OFFSET); + } +} + +/*! + \brief configure DAC wave bit width + \param[in] dac_periph: DACx(x = 0,1) + \param[in] bit_width: noise wave bit width + only one parameter can be selected which is shown as below: + \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 dac_periph, uint32_t bit_width) +{ + if(DAC0 == dac_periph){ + /* configure DAC0 wave bit width */ + DAC_CTL &= ~DAC_CTL_DWBW0; + DAC_CTL |= bit_width; + }else{ + /* configure DAC1 wave bit width */ + DAC_CTL &= ~DAC_CTL_DWBW1; + DAC_CTL |= (bit_width << DAC1_REG_OFFSET); + } +} + +/*! + \brief configure DAC LFSR noise mode + \param[in] dac_periph: DACx(x = 0,1) + \param[in] unmask_bits: unmask LFSR bits in DAC LFSR noise mode + only one parameter can be selected which is shown as below: + \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 dac_periph, uint32_t unmask_bits) +{ + if(DAC0 == dac_periph){ + /* configure DAC0 LFSR noise mode */ + DAC_CTL &= ~DAC_CTL_DWBW0; + DAC_CTL |= unmask_bits; + }else{ + /* configure DAC1 LFSR noise mode */ + DAC_CTL &= ~DAC_CTL_DWBW1; + DAC_CTL |= (unmask_bits << DAC1_REG_OFFSET); + } +} + +/*! + \brief configure DAC triangle noise mode + \param[in] dac_periph: DACx(x = 0,1) + \param[in] amplitude: triangle amplitude in DAC triangle noise mode + only one parameter can be selected which is shown as below: + \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 dac_periph, uint32_t amplitude) +{ + if(DAC0 == dac_periph){ + /* configure DAC0 triangle noise mode */ + DAC_CTL &= ~DAC_CTL_DWBW0; + DAC_CTL |= amplitude; + }else{ + /* configure DAC1 triangle noise mode */ + DAC_CTL &= ~DAC_CTL_DWBW1; + DAC_CTL |= (amplitude << DAC1_REG_OFFSET); + } +} + +/*! + \brief enable DAC concurrent mode + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1; + DAC_CTL |= (ctl); +} + +/*! + \brief disable DAC concurrent mode + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1; + DAC_CTL &= (~ctl); +} + +/*! + \brief enable DAC concurrent software trigger function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_enable(void) +{ + uint32_t swt = 0U; + swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; + DAC_SWT |= (swt); +} + +/*! + \brief disable DAC concurrent software trigger function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_disable(void) +{ + uint32_t swt = 0U; + swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; + DAC_SWT &= (~swt); +} + +/*! + \brief enable DAC concurrent buffer function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_output_buffer_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1; + DAC_CTL &= (~ctl); +} + +/*! + \brief disable DAC concurrent buffer function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_output_buffer_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1; + DAC_CTL |= (ctl); +} + +/*! + \brief set DAC concurrent mode data holding register value + \param[in] dac_align: data alignment + only one parameter can be selected which is shown as below: + \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] data0: data to be loaded + \param[in] data1: data to be loaded + \param[out] none + \retval none +*/ +void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1) +{ + uint32_t data = 0U; + switch(dac_align){ + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + data = ((uint32_t)data1 << DH_12BIT_OFFSET) | data0; + DACC_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + data = ((uint32_t)data1 << DH_12BIT_OFFSET) | data0; + DACC_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + data = ((uint32_t)data1 << DH_8BIT_OFFSET) | data0; + DACC_R8DH = data; + break; + default: + break; + } +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_dbg.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_dbg.c new file mode 100644 index 0000000000000000000000000000000000000000..2e0dfe5277fd7a09731493bd857324c9a701b5a0 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_dbg.c @@ -0,0 +1,110 @@ +/*! + \file gd32vf103_dbg.c + \brief DBG driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_dbg.h" + +/*! + \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_CTL |= 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_CTL &= ~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_FWDGT_HOLD : debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted + \arg DBG_CANx_HOLD (x=0,1): hold CANx counter when core is halted + \arg DBG_I2Cx_HOLD (x=0,1): hold I2Cx smbus when core is halted + \arg DBG_TIMERx_HOLD (x=0,1,2,3,4,5,6): hold TIMERx counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_enable(dbg_periph_enum dbg_periph) +{ + DBG_CTL |= (uint32_t)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_FWDGT_HOLD : debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted + \arg DBG_CANx_HOLD (x=0,1): hold CAN0 counter when core is halted + \arg DBG_I2Cx_HOLD (x=0,1): hold I2Cx smbus when core is halted + \arg DBG_TIMERx_HOLD (x=0,1,2,3,4,5,6): hold TIMERx counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_disable(dbg_periph_enum dbg_periph) +{ + DBG_CTL &= ~(uint32_t)dbg_periph; +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_dma.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..0d2c12c8fb560975be1a020dd24975953926d59c --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_dma.c @@ -0,0 +1,731 @@ +/*! + \file gd32vf103_dma.c + \brief DMA driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_dma.h" + +#define DMA_WRONG_HANDLE while(1){} + +/* check whether peripheral matches channels or not */ +static ErrStatus dma_periph_and_channel_check(uint32_t dma_periph, dma_channel_enum channelx); + +/*! + \brief deinitialize DMA a channel registers + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is deinitialized + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + /* disable DMA a channel */ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN; + /* reset DMA channel registers */ + DMA_CHCTL(dma_periph, channelx) = DMA_CHCTL_RESET_VALUE; + DMA_CHCNT(dma_periph, channelx) = DMA_CHCNT_RESET_VALUE; + DMA_CHPADDR(dma_periph, channelx) = DMA_CHPADDR_RESET_VALUE; + DMA_CHMADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_INTC(dma_periph) |= 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 = DMA_PERIPH_INCREASE_DISABLE; + init_struct->memory_addr = 0U; + init_struct->memory_width = 0U; + init_struct->memory_inc = DMA_MEMORY_INCREASE_DISABLE; + init_struct->number = 0U; + init_struct->direction = DMA_PERIPHERAL_TO_MEMORY; + init_struct->priority = DMA_PRIORITY_LOW; +} + +/*! + \brief initialize DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is initialized + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] init_struct: the data needed to initialize DMA channel + periph_addr: peripheral base address + periph_width: DMA_PERIPHERAL_WIDTH_8BIT, DMA_PERIPHERAL_WIDTH_16BIT, DMA_PERIPHERAL_WIDTH_32BIT + periph_inc: DMA_PERIPH_INCREASE_ENABLE, DMA_PERIPH_INCREASE_DISABLE + memory_addr: memory base address + memory_width: DMA_MEMORY_WIDTH_8BIT, DMA_MEMORY_WIDTH_16BIT, DMA_MEMORY_WIDTH_32BIT + memory_inc: DMA_MEMORY_INCREASE_ENABLE, DMA_MEMORY_INCREASE_DISABLE + direction: DMA_PERIPHERAL_TO_MEMORY, DMA_MEMORY_TO_PERIPHERAL + number: the number of remaining data to be transferred by the DMA + priority: DMA_PRIORITY_LOW, DMA_PRIORITY_MEDIUM, DMA_PRIORITY_HIGH, DMA_PRIORITY_ULTRA_HIGH + \param[out] none + \retval none +*/ +void dma_init(uint32_t dma_periph, dma_channel_enum channelx, dma_parameter_struct* init_struct) +{ + uint32_t ctl; + + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + /* configure peripheral base address */ + DMA_CHPADDR(dma_periph, channelx) = init_struct->periph_addr; + + /* configure memory base address */ + DMA_CHMADDR(dma_periph, channelx) = init_struct->memory_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(dma_periph, channelx) = (init_struct->number & DMA_CHANNEL_CNT_MASK); + + /* configure peripheral transfer width,memory transfer width and priority */ + ctl = DMA_CHCTL(dma_periph, 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(dma_periph, channelx) = ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc){ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + }else{ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc){ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA; + }else{ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure the direction of data transfer */ + if(DMA_PERIPHERAL_TO_MEMORY == init_struct->direction){ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_DIR; + }else{ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief enable DMA circulation mode + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN; +} + +/*! + \brief disable DMA circulation mode + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_circulation_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN; +} + +/*! + \brief enable memory to memory mode + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_M2M; +} + +/*! + \brief disable memory to memory mode + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_M2M; +} + +/*! + \brief enable DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CHEN; +} + +/*! + \brief disable DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN; +} + +/*! + \brief set DMA peripheral base address + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set peripheral base address + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] address: peripheral base address + \param[out] none + \retval none +*/ +void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHPADDR(dma_periph, channelx) = address; +} + +/*! + \brief set DMA memory base address + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set memory base address + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] address: memory base address + \param[out] none + \retval none +*/ +void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHMADDR(dma_periph, channelx) = address; +} + +/*! + \brief set the number of remaining data to be transferred by the DMA + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set number + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] number: the number of remaining data to be transferred by the DMA + \param[out] none + \retval none +*/ +void dma_transfer_number_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t number) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCNT(dma_periph, channelx) = (number & DMA_CHANNEL_CNT_MASK); +} + +/*! + \brief get the number of remaining data to be transferred by the DMA + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set number + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval uint32_t: the number of remaining data to be transferred by the DMA +*/ +uint32_t dma_transfer_number_get(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + return (uint32_t)DMA_CHCNT(dma_periph, channelx); +} + +/*! + \brief configure priority level of DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] priority: priority Level of this channel + only one parameter can be selected which is shown as below: + \arg DMA_PRIORITY_LOW: low priority + \arg DMA_PRIORITY_MEDIUM: medium priority + \arg DMA_PRIORITY_HIGH: high priority + \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority + \param[out] none + \retval none +*/ +void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t priority) +{ + uint32_t ctl; + + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PRIO; + ctl |= priority; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief configure transfer data size of memory + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] mwidth: transfer data width of memory + only one parameter can be selected which is shown as below: + \arg DMA_MEMORY_WIDTH_8BIT: transfer data width of memory is 8-bit + \arg DMA_MEMORY_WIDTH_16BIT: transfer data width of memory is 16-bit + \arg DMA_MEMORY_WIDTH_32BIT: transfer data width of memory is 32-bit + \param[out] none + \retval none +*/ +void dma_memory_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t mwidth) +{ + uint32_t ctl; + + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MWIDTH; + ctl |= mwidth; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief configure transfer data size of peripheral + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] pwidth: transfer data width of peripheral + only one parameter can be selected which is shown as below: + \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data width of peripheral is 8-bit + \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data width of peripheral is 16-bit + \arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data width of peripheral is 32-bit + \param[out] none + \retval none +*/ +void dma_periph_width_config (uint32_t dma_periph, dma_channel_enum channelx, uint32_t pwidth) +{ + uint32_t ctl; + + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PWIDTH; + ctl |= pwidth; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief enable next address increasement algorithm of memory + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_increase_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA; +} + +/*! + \brief disable next address increasement algorithm of memory + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_increase_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA; +} + +/*! + \brief enable next address increasement algorithm of peripheral + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_periph_increase_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; +} + +/*! + \brief disable next address increasement algorithm of peripheral + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_periph_increase_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA; +} + +/*! + \brief configure the direction of data transfer on the channel + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] direction: specify the direction of data transfer + only one parameter can be selected which is shown as below: + \arg DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory + \arg DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral + \param[out] none + \retval none +*/ +void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t direction) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + if(DMA_PERIPHERAL_TO_MEMORY == direction){ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_DIR; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief check DMA flag is set or not + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) +{ + FlagStatus reval; + + if(RESET != (DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx))){ + reval = SET; + }else{ + reval = RESET; + } + + return reval; +} + +/*! + \brief clear DMA a channel flag + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval none +*/ +void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx); +} + +/*! + \brief check DMA flag and interrupt enable bit is set or not + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_INT_FLAG_FTF: full transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_ERR: error interrupt flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) +{ + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + + switch(flag){ + case DMA_INT_FLAG_FTF: + /* check whether the full transfer finish interrupt flag is set and enabled */ + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE; + break; + case DMA_INT_FLAG_HTF: + /* check whether the half transfer finish interrupt flag is set and enabled */ + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INT_FLAG_ERR: + /* check whether the error interrupt flag is set and enabled */ + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_ERRIE; + break; + default: + DMA_WRONG_HANDLE + } + + /* when the interrupt flag is set and enabled, return SET */ + if(interrupt_flag && interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear DMA a channel flag + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_INT_FLAG_G: global interrupt flag of channel + \arg DMA_INT_FLAG_FTF: full transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_ERR: error interrupt flag of channel + \param[out] none + \retval none +*/ +void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx); +} + +/*! + \brief enable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] source: specify which interrupt to enbale + one or more parameters can be selected which are shown as below + \arg DMA_INT_FTF: channel full transfer finish interrupt + \arg DMA_INT_HTF: channel half transfer finish interrupt + \arg DMA_INT_ERR: channel error interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) |= source; +} + +/*! + \brief disable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4) + \param[in] source: specify which interrupt to disbale + one or more parameters can be selected which are shown as below + \arg DMA_INT_FTF: channel full transfer finish interrupt + \arg DMA_INT_HTF: channel half transfer finish interrupt + \arg DMA_INT_ERR: channel error interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source) +{ + if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){ + DMA_WRONG_HANDLE + } + + DMA_CHCTL(dma_periph, channelx) &= ~source; +} + +/*! + \brief check whether peripheral and channels match + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \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[out] none + \retval none +*/ +static ErrStatus dma_periph_and_channel_check(uint32_t dma_periph, dma_channel_enum channelx) +{ + ErrStatus val = SUCCESS; + + if(DMA1 == dma_periph){ + /* for DMA1, the channel is from DMA_CH0 to DMA_CH4 */ + if(channelx > DMA_CH4){ + val = ERROR; + } + } + + return val; +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_eclic.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_eclic.c new file mode 100644 index 0000000000000000000000000000000000000000..d4385d636347f3e4f3527a5429463c93ec3f2b59 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_eclic.c @@ -0,0 +1,99 @@ +/*! + \file gd32vf103_eclic.c + \brief ECLIC(Enhancement Core-Local Interrupt Controller) driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_eclic.h" +#include "riscv_encoding.h" + +#define REG_DBGMCU2 ((uint32_t)0xE0042008) +#define REG_DBGMCU2EN ((uint32_t)0xE004200C) + +/*! + \brief set the priority group + \param[in] prigroup: specify the priority group + \arg ECLIC_PRIGROUP_LEVEL0_PRIO4 + \arg ECLIC_PRIGROUP_LEVEL1_PRIO3 + \arg ECLIC_PRIGROUP_LEVEL2_PRIO2 + \arg ECLIC_PRIGROUP_LEVEL3_PRIO1 + \arg ECLIC_PRIGROUP_LEVEL4_PRIO0 + \param[out] none + \retval none +*/ +void eclic_priority_group_set(uint32_t prigroup) { + eclic_set_nlbits(prigroup); +} + +/*! + \brief enable the interrupt request + \param[in] source: interrupt request, detailed in IRQn_Type + \param[in] level: the level needed to set (maximum is 16) + \param[in] priority: the priority needed to set (maximum is 16) + \param[out] none + \retval none +*/ +void eclic_irq_enable(uint32_t source, uint8_t level, uint8_t priority) { + eclic_enable_interrupt(source); + eclic_set_int_level(source, level); + eclic_set_int_priority(source, priority); +} + +/*! + \brief disable the interrupt request + \param[in] source: interrupt request, detailed in IRQn_Type + \param[out] none + \retval none +*/ +void eclic_irq_disable(uint32_t source) { + eclic_disable_interrupt(source); +} + +/*! + \brief reset system + \param[in] none + \param[out] none + \retval none +*/ +void eclic_system_reset(void) { + REG32(REG_DBGMCU2EN) = 0x4b5a6978; + REG32(REG_DBGMCU2) = 0x1; +} + +/*! + \brief send event(SEV) + \param[in] none + \param[out] none + \retval none +*/ +void eclic_send_event(void) { + set_csr(0x812, 0x1); +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_exmc.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_exmc.c new file mode 100644 index 0000000000000000000000000000000000000000..d414e078e0ed7eef2f9169a912b5fed3b90a0168 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_exmc.c @@ -0,0 +1,164 @@ +/*! + \file gd32vf103_exmc.c + \brief EXMC driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_exmc.h" + +/* EXMC bank0 register reset value */ +#define BANK0_SNCTL0_REGION_RESET ((uint32_t)0x000030DAU) +#define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU) + +/* EXMC register bit offset */ +#define SNCTL_NRMUX_OFFSET ((uint32_t)1U) +#define SNCTL_WREN_OFFSET ((uint32_t)12U) +#define SNCTL_NRWTEN_OFFSET ((uint32_t)13U) +#define SNCTL_ASYNCWAIT_OFFSET ((uint32_t)15U) + +#define SNTCFG_AHLD_OFFSET ((uint32_t)4U) +#define SNTCFG_DSET_OFFSET ((uint32_t)8U) +#define SNTCFG_BUSLAT_OFFSET ((uint32_t)16U) + +/*! + \brief deinitialize EXMC NOR/SRAM region + \param[in] norsram_region: select the region of bank0 + \arg EXMC_BANK0_NORSRAM_REGIONx(x=0) + \param[out] none + \retval none +*/ +void exmc_norsram_deinit(uint32_t norsram_region) +{ + /* reset the registers */ + if(EXMC_BANK0_NORSRAM_REGION0 == norsram_region){ + EXMC_SNCTL(norsram_region) = BANK0_SNCTL0_REGION_RESET; + } + + EXMC_SNTCFG(norsram_region) = BANK0_SNTCFG_RESET; +} + +/*! + \brief initialize the structure exmc_norsram_parameter_struct + \param[in] none + \param[out] exmc_norsram_init_struct: the initialized structure exmc_norsram_parameter_struct pointer + \retval none +*/ +void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct) +{ + /* configure the structure with default value */ + exmc_norsram_init_struct->norsram_region = EXMC_BANK0_NORSRAM_REGION0; + exmc_norsram_init_struct->address_data_mux = ENABLE; + exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_SRAM; + exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_16B; + exmc_norsram_init_struct->nwait_polarity = EXMC_NWAIT_POLARITY_LOW; + exmc_norsram_init_struct->memory_write = ENABLE; + exmc_norsram_init_struct->nwait_signal = ENABLE; + exmc_norsram_init_struct->asyn_wait = DISABLE; + + /* read/write timing configure */ + exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime = 0xFU; + exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime = 0xFU; + exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime = 0xFFU; + exmc_norsram_init_struct->read_write_timing->bus_latency = 0xFU; +} + +/*! + \brief initialize EXMC NOR/SRAM region + \param[in] exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter + norsram_region: EXMC_BANK0_NORSRAM_REGIONx,x=0 + asyn_wait: ENABLE or DISABLE + nwait_signal: ENABLE or DISABLE + memory_write: ENABLE or DISABLE + nwait_polarity: EXMC_NWAIT_POLARITY_LOW,EXMC_NWAIT_POLARITY_HIGH + databus_width: EXMC_NOR_DATABUS_WIDTH_8B,EXMC_NOR_DATABUS_WIDTH_16B + memory_type: EXMC_MEMORY_TYPE_SRAM,EXMC_MEMORY_TYPE_PSRAM,EXMC_MEMORY_TYPE_NOR + address_data_mux: ENABLE + read_write_timing: structure exmc_norsram_timing_parameter_struct set the time + \param[out] none + \retval none +*/ +void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct) +{ + uint32_t snctl = 0x00000000U, sntcfg = 0x00000000U; + + /* get the register value */ + snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region); + + /* clear relative bits */ + snctl &= ((uint32_t)~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_NRWTPOL | + EXMC_SNCTL_WREN | EXMC_SNCTL_NRWTEN | EXMC_SNCTL_ASYNCWAIT | EXMC_SNCTL_NRMUX)); + + snctl |= (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) | + exmc_norsram_init_struct->memory_type | + exmc_norsram_init_struct->databus_width | + exmc_norsram_init_struct->nwait_polarity | + (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) | + (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) | + (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET); + + sntcfg = (uint32_t)((exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime - 1U ) & EXMC_SNTCFG_ASET )| + (((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U ) << SNTCFG_AHLD_OFFSET ) & EXMC_SNTCFG_AHLD ) | + (((exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime - 1U ) << SNTCFG_DSET_OFFSET ) & EXMC_SNTCFG_DSET ) | + (((exmc_norsram_init_struct->read_write_timing->bus_latency - 1U ) << SNTCFG_BUSLAT_OFFSET ) & EXMC_SNTCFG_BUSLAT ); + + /* nor flash access enable */ + if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type){ + snctl |= (uint32_t)EXMC_SNCTL_NREN; + } + + /* configure the registers */ + EXMC_SNCTL(exmc_norsram_init_struct->norsram_region) = snctl; + EXMC_SNTCFG(exmc_norsram_init_struct->norsram_region) = sntcfg; +} + +/*! + \brief enable EXMC NOR/PSRAM bank region + \param[in] norsram_region: specify the region of NOR/PSRAM bank + \arg EXMC_BANK0_NORSRAM_REGIONx(x=0) + \param[out] none + \retval none +*/ +void exmc_norsram_enable(uint32_t norsram_region) +{ + EXMC_SNCTL(norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN; +} + +/*! + \brief disable EXMC NOR/PSRAM bank region + \param[in] norsram_region: specify the region of NOR/PSRAM bank + \arg EXMC_BANK0_NORSRAM_REGIONx(x=0) + \param[out] none + \retval none +*/ +void exmc_norsram_disable(uint32_t norsram_region) +{ + EXMC_SNCTL(norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN; +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_exti.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_exti.c new file mode 100644 index 0000000000000000000000000000000000000000..4833b213bd357435605b74a0ec8bb71f7066229e --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_exti.c @@ -0,0 +1,252 @@ +/*! + \file gd32vf103_exti.c + \brief EXTI driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_exti.h" + +#define EXTI_REG_RESET_VALUE ((uint32_t)0x00000000U) + +/*! + \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 = EXTI_REG_RESET_VALUE; + EXTI_EVEN = EXTI_REG_RESET_VALUE; + EXTI_RTEN = EXTI_REG_RESET_VALUE; + EXTI_FTEN = EXTI_REG_RESET_VALUE; + EXTI_SWIEV = EXTI_REG_RESET_VALUE; +} + +/*! + \brief initialize the EXTI + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..18): 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: 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 edge trigger + \arg EXTI_TRIG_BOTH: rising edge and falling edge 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..18): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_enable(exti_line_enum linex) +{ + EXTI_INTEN |= (uint32_t) linex; +} + +/*! + \brief enable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..18): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_enable(exti_line_enum linex) +{ + EXTI_EVEN |= (uint32_t) linex; +} + +/*! + \brief disable the interrupt from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..18): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_disable(exti_line_enum linex) +{ + EXTI_INTEN &= ~(uint32_t) linex; +} + +/*! + \brief disable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..18): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_disable(exti_line_enum linex) +{ + EXTI_EVEN &= ~(uint32_t) linex; +} + +/*! + \brief get EXTI lines flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..18): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_flag_get(exti_line_enum linex) +{ + if (RESET != (EXTI_PD & (uint32_t) linex)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..18): EXTI line x + \param[out] none + \retval none +*/ +void exti_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t) linex; +} + +/*! + \brief get EXTI lines flag when the interrupt flag is set + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..18): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex) +{ + uint32_t flag_left, flag_right; + + flag_left = EXTI_PD & (uint32_t) linex; + flag_right = EXTI_INTEN & (uint32_t) linex; + + if ((RESET != flag_left) && (RESET != flag_right)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..18): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t) linex; +} + +/*! + \brief enable EXTI software interrupt event + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..18): 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..18): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_disable(exti_line_enum linex) +{ + EXTI_SWIEV &= ~(uint32_t) linex; +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_fmc.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_fmc.c new file mode 100644 index 0000000000000000000000000000000000000000..c219a7961772dbc88c222f2d3ad038b06ecdc35e --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_fmc.c @@ -0,0 +1,649 @@ +/*! + \file gd32vf103_fmc.c + \brief FMC driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_fmc.h" + +/*! + \brief set the wait state counter value + \param[in] wscntwait state counter value + \arg WS_WSCNT_0: FMC 0 wait state + \arg WS_WSCNT_1: FMC 1 wait state + \arg WS_WSCNT_2: FMC 2 wait state + \param[out] none + \retval none + */ +void fmc_wscnt_set(uint32_t wscnt) +{ + uint32_t reg; + + reg = FMC_WS; + /* set the wait state counter value */ + reg &= ~FMC_WS_WSCNT; + FMC_WS = (reg | wscnt); +} + +/*! + \brief unlock the main FMC operation + \param[in] none + \param[out] none + \retval none + */ +void fmc_unlock(void) +{ + if((RESET != (FMC_CTL0 & FMC_CTL0_LK))){ + /* write the FMC unlock key */ + FMC_KEY0 = UNLOCK_KEY0; + FMC_KEY0 = UNLOCK_KEY1; + } +} + +/*! + \brief lock the main FMC operation + \param[in] none + \param[out] none + \retval none + */ +void fmc_lock(void) +{ + /* set the LK bit */ + FMC_CTL0 |= FMC_CTL0_LK; +} + + +/*! + \brief FMC erase page + \param[in] page_address: the page address to be erased. + \param[out] none + \retval state of FMC, refer to fmc_state_enum + */ +fmc_state_enum fmc_page_erase(uint32_t page_address) +{ + fmc_state_enum fmc_state; + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + /* if the last operation is completed, start page erase */ + if (FMC_READY == fmc_state) { + FMC_CTL0 |= FMC_CTL0_PER; + FMC_ADDR0 = page_address; + FMC_CTL0 |= FMC_CTL0_START; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the PER bit */ + FMC_CTL0 &= ~FMC_CTL0_PER; + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief FMC erase whole chip + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + */ +fmc_state_enum fmc_mass_erase(void) +{ + fmc_state_enum fmc_state; + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start whole chip erase */ + FMC_CTL0 |= FMC_CTL0_MER; + FMC_CTL0 |= FMC_CTL0_START; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the MER bit */ + FMC_CTL0 &= ~FMC_CTL0_MER; + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief FMC program a word at the corresponding address + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval state of FMC, refer to fmc_state_enum + */ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) +{ + fmc_state_enum fmc_state = FMC_READY; + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL0 |= FMC_CTL0_PG; + REG32(address) = data; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the PG bit */ + FMC_CTL0 &= ~FMC_CTL0_PG; + } + /* return the FMC state */ + return fmc_state; +} +/* + \brief FMC program a half word at the corresponding address + \param[in] address: address to program + \param[in] data: halfword to program + \param[out] none + \retval state of FMC, refer to fmc_state_enum +*/ +fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data) +{ + fmc_state_enum fmc_state = FMC_READY; + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL0 |= FMC_CTL0_PG; + REG16(address) = data; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the PG bit */ + FMC_CTL0 &= ~FMC_CTL0_PG; + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief unlock the option byte operation + \param[in] none + \param[out] none + \retval none + */ +void ob_unlock(void) +{ + if(RESET == (FMC_CTL0 & FMC_CTL0_OBWEN)){ + /* write the FMC key */ + FMC_OBKEY = UNLOCK_KEY0; + FMC_OBKEY = UNLOCK_KEY1; + } + + /* wait until OBWEN bit is set by hardware */ + while (RESET == (FMC_CTL0 & FMC_CTL0_OBWEN)) { + } +} + +/*! + \brief lock the option byte operation + \param[in] none + \param[out] none + \retval none + */ +void ob_lock(void) +{ + /* reset the OBWEN bit */ + FMC_CTL0 &= ~FMC_CTL0_OBWEN; +} + +/*! + \brief erase the FMC option byte + unlock the FMC_CTL0 and option byte before calling this function + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + */ +fmc_state_enum ob_erase(void) +{ + uint16_t temp_spc = FMC_NSPC; + + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* check the option byte security protection value */ + if(RESET != ob_spc_get()){ + temp_spc = FMC_USPC; + } + + if(FMC_READY == fmc_state){ + + /* start erase the option byte */ + FMC_CTL0 |= FMC_CTL0_OBER; + FMC_CTL0 |= FMC_CTL0_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* reset the OBER bit */ + FMC_CTL0 &= ~FMC_CTL0_OBER; + /* set the OBPG bit */ + FMC_CTL0 |= FMC_CTL0_OBPG; + /* no security protection */ + OB_SPC = (uint16_t) temp_spc; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + if (FMC_TOERR != fmc_state) { + /* reset the OBPG bit */ + FMC_CTL0 &= ~FMC_CTL0_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL0 &= ~FMC_CTL0_OBPG; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief enable write protection + \param[in] ob_wp: specify sector to be write protected, set the bit to 1 if + you want to protect the corresponding pages. meanwhile, sector + macro could used to set specific sector write protected. + one or more parameters can be selected which are shown as below: + \arg OB_WPx(x = 0..31): write protect specify sector + \arg OB_WP_ALL: write protect all sector + \param[out] none + \retval state of FMC, refer to fmc_state_enum + */ +fmc_state_enum ob_write_protection_enable(uint32_t ob_wp) +{ + uint16_t temp_wp0, temp_wp1, temp_wp2, temp_wp3; + + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + ob_wp = (uint32_t) (~ob_wp); + temp_wp0 = (uint16_t) (ob_wp & OB_WP0_WP0); + temp_wp1 = (uint16_t) ((ob_wp & OB_WP1_WP1) >> 8U); + temp_wp2 = (uint16_t) ((ob_wp & OB_WP2_WP2) >> 16U); + temp_wp3 = (uint16_t) ((ob_wp & OB_WP3_WP3) >> 24U); + + if(FMC_READY == fmc_state){ + + /* set the OBPG bit*/ + FMC_CTL0 |= FMC_CTL0_OBPG; + + if(0xFFU != temp_wp0){ + OB_WP0 = temp_wp0; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + if((FMC_READY == fmc_state) && (0xFFU != temp_wp1)){ + OB_WP1 = temp_wp1; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + if((FMC_READY == fmc_state) && (0xFFU != temp_wp2)){ + OB_WP2 = temp_wp2; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + if((FMC_READY == fmc_state) && (0xFFU != temp_wp3)){ + OB_WP3 = temp_wp3; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL0 &= ~FMC_CTL0_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure security protection + \param[in] ob_spc: specify security protection + only one parameter can be selected which is shown as below: + \arg FMC_NSPC: no security protection + \arg FMC_USPC: under security protection + \param[out] none + \retval state of FMC, refer to fmc_state_enum + */ +fmc_state_enum ob_security_protection_config(uint8_t ob_spc) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + FMC_CTL0 |= FMC_CTL0_OBER; + FMC_CTL0 |= FMC_CTL0_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* reset the OBER bit */ + FMC_CTL0 &= ~FMC_CTL0_OBER; + + /* start the option byte program */ + FMC_CTL0 |= FMC_CTL0_OBPG; + + OB_SPC = (uint16_t) ob_spc; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if (FMC_TOERR != fmc_state) { + /* reset the OBPG bit */ + FMC_CTL0 &= ~FMC_CTL0_OBPG; + } + }else{ + if (FMC_TOERR != fmc_state) { + /* reset the OBER bit */ + FMC_CTL0 &= ~FMC_CTL0_OBER; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC user option byte + \param[in] ob_fwdgt: option byte watchdog value + \arg OB_FWDGT_SW: software free watchdog + \arg OB_FWDGT_HW: hardware free watchdog + \param[in] ob_deepsleep: option byte deepsleep reset value + \arg OB_DEEPSLEEP_NRST: no reset when entering deepsleep mode + \arg OB_DEEPSLEEP_RST: generate a reset instead of entering deepsleep mode + \param[in] ob_stdby:option byte standby reset value + \arg OB_STDBY_NRST: no reset when entering standby mode + \arg OB_STDBY_RST: generate a reset instead of entering standby mode + \param[in] ob_boot: specifies the option byte boot bank value + \arg OB_BOOT_B0: boot from bank0 + \param[out] none + \retval state of FMC, refer to fmc_state_enum + */ +fmc_state_enum ob_user_write(uint8_t ob_fwdgt, uint8_t ob_deepsleep, uint8_t ob_stdby, uint8_t ob_boot) +{ + fmc_state_enum fmc_state = FMC_READY; + uint8_t temp; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the OBPG bit*/ + FMC_CTL0 |= FMC_CTL0_OBPG; + + temp = ((uint8_t)((uint8_t)((uint8_t)(ob_boot | ob_fwdgt) | ob_deepsleep) | ob_stdby) | OB_USER_MASK); + OB_USER = (uint16_t) temp; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL0 &= ~FMC_CTL0_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program option bytes data + \param[in] address: the option bytes address to be programmed + \param[in] data: the byte to be programmed + \param[out] none + \retval state of FMC, refer to fmc_state_enum + */ +fmc_state_enum ob_data_program(uint32_t address, uint8_t data) { + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the OBPG bit */ + FMC_CTL0 |= FMC_CTL0_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_CTL0 &= ~FMC_CTL0_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief get the FMC user option byte + \param[in] none + \param[out] none + \retval the FMC user option byte values + */ +uint8_t ob_user_get(void) +{ + /* return the FMC user option byte value */ + return (uint8_t) (FMC_OBSTAT >> 2U); +} + +/*! + \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 >> 10U); +} + +/*! + \brief get the FMC option byte write protection + \param[in] none + \param[out] none + \retval the FMC write protection option byte value + */ +uint32_t ob_write_protection_get(void) +{ + /* return the FMC write protection option byte value */ + return FMC_WP; +} + +/*! + \brief get the FMC option byte security protection + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET + */ +FlagStatus ob_spc_get(void) +{ + FlagStatus spc_state = RESET; + + if(RESET != (FMC_OBSTAT & FMC_OBSTAT_SPC)){ + spc_state = SET; + }else{ + spc_state = RESET; + } + return spc_state; +} + +/*! + \brief enable FMC interrupt + \param[in] interrupt: the FMC interrupt source + only one parameter can be selected which is shown as below: + \arg FMC_INT_END: enable FMC end of program interrupt + \arg FMC_INT_ERR: enable FMC error interrupt + \param[out] none + \retval none + */ +void fmc_interrupt_enable(uint32_t interrupt) +{ + FMC_REG_VAL(interrupt) |= BIT(FMC_BIT_POS(interrupt)); +} + +/*! + \brief disable FMC interrupt + \param[in] interrupt: the FMC interrupt source + only one parameter can be selected which is shown as below: + \arg FMC_INT_END: enable FMC end of program interrupt + \arg FMC_INT_ERR: enable FMC error interrupt + \param[out] none + \retval none + */ +void fmc_interrupt_disable(uint32_t interrupt) +{ + FMC_REG_VAL(interrupt) &= ~BIT(FMC_BIT_POS(interrupt)); +} + +/*! + \brief check flag is set or not + \param[in] flag: check FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_BUSY: FMC busy flag bit + \arg FMC_FLAG_PGERR: FMC operation error flag bit + \arg FMC_FLAG_WPERR: FMC erase/program protection error flag bit + \arg FMC_FLAG_END: FMC end of operation flag bit + \arg FMC_FLAG_OBERR: FMC option bytes read error flag bit + \param[out] none + \retval FlagStatus: SET or RESET + */ +FlagStatus fmc_flag_get(uint32_t flag) +{ + if(RESET != (FMC_REG_VAL(flag) & BIT(FMC_BIT_POS(flag)))){ + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear the FMC flag + \param[in] flag: clear FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_PGERR: FMC operation error flag bit + \arg FMC_FLAG_WPERR: FMC erase/program protection error flag bit + \arg FMC_FLAG_END: FMC end of operation flag bit + \param[out] none + \retval none + */ +void fmc_flag_clear(uint32_t flag) +{ + FMC_REG_VAL(flag) = (!FMC_REG_VAL(flag)) | BIT(FMC_BIT_POS(flag)); +} + +/*! + \brief get FMC interrupt flag state + \param[in] flag: FMC interrupt flags, refer to fmc_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg FMC_INT_FLAG_PGERR: FMC operation error interrupt flag bit + \arg FMC_INT_FLAG_WPERR: FMC erase/program protection error interrupt flag bit + \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag bit + \param[out] none + \retval FlagStatus: SET or RESET + */ +FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum flag) +{ + FlagStatus ret1 = RESET; + FlagStatus ret2 = RESET; + + if(FMC_STAT0_REG_OFFSET == FMC_REG_OFFSET_GET(flag)){ + /* get the staus of interrupt flag */ + ret1 = (FlagStatus) (FMC_REG_VALS(flag) & BIT(FMC_BIT_POS0(flag))); + /* get the staus of interrupt enale bit */ + ret2 = (FlagStatus) (FMC_CTL0 & BIT(FMC_BIT_POS1(flag))); + } + + if(ret1 && ret2){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear FMC interrupt flag state + \param[in] flag: FMC interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg FMC_INT_FLAG_PGERR: FMC operation error interrupt flag bit + \arg FMC_INT_FLAG_WPERR: FMC erase/program protection error interrupt flag bit + \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag bit + \param[out] none + \retval none + */ +void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum flag) +{ + FMC_REG_VALS(flag) |= BIT(FMC_BIT_POS0(flag)); +} + +/*! + \brief get the FMC state + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + */ +fmc_state_enum fmc_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((uint32_t) 0x00U != (FMC_STAT0 & FMC_STAT0_BUSY)){ + fmc_state = FMC_BUSY; + }else{ + if((uint32_t) 0x00U != (FMC_STAT0 & FMC_STAT0_WPERR)){ + fmc_state = FMC_WPERR; + }else{ + if((uint32_t) 0x00U != (FMC_STAT0 & (FMC_STAT0_PGERR))){ + fmc_state = FMC_PGERR; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC is ready or not + \param[in] timeout: count of loop + \param[out] none + \retval state of FMC, refer to fmc_state_enum + */ +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) && (0x00U != timeout)); + + if(FMC_BUSY == fmc_state){ + fmc_state = FMC_TOERR; + } + /* return the FMC state */ + return fmc_state; +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_fwdgt.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_fwdgt.c new file mode 100644 index 0000000000000000000000000000000000000000..c0f2a38e836ddd84e4a24b65a21baa3c03418e68 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_fwdgt.c @@ -0,0 +1,151 @@ +/*! + \file gd32vf103_fwdgt.c + \brief FWDGT driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_fwdgt.h" + +/* write value to FWDGT_CTL_CMD bit field */ +#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) +/* write value to FWDGT_RLD_RLD bit field */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +/*! + \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 and FWDGT_RLD + \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 reload the counter of FWDGT + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_counter_reload(void) +{ + FWDGT_CTL = FWDGT_KEY_RELOAD; +} + +/*! + \brief configure counter reload value, and prescaler divider value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[in] prescaler_div: FWDGT prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC,and FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if((uint32_t)RESET != flag_status){ + return ERROR; + } + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_div; + + timeout = FWDGT_RLD_TIMEOUT; + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if((uint32_t)RESET != flag_status){ + return ERROR; + } + FWDGT_RLD = RLD_RLD(reload_value); + /* reload the counter */ + FWDGT_CTL = FWDGT_KEY_RELOAD; + + return SUCCESS; +} + +/*! + \brief get flag state of FWDGT + \param[in] flag: flag to get + only one parameter can be selected which is shown as below: + \arg FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going + \arg FWDGT_FLAG_RUD: a write operation to FWDGT_RLD register is on going + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fwdgt_flag_get(uint16_t flag) +{ + if(FWDGT_STAT & flag){ + return SET; + } + + return RESET; +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_gpio.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..cc0fd3f644b1904a0e18bf219414ea3f9d622220 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_gpio.c @@ -0,0 +1,503 @@ +/*! + \file gd32vf103_gpio.c + \brief GPIO driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_gpio.h" + +#define AFIO_EXTI_SOURCE_MASK ((uint8_t)0x03U) /*!< AFIO exti source selection mask*/ +#define AFIO_EXTI_SOURCE_FIELDS ((uint8_t)0x04U) /*!< select AFIO exti source registers */ +#define LSB_16BIT_MASK ((uint16_t)0xFFFFU) /*!< LSB 16-bit mask */ +#define PCF_POSITION_MASK ((uint32_t)0x000F0000U) /*!< AFIO_PCF register position mask */ +#define PCF_SWJCFG_MASK ((uint32_t)0xF0FFFFFFU) /*!< AFIO_PCF register SWJCFG mask */ +#define PCF_LOCATION1_MASK ((uint32_t)0x00200000U) /*!< AFIO_PCF register location1 mask */ +#define PCF_LOCATION2_MASK ((uint32_t)0x00100000U) /*!< AFIO_PCF register location2 mask */ +#define AFIO_PCF1_FIELDS ((uint32_t)0x80000000U) /*!< select AFIO_PCF1 register */ +#define GPIO_OUTPUT_PORT_OFFSET ((uint32_t)4U) /*!< GPIO event output port offset*/ + +/*! + \brief reset GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E) + \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 GPIOE: + /* reset GPIOE */ + rcu_periph_reset_enable(RCU_GPIOERST); + rcu_periph_reset_disable(RCU_GPIOERST); + break; + default: + break; + } +} + +/*! + \brief reset alternate function I/O(AFIO) + \param[in] none + \param[out] none + \retval none +*/ +void gpio_afio_deinit(void) +{ + rcu_periph_reset_enable(RCU_AFRST); + rcu_periph_reset_disable(RCU_AFRST); +} + +/*! + \brief GPIO parameter initialization + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E) + \param[in] mode: gpio pin mode + only one parameter can be selected which is shown as below: + \arg GPIO_MODE_AIN: analog input mode + \arg GPIO_MODE_IN_FLOATING: floating input mode + \arg GPIO_MODE_IPD: pull-down input mode + \arg GPIO_MODE_IPU: pull-up input mode + \arg GPIO_MODE_OUT_OD: GPIO output with open-drain + \arg GPIO_MODE_OUT_PP: GPIO output with push-pull + \arg GPIO_MODE_AF_OD: AFIO output with open-drain + \arg GPIO_MODE_AF_PP: AFIO output with push-pull + \param[in] speed: gpio output max speed value + only one parameter can be selected which is shown as below: + \arg GPIO_OSPEED_10MHZ: output max speed 10MHz + \arg GPIO_OSPEED_2MHZ: output max speed 2MHz + \arg GPIO_OSPEED_50MHZ: output max speed 50MHz + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + + \param[out] none + \retval none +*/ +void gpio_init(uint32_t gpio_periph, uint32_t mode, uint32_t speed, + uint32_t pin) +{ + uint16_t i; + uint32_t temp_mode = 0U; + uint32_t reg = 0U; + + /* GPIO mode configuration */ + temp_mode = (uint32_t) (mode & ((uint32_t) 0x0FU)); + + /* GPIO speed configuration */ + if (((uint32_t) 0x00U) != ((uint32_t) mode & ((uint32_t) 0x10U))) { + /* output mode max speed:10MHz,2MHz,50MHz */ + temp_mode |= (uint32_t) speed; + } + + /* configure the eight low port pins with GPIO_CTL0 */ + for (i = 0U; i < 8U; i++) { + if ((1U << i) & pin) { + reg = GPIO_CTL0(gpio_periph); + + /* clear the specified pin mode bits */ + reg &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + reg |= GPIO_MODE_SET(i, temp_mode); + + /* set IPD or IPU */ + if (GPIO_MODE_IPD == mode) { + /* reset the corresponding OCTL bit */ + GPIO_BC(gpio_periph) = (uint32_t) ((1U << i) & pin); + } else { + /* set the corresponding OCTL bit */ + if (GPIO_MODE_IPU == mode) { + GPIO_BOP(gpio_periph) = (uint32_t) ((1U << i) & pin); + } + } + /* set GPIO_CTL0 register */ + GPIO_CTL0(gpio_periph) = reg; + } + } + /* configure the eight high port pins with GPIO_CTL1 */ + for (i = 8U; i < 16U; i++) { + if ((1U << i) & pin) { + reg = GPIO_CTL1(gpio_periph); + + /* clear the specified pin mode bits */ + reg &= ~GPIO_MODE_MASK(i - 8U); + /* set the specified pin mode bits */ + reg |= GPIO_MODE_SET(i - 8U, temp_mode); + + /* set IPD or IPU */ + if (GPIO_MODE_IPD == mode) { + /* reset the corresponding OCTL bit */ + GPIO_BC(gpio_periph) = (uint32_t) ((1U << i) & pin); + } else { + /* set the corresponding OCTL bit */ + if (GPIO_MODE_IPU == mode) { + GPIO_BOP(gpio_periph) = (uint32_t) ((1U << i) & pin); + } + } + /* set GPIO_CTL1 register */ + GPIO_CTL1(gpio_periph) = reg; + } + } +} + +/*! + \brief set GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E) + \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 + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E) + \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,E) + \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,E) + \param[in] data: specify the value to be written to the port output data 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,E) + \param[in] pin: GPIO pin + only one parameter can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval input status of gpio pin: 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 port input status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E) + \param[out] none + \retval input status 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,E) + \param[in] pin: GPIO pin + only one parameter can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval output status of gpio pin: 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 port output status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E) + \param[out] none + \retval output status of gpio all pins +*/ +uint16_t gpio_output_port_get(uint32_t gpio_periph) +{ + return ((uint16_t) GPIO_OCTL(gpio_periph)); +} + +/*! + \brief configure GPIO pin remap + \param[in] gpio_remap: select the pin to remap + only one parameter can be selected which are shown as below: + \arg GPIO_SPI0_REMAP: SPI0 remapping + \arg GPIO_I2C0_REMAP: I2C0 remapping + \arg GPIO_USART0_REMAP: USART0 remapping + \arg GPIO_USART1_REMAP: USART1 remapping + \arg GPIO_USART2_PARTIAL_REMAP: USART2 partial remapping + \arg GPIO_USART2_FULL_REMAP: USART2 full remapping + \arg GPIO_TIMER0_PARTIAL_REMAP: TIMER0 partial remapping + \arg GPIO_TIMER0_FULL_REMAP: TIMER0 full remapping + \arg GPIO_TIMER1_PARTIAL_REMAP0: TIMER1 partial remapping + \arg GPIO_TIMER1_PARTIAL_REMAP1: TIMER1 partial remapping + \arg GPIO_TIMER1_FULL_REMAP: TIMER1 full remapping + \arg GPIO_TIMER2_PARTIAL_REMAP: TIMER2 partial remapping + \arg GPIO_TIMER2_FULL_REMAP: TIMER2 full remapping + \arg GPIO_TIMER3_REMAP: TIMER3 remapping + \arg GPIO_CAN0_PARTIAL_REMAP: CAN0 partial remapping + \arg GPIO_CAN0_FULL_REMAP: CAN0 full remapping + \arg GPIO_PD01_REMAP: PD01 remapping + \arg GPIO_TIMER4CH3_IREMAP: TIMER4 channel3 internal remapping + \arg GPIO_CAN1_REMAP: CAN1 remapping + \arg GPIO_SWJ_NONJTRST_REMAP: full SWJ(JTAG-DP),but without NJTRST + \arg GPIO_SWJ_SWDPENABLE_REMAP: JTAG-DP disabled and SW-DP enabled + \arg GPIO_SWJ_DISABLE_REMAP: JTAG-DP disabled and SW-DP disabled + \arg GPIO_SPI2_REMAP: SPI2 remapping + \arg GPIO_TIMER1ITI1_REMAP: TIMER1 internal trigger 1 remapping + \arg GPIO_EXMC_NADV_REMAP: EXMC_NADV connect/disconnect + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void gpio_pin_remap_config(uint32_t remap, ControlStatus newvalue) +{ + uint32_t remap1 = 0U, remap2 = 0U, temp_reg = 0U, temp_mask = 0U; + + if (AFIO_PCF1_FIELDS == (remap & AFIO_PCF1_FIELDS)) { + /* get AFIO_PCF1 regiter value */ + temp_reg = AFIO_PCF1; + } else { + /* get AFIO_PCF0 regiter value */ + temp_reg = AFIO_PCF0; + } + + temp_mask = (remap & PCF_POSITION_MASK) >> 0x10U; + remap1 = remap & LSB_16BIT_MASK; + + /* judge pin remap type */ + if ((PCF_LOCATION1_MASK | PCF_LOCATION2_MASK) + == (remap & (PCF_LOCATION1_MASK | PCF_LOCATION2_MASK))) { + temp_reg &= PCF_SWJCFG_MASK; + AFIO_PCF0 &= PCF_SWJCFG_MASK; + } else if (PCF_LOCATION2_MASK == (remap & PCF_LOCATION2_MASK)) { + remap2 = ((uint32_t) 0x03U) << temp_mask; + temp_reg &= ~remap2; + temp_reg |= ~PCF_SWJCFG_MASK; + } else { + temp_reg &= ~(remap1 << ((remap >> 0x15U) * 0x10U)); + temp_reg |= ~PCF_SWJCFG_MASK; + } + + /* set pin remap value */ + if (DISABLE != newvalue) { + temp_reg |= (remap1 << ((remap >> 0x15U) * 0x10U)); + } + + if (AFIO_PCF1_FIELDS == (remap & AFIO_PCF1_FIELDS)) { + /* set AFIO_PCF1 regiter value */ + AFIO_PCF1 = temp_reg; + } else { + /* set AFIO_PCF0 regiter value */ + AFIO_PCF0 = temp_reg; + } +} + +/*! + \brief select GPIO pin exti sources + \param[in] gpio_outputport: gpio event output port + only one parameter can be selected which are shown as below: + \arg GPIO_PORT_SOURCE_GPIOA: output port source A + \arg GPIO_PORT_SOURCE_GPIOB: output port source B + \arg GPIO_PORT_SOURCE_GPIOC: output port source C + \arg GPIO_PORT_SOURCE_GPIOD: output port source D + \arg GPIO_PORT_SOURCE_GPIOE: output port source E + \param[in] gpio_outputpin: GPIO_PIN_SOURCE_x(x=0..15) + \param[out] none + \retval none +*/ +void gpio_exti_source_select(uint8_t output_port, uint8_t output_pin) +{ + uint32_t source = 0U; + source = ((uint32_t) 0x0FU) + << (AFIO_EXTI_SOURCE_FIELDS * (output_pin & AFIO_EXTI_SOURCE_MASK)); + + /* select EXTI sources */ + if (GPIO_PIN_SOURCE_4 > output_pin) { + /* select EXTI0/EXTI1/EXTI2/EXTI3 */ + AFIO_EXTISS0 &= ~source; + AFIO_EXTISS0 |= (((uint32_t) output_port) + << (AFIO_EXTI_SOURCE_FIELDS + * (output_pin & AFIO_EXTI_SOURCE_MASK))); + } else if (GPIO_PIN_SOURCE_8 > output_pin) { + /* select EXTI4/EXTI5/EXTI6/EXTI7 */ + AFIO_EXTISS1 &= ~source; + AFIO_EXTISS1 |= (((uint32_t) output_port) + << (AFIO_EXTI_SOURCE_FIELDS + * (output_pin & AFIO_EXTI_SOURCE_MASK))); + } else if (GPIO_PIN_SOURCE_12 > output_pin) { + /* select EXTI8/EXTI9/EXTI10/EXTI11 */ + AFIO_EXTISS2 &= ~source; + AFIO_EXTISS2 |= (((uint32_t) output_port) + << (AFIO_EXTI_SOURCE_FIELDS + * (output_pin & AFIO_EXTI_SOURCE_MASK))); + } else { + /* select EXTI12/EXTI13/EXTI14/EXTI15 */ + AFIO_EXTISS3 &= ~source; + AFIO_EXTISS3 |= (((uint32_t) output_port) + << (AFIO_EXTI_SOURCE_FIELDS + * (output_pin & AFIO_EXTI_SOURCE_MASK))); + } +} + +/*! + \brief configure GPIO pin event output + \param[in] output_port: gpio event output port + only one parameter can be selected which are shown as below: + \arg GPIO_EVENT_PORT_GPIOA: event output port A + \arg GPIO_EVENT_PORT_GPIOB: event output port B + \arg GPIO_EVENT_PORT_GPIOC: event output port C + \arg GPIO_EVENT_PORT_GPIOD: event output port D + \arg GPIO_EVENT_PORT_GPIOE: event output port E + \param[in] output_pin: + only one parameter can be selected which are shown as below: + \arg GPIO_EVENT_PIN_x(x=0..15) + \param[out] none + \retval none +*/ +void gpio_event_output_config(uint8_t output_port, uint8_t output_pin) +{ + uint32_t reg = 0U; + reg = AFIO_EC; + + /* clear AFIO_EC_PORT and AFIO_EC_PIN bits */ + reg &= (uint32_t) (~(AFIO_EC_PORT | AFIO_EC_PIN)); + + reg |= (uint32_t) ((uint32_t) output_port << GPIO_OUTPUT_PORT_OFFSET); + reg |= (uint32_t) output_pin; + + AFIO_EC = reg; +} + +/*! + \brief enable GPIO pin event output + \param[in] none + \param[out] none + \retval none +*/ +void gpio_event_output_enable(void) +{ + AFIO_EC |= AFIO_EC_EOE; +} + +/*! + \brief disable GPIO pin event output + \param[in] none + \param[out] none + \retval none +*/ +void gpio_event_output_disable(void) +{ + AFIO_EC &= (uint32_t) (~AFIO_EC_EOE); +} + +/*! + \brief lock GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E) + \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); +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_i2c.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..1e6ab305c62da56dae9c354561de8b845608f642 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_i2c.c @@ -0,0 +1,726 @@ +/*! + \file gd32vf103_i2c.c + \brief I2C driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_i2c.h" + +/* I2C register bit mask */ +#define I2CCLK_MAX ((uint32_t)0x00000048U) /*!< 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) + \param[in] dutycyc: duty cycle in fast mode + 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 { + } +} + +/*! + \brief configure I2C address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] mode: + only one parameter can be selected which is shown as below: + \arg I2C_I2CMODE_ENABLE: I2C mode + \arg I2C_SMBUSMODE_ENABLE: SMBus mode + \param[in] addformat: 7bits or 10bits + only one parameter can be selected which is shown as below: + \arg I2C_ADDFORMAT_7BITS: 7bits + \arg I2C_ADDFORMAT_10BITS: 10bits + \param[in] addr: I2C address + \param[out] none + \retval none + */ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode,uint32_t addformat, uint32_t addr) +{ + /* SMBus/I2C mode selected */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SMBEN); + ctl |= mode; + I2C_CTL0(i2c_periph) = ctl; + /* configure address */ + addr = addr & I2C_ADDRESS_MASK; + I2C_SADDR0(i2c_periph) = (addformat | addr); +} + +/*! + \brief SMBus type selection + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] type: + only one parameter can be selected which is shown as below: + \arg I2C_SMBUS_DEVICE: device + \arg I2C_SMBUS_HOST: host + \param[out] none + \retval none + */ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type) +{ + if (I2C_SMBUS_HOST == type) { + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL; + } else { + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL); + } +} + +/*! + \brief whether or not to send an ACK + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] ack: + only one parameter can be selected which is shown as below: + \arg I2C_ACK_ENABLE: ACK will be sent + \arg I2C_ACK_DISABLE: ACK will not be sent + \param[out] none + \retval none + */ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack) +{ + if (I2C_ACK_ENABLE == ack) { + I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN; + } else { + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN); + } +} + +/*! + \brief configure I2C POAP position + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] pos: + only one parameter can be selected which is shown as below: + \arg I2C_ACKPOS_CURRENT: whether to send ACK or not for the current + \arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte + \param[out] none + \retval none + */ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos) +{ + /* configure I2C POAP position */ + if (I2C_ACKPOS_NEXT == pos) { + I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP; + } else { + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP); + } +} + +/*! + \brief master sends slave address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] addr: slave address + \param[in] trandirection: transmitter or receiver + only one parameter can be selected which is shown as below: + \arg I2C_TRANSMITTER: transmitter + \arg I2C_RECEIVER: receiver + \param[out] none + \retval none + */ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr,uint32_t trandirection) +{ + /* master is a transmitter or a receiver */ + if (I2C_TRANSMITTER == trandirection) { + addr = addr & I2C_TRANSMITTER; + } else { + addr = addr | I2C_RECEIVER; + } + /* send slave address */ + I2C_DATA(i2c_periph) = addr; +} + +/*! + \brief configure I2C saddress1 + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] addr: I2C address + \param[out] none + \retval none +*/ +void i2c_saddr1_config(uint32_t i2c_periph,uint32_t addr) +{ + /* configure saddress1 */ + I2C_SADDR1(i2c_periph) = (0xFE & addr); +} + +/*! + \brief enable dual-address mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] addr: the second address in dual-address mode + \param[out] none + \retval none +*/ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr) +{ + /* configure address */ + addr = addr & I2C_ADDRESS2_MASK; + I2C_SADDR1(i2c_periph) = (I2C_SADDR1_DUADEN | addr); +} + +/*! + \brief disable dual-address mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_dualaddr_disable(uint32_t i2c_periph) +{ + I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN); +} + +/*! + \brief enable I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none + */ +void i2c_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN; +} + +/*! + \brief disable I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none + */ +void i2c_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_I2CEN); +} + +/*! + \brief generate a START condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none + */ +void i2c_start_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_START; +} + +/*! + \brief generate a STOP condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none + */ +void i2c_stop_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP; +} + +/*! + \brief I2C transmit data function + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] data: data of transmission + \param[out] none + \retval none + */ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data) +{ + I2C_DATA(i2c_periph) = DATA_TRANS(data); +} + +/*! + \brief I2C receive data function + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval data of received + */ +uint8_t i2c_data_receive(uint32_t i2c_periph) +{ + return (uint8_t) DATA_RECV(I2C_DATA(i2c_periph)); +} + +/*! + \brief enable I2C DMA mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] dmastate: + only one parameter can be selected which is shown as below: + \arg I2C_DMA_ON: DMA mode enable + \arg I2C_DMA_OFF: DMA mode disable + \param[out] none + \retval none + */ +void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate) +{ + /* configure I2C DMA function */ + uint32_t ctl = 0U; + + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMAON); + ctl |= dmastate; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief configure whether next DMA EOT is DMA last transfer or not + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] dmalast: + only one parameter can be selected which is shown as below: + \arg I2C_DMALST_ON: next DMA EOT is the last transfer + \arg I2C_DMALST_OFF: next DMA EOT is not the last transfer + \param[out] none + \retval none + */ +void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast) +{ + /* configure DMA last transfer */ + uint32_t ctl = 0U; + + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMALST); + ctl |= dmalast; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief whether to stretch SCL low when data is not ready in slave mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] stretchpara: + only one parameter can be selected which is shown as below: + \arg I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled + \arg I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled + \param[out] none + \retval none + */ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara) +{ + /* configure I2C SCL strerching enable or disable */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SS); + ctl |= stretchpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief whether or not to response to a general call + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] gcallpara: + only one parameter can be selected which is shown as below: + \arg I2C_GCEN_ENABLE: slave will response to a general call + \arg I2C_GCEN_DISABLE: slave will not response to a general call + \param[out] none + \retval none + */ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara) +{ + /* configure slave response to a general call enable or disable */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_GCEN); + ctl |= gcallpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief software reset I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] sreset: + only one parameter can be selected which is shown as below: + \arg I2C_SRESET_SET: I2C is under reset + \arg I2C_SRESET_RESET: I2C is not under reset + \param[out] none + \retval none + */ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset) +{ + /* modify CTL0 and configure software reset I2C state */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SRESET); + ctl |= sreset; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief I2C PEC calculation on or off + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] pecpara: + only one parameter can be selected which is shown as below: + \arg I2C_PEC_ENABLE: PEC calculation on + \arg I2C_PEC_DISABLE: PEC calculation off + \param[out] none + \retval none + */ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate) +{ + /* on/off PEC calculation */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECEN); + ctl |= pecstate; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief I2C whether to transfer PEC value + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] pecpara: + only one parameter can be selected which is shown as below: + \arg I2C_PECTRANS_ENABLE: transfer PEC + \arg I2C_PECTRANS_DISABLE: not transfer PEC + \param[out] none + \retval none + */ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara) +{ + /* whether to transfer PEC */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECTRANS); + ctl |= pecpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief get packet error checking value + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval PEC value + */ +uint8_t i2c_pec_value_get(uint32_t i2c_periph) +{ + return (uint8_t) ((I2C_STAT1(i2c_periph) & I2C_STAT1_PECV)>> STAT1_PECV_OFFSET); +} + +/*! + \brief I2C issue alert through SMBA pin + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] smbuspara: + only one parameter can be selected which is shown as below: + \arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin + \arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin + \param[out] none + \retval none + */ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara) +{ + /* issue alert through SMBA pin configure*/ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SALT); + ctl |= smbuspara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief enable or disable I2C ARP protocol in SMBus switch + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] 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_DUMODF: 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) +{ + uint32_t temp; + if (I2C_FLAG_ADDSEND == flag) { + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + temp = I2C_STAT0(i2c_periph); + temp = 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: I2C interrupts, refer to i2c_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_ERR: error interrupt enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \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] 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_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) +{ + uint32_t temp; + if (I2C_INT_FLAG_ADDSEND == int_flag) { + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + temp = I2C_STAT0(i2c_periph); + temp = I2C_STAT1(i2c_periph); + } else { + I2C_REG_VAL2(i2c_periph, int_flag) &= ~BIT(I2C_BIT_POS2(int_flag)); + } +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_pmu.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_pmu.c new file mode 100644 index 0000000000000000000000000000000000000000..905cec75c31e08d01dd33ec560dc226f2fa7da06 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_pmu.c @@ -0,0 +1,270 @@ +/*! + \file gd32vf103_pmu.c + \brief PMU driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_pmu.h" +#include "riscv_encoding.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.2V + \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.5V + \arg PMU_LVDT_4: voltage threshold is 2.6V + \arg PMU_LVDT_5: voltage threshold is 2.7V + \arg PMU_LVDT_6: voltage threshold is 2.8V + \arg PMU_LVDT_7: voltage threshold is 2.9V + \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 disable PMU lvd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; +} + +/*! + \brief PMU work at sleep mode + \param[in] sleepmodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_sleepmode(uint8_t sleepmodecmd) +{ + /* clear sleepdeep bit of Cortex-M3 system control register */ + clear_csr(0x811, 0x1); + + /* select WFI or WFE command to enter sleep mode */ + if(WFI_CMD == sleepmodecmd){ + __WFI(); + }else{ + clear_csr(mstatus, MSTATUS_MIE); + set_csr(0x810, 0x1); + __WFI(); + clear_csr(0x810, 0x1); + set_csr(mstatus, MSTATUS_MIE); + } +} + +/*! + \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 work at normal power mode 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) +{ + /* 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 CSR_SLEEPVALUE bit of RISC-V system control register */ + set_csr(0x811, 0x1); + /* select WFI or WFE command to enter deepsleep mode */ + if(WFI_CMD == deepsleepmodecmd){ + __WFI(); + }else{ + clear_csr(mstatus, MSTATUS_MIE); + set_csr(0x810, 0x1); + __WFI(); + clear_csr(0x810, 0x1); + set_csr(mstatus, MSTATUS_MIE); + } + /* reset sleepdeep bit of RISC-V system control register */ + clear_csr(0x811, 0x1); +} + +/*! + \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 CSR_SLEEPVALUE bit of RISC-V system control register */ + set_csr(0x811, 0x1); + + /* 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{ + clear_csr(mstatus, MSTATUS_MIE); + set_csr(0x810, 0x1); + __WFI(); + clear_csr(0x810, 0x1); + set_csr(mstatus, MSTATUS_MIE); + } + clear_csr(0x811, 0x1); +} + +/*! + \brief enable wakeup pin + \param[in] none + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(void) +{ + PMU_CS |= PMU_CS_WUPEN; +} + +/*! + \brief disable wakeup pin + \param[in] none + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(void) +{ + PMU_CS &= ~PMU_CS_WUPEN; +} + +/*! + \brief enable write access to the registers in backup domain + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL |= PMU_CTL_BKPWEN; +} + +/*! + \brief disable write access to the registers in backup domain + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL &= ~PMU_CTL_BKPWEN; +} + +/*! + \brief get flag state + \param[in] flag: + only one parameter can be selected which is shown as below: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \arg PMU_FLAG_LVD: lvd flag + \param[out] none + \retval FlagStatus SET or RESET +*/ +FlagStatus pmu_flag_get(uint32_t flag) +{ + if(PMU_CS & flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear flag bit + \param[in] flag_reset: + only one parameter can be selected which is 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_reset) +{ + switch(flag_reset){ + case PMU_FLAG_RESET_WAKEUP: + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + break; + case PMU_FLAG_RESET_STANDBY: + /* reset standby flag */ + PMU_CTL |= PMU_CTL_STBRST; + break; + default : + break; + } +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_rcu.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_rcu.c new file mode 100644 index 0000000000000000000000000000000000000000..b2c0d83052c0254e4d83210377c9b6ff4a12c464 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_rcu.c @@ -0,0 +1,1111 @@ +/*! + \file gd32vf103_rcu.c + \brief RCU driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_rcu.h" + +/* define clock source */ +#define SEL_IRC8M ((uint16_t)0U) +#define SEL_HXTAL ((uint16_t)1U) +#define SEL_PLL ((uint16_t)2U) + +/* define startup timeout count */ +#define OSC_STARTUP_TIMEOUT ((uint32_t)0xFFFFFU) +#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x3FFFFFFU) + +/*! + \brief deinitialize the RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_deinit(void) +{ + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + rcu_osci_stab_wait(RCU_IRC8M); + + /* reset CFG0 register */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | + RCU_CFG0_ADCPSC | RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF | + RCU_CFG0_USBFSPSC | RCU_CFG0_CKOUT0SEL | RCU_CFG0_ADCPSC_2 | RCU_CFG0_PLLMF_4); + /* reset CTL register */ + RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN); + RCU_CTL &= ~RCU_CTL_HXTALBPS; + RCU_CTL &= ~(RCU_CTL_PLL1EN | RCU_CTL_PLL2EN); + /* reset INT and CFG1 register */ + RCU_INT = 0x00ff0000U; + RCU_CFG1 &= ~(RCU_CFG1_PREDV0 | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PLL2MF | + RCU_CFG1_PREDV0SEL | RCU_CFG1_I2S1SEL | RCU_CFG1_I2S2SEL); +} + +/*! + \brief enable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOx (x=A,B,C,D,E): GPIO ports clock + \arg RCU_AF : alternate function clock + \arg RCU_CRC: CRC clock + \arg RCU_DMAx (x=0,1): DMA clock + \arg RCU_USBFS: USBFS clock + \arg RCU_EXMC: EXMC clock + \arg RCU_TIMERx (x=0,1,2,3,4,5,6): TIMER clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_SPIx (x=0,1,2): SPI clock + \arg RCU_USARTx (x=0,1,2): USART clock + \arg RCU_UARTx (x=3,4): UART clock + \arg RCU_I2Cx (x=0,1): I2C clock + \arg RCU_CANx (x=0,1): CAN clock + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC clock + \arg RCU_RTC: RTC clock + \arg RCU_ADCx (x=0,1): ADC clock + \arg RCU_BKPI: BKP interface clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_enable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief disable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOx (x=A,B,C,D,E): GPIO ports clock + \arg RCU_AF: alternate function clock + \arg RCU_CRC: CRC clock + \arg RCU_DMAx (x=0,1): DMA clock + \arg RCU_USBFS: USBFS clock + \arg RCU_EXMC: EXMC clock + \arg RCU_TIMERx (x=0,1,2,3,4,5,6): TIMER clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_SPIx (x=0,1,2): SPI clock + \arg RCU_USARTx (x=0,1,2): USART clock + \arg RCU_UARTx (x=3,4): UART clock + \arg RCU_I2Cx (x=0,1): I2C clock + \arg RCU_CANx (x=0,1): CAN clock + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC clock + \arg RCU_RTC: RTC clock + \arg RCU_ADCx (x=0,1): ADC clock + \arg RCU_BKPI: BKP interface clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_disable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief enable the peripherals clock when sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM_SLP: SRAM clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph) +{ + RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief disable the peripherals clock when sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM_SLP: SRAM clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief reset the peripherals + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOxRST (x=A,B,C,D,E): reset GPIO ports + \arg RCU_AFRST : reset alternate function clock + \arg RCU_USBFSRST: reset USBFS + \arg RCU_TIMERxRST (x=0,1,2,3,4,5,6): reset TIMER + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_SPIxRST (x=0,1,2): reset SPI + \arg RCU_USARTxRST (x=0,1,2): reset USART + \arg RCU_UARTxRST (x=3,4): reset UART + \arg RCU_I2CxRST (x=0,1): reset I2C + \arg RCU_CANxRST (x=0,1): reset CAN + \arg RCU_PMURST: reset PMU + \arg RCU_DACRST: reset DAC + \arg RCU_ADCxRST (x=0,1): reset ADC + \arg RCU_BKPIRST: reset BKPI + \param[out] none + \retval none +*/ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) |= BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief disable reset the peripheral + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOxRST (x=A,B,C,D,E): reset GPIO ports + \arg RCU_AFRST : reset alternate function clock + \arg RCU_USBFSRST: reset USBFS + \arg RCU_TIMERxRST (x=0,1,2,3,4,5,6): reset TIMER + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_SPIxRST (x=0,1,2): reset SPI + \arg RCU_USARTxRST (x=0,1,2): reset USART + \arg RCU_UARTxRST (x=3,4): reset UART + \arg RCU_I2CxRST (x=0,1): reset I2C + \arg RCU_CANxRST (x=0,1): reset CAN + \arg RCU_PMURST: reset PMU + \arg RCU_DACRST: reset DAC + \arg RCU_ADCxRST (x=0,1): reset ADC + \arg RCU_BKPIRST: reset BKPI + \param[out] none + \retval none +*/ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) &= ~BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief reset the BKP domain + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_enable(void) +{ + RCU_BDCTL |= RCU_BDCTL_BKPRST; +} + +/*! + \brief disable the BKP domain reset + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_disable(void) +{ + RCU_BDCTL &= ~RCU_BDCTL_BKPRST; +} + +/*! + \brief configure the system clock source + \param[in] ck_sys: system clock source select + only one parameter can be selected which is shown as below: + \arg RCU_CKSYSSRC_IRC8M: select CK_IRC8M as the CK_SYS source + \arg RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_CKSYSSRC_PLL: select CK_PLL as the CK_SYS source + \param[out] none + \retval none +*/ +void rcu_system_clock_source_config(uint32_t ck_sys) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the SCS bits and set according to ck_sys */ + reg &= ~RCU_CFG0_SCS; + RCU_CFG0 = (reg | ck_sys); +} + +/*! + \brief get the system clock source + \param[in] none + \param[out] none + \retval which clock is selected as CK_SYS source + \arg RCU_SCSS_IRC8M: CK_IRC8M is selected as the CK_SYS source + \arg RCU_SCSS_HXTAL: CK_HXTAL is selected as the CK_SYS source + \arg RCU_SCSS_PLL: CK_PLL is selected as the CK_SYS source +*/ +uint32_t rcu_system_clock_source_get(void) +{ + return (RCU_CFG0 & RCU_CFG0_SCSS); +} + +/*! + \brief configure the AHB clock prescaler selection + \param[in] ck_ahb: AHB clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_AHB_CKSYS_DIVx, x=1, 2, 4, 8, 16, 64, 128, 256, 512 + \param[out] none + \retval none +*/ +void rcu_ahb_clock_config(uint32_t ck_ahb) +{ + uint32_t reg; + + reg = RCU_CFG0; + + /* reset the AHBPSC bits and set according to ck_ahb */ + reg &= ~RCU_CFG0_AHBPSC; + RCU_CFG0 = (reg | ck_ahb); +} + +/*! + \brief configure the APB1 clock prescaler selection + \param[in] ck_apb1: APB1 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB1_CKAHB_DIV1: select CK_AHB as CK_APB1 + \arg RCU_APB1_CKAHB_DIV2: select CK_AHB/2 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV4: select CK_AHB/4 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV8: select CK_AHB/8 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV16: select CK_AHB/16 as CK_APB1 + \param[out] none + \retval none +*/ +void rcu_apb1_clock_config(uint32_t ck_apb1) +{ + uint32_t reg; + + reg = RCU_CFG0; + + /* reset the APB1PSC and set according to ck_apb1 */ + reg &= ~RCU_CFG0_APB1PSC; + RCU_CFG0 = (reg | ck_apb1); +} + +/*! + \brief configure the APB2 clock prescaler selection + \param[in] ck_apb2: APB2 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB2_CKAHB_DIV1: select CK_AHB as CK_APB2 + \arg RCU_APB2_CKAHB_DIV2: select CK_AHB/2 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV4: select CK_AHB/4 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV8: select CK_AHB/8 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV16: select CK_AHB/16 as CK_APB2 + \param[out] none + \retval none +*/ +void rcu_apb2_clock_config(uint32_t ck_apb2) +{ + uint32_t reg; + + reg = RCU_CFG0; + + /* reset the APB2PSC and set according to ck_apb2 */ + reg &= ~RCU_CFG0_APB2PSC; + RCU_CFG0 = (reg | ck_apb2); +} + +/*! + \brief configure the CK_OUT0 clock source + \param[in] ckout0_src: CK_OUT0 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CKOUT0SRC_NONE: no clock selected + \arg RCU_CKOUT0SRC_CKSYS: system clock selected + \arg RCU_CKOUT0SRC_IRC8M: high speed 8M internal oscillator clock selected + \arg RCU_CKOUT0SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT0SRC_CKPLL_DIV2: CK_PLL/2 selected + \arg RCU_CKOUT0SRC_CKPLL1: CK_PLL1 selected + \arg RCU_CKOUT0SRC_CKPLL2_DIV2: CK_PLL2/2 selected + \arg RCU_CKOUT0SRC_EXT1: EXT1 selected + \arg RCU_CKOUT0SRC_CKPLL2: PLL2 selected + \param[out] none + \retval none +*/ +void rcu_ckout0_config(uint32_t ckout0_src) +{ + uint32_t reg; + + reg = RCU_CFG0; + + /* reset the CKOUT0SRC, set according to ckout0_src */ + reg &= ~RCU_CFG0_CKOUT0SEL; + RCU_CFG0 = (reg | ckout0_src); +} + +/*! + \brief configure the main PLL clock + \param[in] pll_src: PLL clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_PLLSRC_IRC8M_DIV2: IRC8M/2 clock selected as source clock of PLL + \arg RCU_PLLSRC_HXTAL: HXTAL selected as source clock of PLL + \param[in] pll_mul: PLL clock multiplication factor + only one parameter can be selected which is shown as below: + \arg RCU_PLL_MULx (x = 2..14, 6.5, 16..32) + \param[out] none + \retval none +*/ +void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul) +{ + uint32_t reg = 0U; + + reg = RCU_CFG0; + + /* PLL clock source and multiplication factor configuration */ + reg &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + reg |= (pll_src | pll_mul); + + RCU_CFG0 = reg; +} + +/*! + \brief configure the PREDV0 division factor and clock source + \param[in] predv0_source: PREDV0 input clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_PREDV0SRC_HXTAL: HXTAL selected as PREDV0 input source clock + \arg RCU_PREDV0SRC_CKPLL1: CK_PLL1 selected as PREDV0 input source clock + \param[in] predv0_div: PREDV0 division factor + only one parameter can be selected which is shown as below: + \arg RCU_PREDV0_DIVx, x = 1..16 + \param[out] none + \retval none +*/ +void rcu_predv0_config(uint32_t predv0_source, uint32_t predv0_div) +{ + uint32_t reg = 0U; + + reg = RCU_CFG1; + /* reset PREDV0SEL and PREDV0 bits */ + reg &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV0); + /* set the PREDV0SEL and PREDV0 division factor */ + reg |= (predv0_source | predv0_div); + + RCU_CFG1 = reg; +} + +/*! + \brief configure the PREDV1 division factor + \param[in] predv1_div: PREDV1 division factor + only one parameter can be selected which is shown as below: + \arg RCU_PREDV1_DIVx, x = 1..16 + \param[out] none + \retval none +*/ +void rcu_predv1_config(uint32_t predv1_div) +{ + uint32_t reg = 0U; + + reg = RCU_CFG1; + /* reset the PREDV1 bits */ + reg &= ~RCU_CFG1_PREDV1; + /* set the PREDV1 division factor */ + reg |= predv1_div; + + RCU_CFG1 = reg; +} + +/*! + \brief configure the PLL1 clock + \param[in] pll_mul: PLL clock multiplication factor + only one parameter can be selected which is shown as below: + \arg RCU_PLL1_MULx (x = 8..16, 20) + \param[out] none + \retval none +*/ +void rcu_pll1_config(uint32_t pll_mul) +{ + RCU_CFG1 &= ~RCU_CFG1_PLL1MF; + RCU_CFG1 |= pll_mul; +} + +/*! + \brief configure the PLL2 clock + \param[in] pll_mul: PLL clock multiplication factor + only one parameter can be selected which is shown as below: + \arg RCU_PLL2_MULx (x = 8..16, 20) + \param[out] none + \retval none +*/ +void rcu_pll2_config(uint32_t pll_mul) +{ + RCU_CFG1 &= ~RCU_CFG1_PLL2MF; + RCU_CFG1 |= pll_mul; +} + +/*! + \brief configure the ADC prescaler factor + \param[in] adc_psc: ADC prescaler factor + only one parameter can be selected which is shown as below: + \arg RCU_CKADC_CKAPB2_DIV2: ADC prescaler select CK_APB2/2 + \arg RCU_CKADC_CKAPB2_DIV4: ADC prescaler select CK_APB2/4 + \arg RCU_CKADC_CKAPB2_DIV6: ADC prescaler select CK_APB2/6 + \arg RCU_CKADC_CKAPB2_DIV8: ADC prescaler select CK_APB2/8 + \arg RCU_CKADC_CKAPB2_DIV12: ADC prescaler select CK_APB2/12 + \arg RCU_CKADC_CKAPB2_DIV16: ADC prescaler select CK_APB2/16 + \param[out] none + \retval none +*/ +void rcu_adc_clock_config(uint32_t adc_psc) +{ + uint32_t reg0; + + /* reset the ADCPSC bits */ + reg0 = RCU_CFG0; + reg0 &= ~(RCU_CFG0_ADCPSC_2 | RCU_CFG0_ADCPSC); + + /* set the ADC prescaler factor */ + switch(adc_psc){ + case RCU_CKADC_CKAPB2_DIV2: + case RCU_CKADC_CKAPB2_DIV4: + case RCU_CKADC_CKAPB2_DIV6: + case RCU_CKADC_CKAPB2_DIV8: + reg0 |= (adc_psc << 14); + break; + + case RCU_CKADC_CKAPB2_DIV12: + case RCU_CKADC_CKAPB2_DIV16: + adc_psc &= ~BIT(2); + reg0 |= (adc_psc << 14 | RCU_CFG0_ADCPSC_2); + break; + + default: + break; + } + + /* set the register */ + RCU_CFG0 = reg0; +} + +/*! + \brief configure the USBFS prescaler factor + \param[in] usb_psc: USB prescaler factor + only one parameter can be selected which is shown as below: + \arg RCU_CKUSB_CKPLL_DIV1_5: USBFS prescaler select CK_PLL/1.5 + \arg RCU_CKUSB_CKPLL_DIV1: USBFS prescaler select CK_PLL/1 + \arg RCU_CKUSB_CKPLL_DIV2_5: USBFS prescaler select CK_PLL/2.5 + \arg RCU_CKUSB_CKPLL_DIV2: USBFS prescaler select CK_PLL/2 + \param[out] none + \retval none +*/ +void rcu_usb_clock_config(uint32_t usb_psc) +{ + uint32_t reg; + + reg = RCU_CFG0; + + /* configure the USBFS prescaler factor */ + reg &= ~RCU_CFG0_USBFSPSC; + RCU_CFG0 = (reg | usb_psc); +} + +/*! + \brief configure the RTC clock source selection + \param[in] rtc_clock_source: RTC clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_RTCSRC_NONE: no clock selected + \arg RCU_RTCSRC_LXTAL: CK_LXTAL selected as RTC source clock + \arg RCU_RTCSRC_IRC40K: CK_IRC40K selected as RTC source clock + \arg RCU_RTCSRC_HXTAL_DIV_128: CK_HXTAL/128 selected as RTC source clock + \param[out] none + \retval none +*/ +void rcu_rtc_clock_config(uint32_t rtc_clock_source) +{ + uint32_t reg; + + reg = RCU_BDCTL; + /* reset the RTCSRC bits and set according to rtc_clock_source */ + reg &= ~RCU_BDCTL_RTCSRC; + RCU_BDCTL = (reg | rtc_clock_source); +} + +/*! + \brief configure the I2S1 clock source selection + \param[in] i2s_clock_source: I2S1 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_I2S1SRC_CKSYS: System clock selected as I2S1 source clock + \arg RCU_I2S1SRC_CKPLL2_MUL2: CK_PLL2x2 selected as I2S1 source clock + \param[out] none + \retval none +*/ +void rcu_i2s1_clock_config(uint32_t i2s_clock_source) +{ + uint32_t reg; + + reg = RCU_CFG1; + /* reset the I2S1SEL bit and set according to i2s_clock_source */ + reg &= ~RCU_CFG1_I2S1SEL; + RCU_CFG1 = (reg | i2s_clock_source); +} + +/*! + \brief configure the I2S2 clock source selection + \param[in] i2s_clock_source: I2S2 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_I2S2SRC_CKSYS: system clock selected as I2S2 source clock + \arg RCU_I2S2SRC_CKPLL2_MUL2: CK_PLL2x2 selected as I2S2 source clock + \param[out] none + \retval none +*/ +void rcu_i2s2_clock_config(uint32_t i2s_clock_source) +{ + uint32_t reg; + + reg = RCU_CFG1; + /* reset the I2S2SEL bit and set according to i2s_clock_source */ + reg &= ~RCU_CFG1_I2S2SEL; + RCU_CFG1 = (reg | i2s_clock_source); +} + +/*! + \brief get the clock stabilization and periphral reset flags + \param[in] flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_FLAG_IRC8MSTB: IRC8M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_PLLSTB: PLL stabilization flag + \arg RCU_FLAG_PLL1STB: PLL1 stabilization flag + \arg RCU_FLAG_PLL2STB: PLL2 stabilization flag + \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag + \arg RCU_FLAG_IRC40KSTB: IRC40K stabilization flag + \arg RCU_FLAG_EPRST: external PIN reset flag + \arg RCU_FLAG_PORRST: power reset flag + \arg RCU_FLAG_SWRST: software reset flag + \arg RCU_FLAG_FWDGTRST: free watchdog timer reset flag + \arg RCU_FLAG_WWDGTRST: window watchdog timer reset flag + \arg RCU_FLAG_LPRST: low-power reset flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_flag_get(rcu_flag_enum flag) +{ + /* get the rcu flag */ + if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear all the reset flag + \param[in] none + \param[out] none + \retval none +*/ +void rcu_all_reset_flag_clear(void) +{ + RCU_RSTSCK |= RCU_RSTSCK_RSTFC; +} + +/*! + \brief get the clock stabilization interrupt and ckm flags + \param[in] int_flag: interrupt and ckm flags, refer to rcu_int_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC40KSTB: IRC40K stabilization interrupt flag + \arg RCU_INT_FLAG_LXTALSTB: LXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_IRC8MSTB: IRC8M stabilization interrupt flag + \arg RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_PLLSTB: PLL stabilization interrupt flag + \arg RCU_INT_FLAG_PLL1STB: PLL1 stabilization interrupt flag + \arg RCU_INT_FLAG_PLL2STB: PLL2 stabilization interrupt flag + \arg RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag) +{ + /* get the rcu interrupt flag */ + if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the interrupt flags + \param[in] int_flag_clear: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC40KSTB_CLR: IRC40K stabilization interrupt flag clear + \arg RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_IRC8MSTB_CLR: IRC8M stabilization interrupt flag clear + \arg RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLSTB_CLR: PLL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLL1STB_CLR: PLL1 stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLL2STB_CLR: PLL2 stabilization interrupt flag clear + \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear + \param[out] none + \retval none +*/ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear) +{ + RCU_REG_VAL(int_flag_clear) |= BIT(RCU_BIT_POS(int_flag_clear)); +} + +/*! + \brief enable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + Only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt enable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable + \arg RCU_INT_PLL1STB: PLL1 stabilization interrupt enable + \arg RCU_INT_PLL2STB: PLL2 stabilization interrupt enable + \param[out] none + \retval none +*/ +void rcu_interrupt_enable(rcu_int_enum stab_int) +{ + RCU_REG_VAL(stab_int) |= BIT(RCU_BIT_POS(stab_int)); +} + +/*! + \brief disable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt enable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable + \arg RCU_INT_PLL1STB: PLL1 stabilization interrupt enable + \arg RCU_INT_PLL2STB: PLL2 stabilization interrupt enable + \param[out] none + \retval none +*/ +void rcu_interrupt_disable(rcu_int_enum stab_int) +{ + RCU_REG_VAL(stab_int) &= ~BIT(RCU_BIT_POS(stab_int)); +} + +/*! + \brief wait for oscillator stabilization flags is SET or oscillator startup is timeout + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator(HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator(LXTAL) + \arg RCU_IRC8M: internal 8M RC oscillators(IRC8M) + \arg RCU_IRC40K: internal 40K RC oscillator(IRC40K) + \arg RCU_PLL_CK: phase locked loop(PLL) + \arg RCU_PLL1_CK: phase locked loop 1 + \arg RCU_PLL2_CK: phase locked loop 2 + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci) +{ + uint32_t stb_cnt = 0U; + ErrStatus reval = ERROR; + FlagStatus osci_stat = RESET; + + switch(osci){ + /* wait HXTAL stable */ + case RCU_HXTAL: + while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_HXTALSTB)){ + reval = SUCCESS; + } + break; + + /* wait LXTAL stable */ + case RCU_LXTAL: + while((RESET == osci_stat) && (LXTAL_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_LXTALSTB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)){ + reval = SUCCESS; + } + break; + + /* wait IRC8M stable */ + case RCU_IRC8M: + while((RESET == osci_stat) && (IRC8M_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC8MSTB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC8MSTB)){ + reval = SUCCESS; + } + break; + + /* wait IRC40K stable */ + case RCU_IRC40K: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC40KSTB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC40KSTB)){ + reval = SUCCESS; + } + break; + + /* wait PLL stable */ + case RCU_PLL_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_PLLSTB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLSTB)){ + reval = SUCCESS; + } + break; + /* wait PLL1 stable */ + case RCU_PLL1_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_PLL1STB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_PLL1STB)){ + reval = SUCCESS; + } + break; + /* wait PLL2 stable */ + case RCU_PLL2_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_PLL2STB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_PLL2STB)){ + reval = SUCCESS; + } + break; + + default: + break; + } + + /* return value */ + return reval; +} + +/*! + \brief turn on the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator(HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator(LXTAL) + \arg RCU_IRC8M: internal 8M RC oscillators(IRC8M) + \arg RCU_IRC40K: internal 40K RC oscillator(IRC40K) + \arg RCU_PLL_CK: phase locked loop(PLL) + \arg RCU_PLL1_CK: phase locked loop 1 + \arg RCU_PLL2_CK: phase locked loop 2 + \param[out] none + \retval none +*/ +void rcu_osci_on(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) |= BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief turn off the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator(HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator(LXTAL) + \arg RCU_IRC8M: internal 8M RC oscillators(IRC8M) + \arg RCU_IRC40K: internal 40K RC oscillator(IRC40K) + \arg RCU_PLL_CK: phase locked loop(PLL) + \arg RCU_PLL1_CK: phase locked loop 1 + \arg RCU_PLL2_CK: phase locked loop 2 + \param[out] none + \retval none +*/ +void rcu_osci_off(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) &= ~BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator(HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator(LXTAL) + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) +{ + uint32_t reg; + + switch(osci){ + /* enable HXTAL to bypass mode */ + case RCU_HXTAL: + reg = RCU_CTL; + RCU_CTL &= ~RCU_CTL_HXTALEN; + RCU_CTL = (reg | RCU_CTL_HXTALBPS); + break; + /* enable LXTAL to bypass mode */ + case RCU_LXTAL: + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg | RCU_BDCTL_LXTALBPS); + break; + case RCU_IRC8M: + case RCU_IRC40K: + case RCU_PLL_CK: + case RCU_PLL1_CK: + case RCU_PLL2_CK: + break; + default: + break; + } +} + +/*! + \brief disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator(HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator(LXTAL) + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci) +{ + uint32_t reg; + + switch(osci){ + /* disable HXTAL to bypass mode */ + case RCU_HXTAL: + reg = RCU_CTL; + RCU_CTL &= ~RCU_CTL_HXTALEN; + RCU_CTL = (reg & ~RCU_CTL_HXTALBPS); + break; + /* disable LXTAL to bypass mode */ + case RCU_LXTAL: + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg & ~RCU_BDCTL_LXTALBPS); + break; + case RCU_IRC8M: + case RCU_IRC40K: + case RCU_PLL_CK: + case RCU_PLL1_CK: + case RCU_PLL2_CK: + break; + default: + break; + } +} + +/*! + \brief enable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ + +void rcu_hxtal_clock_monitor_enable(void) +{ + RCU_CTL |= RCU_CTL_CKMEN; +} + +/*! + \brief disable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_disable(void) +{ + RCU_CTL &= ~RCU_CTL_CKMEN; +} + +/*! + \brief set the IRC8M adjust value + \param[in] irc8m_adjval: IRC8M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc8m_adjust_value_set(uint32_t irc8m_adjval) +{ + uint32_t reg; + + reg = RCU_CTL; + /* reset the IRC8MADJ bits and set according to irc8m_adjval */ + reg &= ~RCU_CTL_IRC8MADJ; + RCU_CTL = (reg | ((irc8m_adjval & 0x1FU) << 3)); +} + +/*! + \brief deep-sleep mode voltage select + \param[in] dsvol: deep sleep mode voltage + only one parameter can be selected which is shown as below: + \arg RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V + \arg RCU_DEEPSLEEP_V_1_1: the core voltage is 1.1V + \arg RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V + \arg RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V + \param[out] none + \retval none +*/ +void rcu_deepsleep_voltage_set(uint32_t dsvol) +{ + dsvol &= RCU_DSV_DSLPVS; + RCU_DSV = dsvol; +} + +/*! + \brief get the system clock, bus and peripheral clock frequency + \param[in] clock: the clock frequency which to get + only one parameter can be selected which is shown as below: + \arg CK_SYS: system clock frequency + \arg CK_AHB: AHB clock frequency + \arg CK_APB1: APB1 clock frequency + \arg CK_APB2: APB2 clock frequency + \param[out] none + \retval clock frequency of system, AHB, APB1, APB2 +*/ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) +{ + uint32_t sws, ck_freq = 0U; + uint32_t cksys_freq, ahb_freq, apb1_freq, apb2_freq; + uint32_t pllsel, predv0sel, pllmf,ck_src, idx, clk_exp; + uint32_t predv0, predv1, pll1mf; + + /* exponent of AHB, APB1 and APB2 clock divider */ + uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC8M is selected as CK_SYS */ + case SEL_IRC8M: + cksys_freq = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + cksys_freq = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case SEL_PLL: + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = (RCU_CFG0 & RCU_CFG0_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + /* PLL clock source is HXTAL */ + ck_src = HXTAL_VALUE; + + predv0sel = (RCU_CFG1 & RCU_CFG1_PREDV0SEL); + /* source clock use PLL1 */ + if(RCU_PREDV0SRC_CKPLL1 == predv0sel){ + predv1 = (uint32_t)((RCU_CFG1 & RCU_CFG1_PREDV1) >> 4) + 1U; + pll1mf = (uint32_t)((RCU_CFG1 & RCU_CFG1_PLL1MF) >> 8) + 2U; + if(17U == pll1mf){ + pll1mf = 20U; + } + ck_src = (ck_src / predv1) * pll1mf; + } + predv0 = (RCU_CFG1 & RCU_CFG1_PREDV0) + 1U; + ck_src /= predv0; + }else{ + /* PLL clock source is IRC8M/2 */ + ck_src = IRC8M_VALUE/2U; + } + + /* PLL multiplication factor */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + if((RCU_CFG0 & RCU_CFG0_PLLMF_4)){ + pllmf |= 0x10U; + } + if(pllmf < 15U){ + pllmf += 2U; + }else{ + pllmf += 1U; + } + + cksys_freq = ck_src * pllmf; + + if(15U == pllmf){ + /* PLL source clock multiply by 6.5 */ + cksys_freq = ck_src * 6U + ck_src / 2U; + } + + break; + /* IRC8M is selected as CK_SYS */ + default: + cksys_freq = IRC8M_VALUE; + break; + } + + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + ahb_freq = cksys_freq >> clk_exp; + + /* calculate APB1 clock frequency */ + idx = GET_BITS(RCU_CFG0, 8, 10); + clk_exp = apb1_exp[idx]; + apb1_freq = ahb_freq >> clk_exp; + + /* calculate APB2 clock frequency */ + idx = GET_BITS(RCU_CFG0, 11, 13); + clk_exp = apb2_exp[idx]; + apb2_freq = ahb_freq >> clk_exp; + + /* return the clocks frequency */ + switch(clock){ + case CK_SYS: + ck_freq = cksys_freq; + break; + case CK_AHB: + ck_freq = ahb_freq; + break; + case CK_APB1: + ck_freq = apb1_freq; + break; + case CK_APB2: + ck_freq = apb2_freq; + break; + default: + break; + } + return ck_freq; +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_rtc.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..e397d3a2cf05953df9ec88e0c9ee213b7238f566 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_rtc.c @@ -0,0 +1,273 @@ +/*! + \file gd32vf103_rtc.c + \brief RTC driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_rtc.h" + +/* RTC register high / low bits mask */ +#define RTC_HIGH_BITS_MASK ((uint32_t)0x000F0000U) /* RTC high bits mask */ +#define RTC_LOW_BITS_MASK ((uint32_t)0x0000FFFFU) /* RTC low bits mask */ + +/* RTC register high bits offset */ +#define RTC_HIGH_BITS_OFFSET ((uint32_t)16U) + +/*! + \brief enter RTC configuration mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_configuration_mode_enter(void) +{ + RTC_CTL |= RTC_CTL_CMF; +} + +/*! + \brief exit RTC configuration mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_configuration_mode_exit(void) +{ + RTC_CTL &= ~RTC_CTL_CMF; +} + +/*! + \brief set RTC counter value + \param[in] cnt: RTC counter value + \param[out] none + \retval none +*/ +void rtc_counter_set(uint32_t cnt) +{ + rtc_configuration_mode_enter(); + /* set the RTC counter high bits */ + RTC_CNTH = (cnt >> RTC_HIGH_BITS_OFFSET); + /* set the RTC counter low bits */ + RTC_CNTL = (cnt & RTC_LOW_BITS_MASK); + rtc_configuration_mode_exit(); +} + +/*! + \brief set RTC prescaler value + \param[in] psc: RTC prescaler value + \param[out] none + \retval none +*/ +void rtc_prescaler_set(uint32_t psc) +{ + rtc_configuration_mode_enter(); + /* set the RTC prescaler high bits */ + RTC_PSCH = ((psc & RTC_HIGH_BITS_MASK) >> RTC_HIGH_BITS_OFFSET); + /* set the RTC prescaler low bits */ + RTC_PSCL = (psc & RTC_LOW_BITS_MASK); + rtc_configuration_mode_exit(); +} + +/*! + \brief wait RTC last write operation finished flag set + \param[in] none + \param[out] none + \retval none +*/ +void rtc_lwoff_wait(void) +{ + /* loop until LWOFF flag is set */ + while(RESET == (RTC_CTL & RTC_CTL_LWOFF)){ + } +} + +/*! + \brief wait RTC registers synchronized flag set + \param[in] none + \param[out] none + \retval none +*/ +void rtc_register_sync_wait(void) +{ + /* clear RSYNF flag */ + RTC_CTL &= ~RTC_CTL_RSYNF; + /* loop until RSYNF flag is set */ + while(RESET == (RTC_CTL & RTC_CTL_RSYNF)){ + } +} + +/*! + \brief set RTC alarm value + \param[in] alarm: RTC alarm value + \param[out] none + \retval none +*/ +void rtc_alarm_config(uint32_t alarm) +{ + rtc_configuration_mode_enter(); + /* set the alarm high bits */ + RTC_ALRMH = (alarm >> RTC_HIGH_BITS_OFFSET); + /* set the alarm low bits */ + RTC_ALRML = (alarm & RTC_LOW_BITS_MASK); + rtc_configuration_mode_exit(); +} + +/*! + \brief get RTC counter value + \param[in] none + \param[out] none + \retval RTC counter value +*/ +uint32_t rtc_counter_get(void) +{ + uint32_t temp = 0x0U; + + temp = RTC_CNTL; + temp |= (RTC_CNTH << RTC_HIGH_BITS_OFFSET); + return temp; +} + +/*! + \brief get RTC divider value + \param[in] none + \param[out] none + \retval RTC divider value +*/ +uint32_t rtc_divider_get(void) +{ + uint32_t temp = 0x00U; + + temp = ((RTC_DIVH & RTC_DIVH_DIV) << RTC_HIGH_BITS_OFFSET); + temp |= RTC_DIVL; + return temp; +} + +/*! + \brief get RTC flag status + \param[in] flag: specify which flag status to get + only one parameter can be selected which is shown as below: + \arg RTC_FLAG_SECOND: second interrupt flag + \arg RTC_FLAG_ALARM: alarm interrupt flag + \arg RTC_FLAG_OVERFLOW: overflow interrupt flag + \arg RTC_FLAG_RSYN: registers synchronized flag + \arg RTC_FLAG_LWOF: last write operation finished flag + \param[out] none + \retval SET or RESET +*/ +FlagStatus rtc_flag_get(uint32_t flag) +{ + if(RESET != (RTC_CTL & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear RTC flag status + \param[in] flag: specify which flag status to clear + one or more parameters can be selected which are shown as below: + \arg RTC_FLAG_SECOND: second interrupt flag + \arg RTC_FLAG_ALARM: alarm interrupt flag + \arg RTC_FLAG_OVERFLOW: overflow interrupt flag + \arg RTC_FLAG_RSYN: registers synchronized flag + \param[out] none + \retval none +*/ +void rtc_flag_clear(uint32_t flag) +{ + /* clear RTC flag */ + RTC_CTL &= ~flag; +} + +/*! + \brief get RTC interrupt flag status + \param[in] flag: specify which flag status to get + only one parameter can be selected which is shown as below: + \arg RTC_INT_FLAG_SECOND: second interrupt flag + \arg RTC_INT_FLAG_ALARM: alarm interrupt flag + \arg RTC_INT_FLAG_OVERFLOW: overflow interrupt flag + \param[out] none + \retval SET or RESET +*/ +FlagStatus rtc_interrupt_flag_get(uint32_t flag) +{ + if(RESET != (RTC_CTL & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear RTC interrupt flag status + \param[in] flag: specify which flag status to clear + one or more parameters can be selected which are shown as below: + \arg RTC_INT_FLAG_SECOND: second interrupt flag + \arg RTC_INT_FLAG_ALARM: alarm interrupt flag + \arg RTC_INT_FLAG_OVERFLOW: overflow interrupt flag + \param[out] none + \retval none +*/ +void rtc_interrupt_flag_clear(uint32_t flag) +{ + /* clear RTC interrupt flag */ + RTC_CTL &= ~flag; +} + +/*! + \brief enable RTC interrupt + \param[in] interrupt: specify which interrupt to enbale + one or more parameters can be selected which are shown as below: + \arg RTC_INT_SECOND: second interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_OVERFLOW: overflow interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_enable(uint32_t interrupt) +{ + RTC_INTEN |= interrupt; +} + +/*! + \brief disable RTC interrupt + \param[in] interrupt: specify which interrupt to disbale + one or more parameters can be selected which are shown as below: + \arg RTC_INT_SECOND: second interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_OVERFLOW: overflow interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_disable(uint32_t interrupt) +{ + RTC_INTEN &= ~interrupt; +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_spi.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..2e1b3a16bbfa6cce89181662b6a3f2c9e7bc8961 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_spi.c @@ -0,0 +1,766 @@ +/*! + \file gd32vf103_spi.c + \brief SPI driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_spi.h" + +/* SPI/I2S parameter initialization mask */ +#define SPI_INIT_MASK ((uint32_t)0x00003040U) /*!< SPI parameter initialization mask */ +#define I2S_INIT_MASK ((uint32_t)0x0000F047U) /*!< I2S parameter initialization mask */ + +/* I2S clock source selection, multiplication and division mask */ +#define I2S1_CLOCK_SEL ((uint32_t)0x00020000U) /* I2S1 clock source selection */ +#define I2S2_CLOCK_SEL ((uint32_t)0x00040000U) /* I2S2 clock source selection */ +#define I2S_CLOCK_MUL_MASK ((uint32_t)0x0000F000U) /* I2S clock multiplication mask */ +#define I2S_CLOCK_DIV_MASK ((uint32_t)0x000000F0U) /* I2S clock division mask */ + +/* default value and offset */ +#define SPI_I2SPSC_DEFAULT_VALUE ((uint32_t)0x00000002U) /* default value of SPI_I2SPSC register */ +#define RCU_CFG1_PREDV1_OFFSET 4U /* PREDV1 offset in RCU_CFG1 */ +#define RCU_CFG1_PLL2MF_OFFSET 12U /* PLL2MF offset in RCU_CFG1 */ + +/*! + \brief reset SPI and I2S + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_i2s_deinit(uint32_t spi_periph) +{ + switch(spi_periph){ + case SPI0: + /* reset SPI0 */ + rcu_periph_reset_enable(RCU_SPI0RST); + rcu_periph_reset_disable(RCU_SPI0RST); + break; + case SPI1: + /* reset SPI1 and I2S1 */ + rcu_periph_reset_enable(RCU_SPI1RST); + rcu_periph_reset_disable(RCU_SPI1RST); + break; + case SPI2: + /* reset SPI2 and I2S2 */ + rcu_periph_reset_enable(RCU_SPI2RST); + rcu_periph_reset_disable(RCU_SPI2RST); + 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,2) + \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; + + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL); +} + +/*! + \brief enable SPI + \param[in] spi_periph: SPIx(x=0,1,2) + \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,2) + \param[out] none + \retval none +*/ +void spi_disable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN); +} + +/*! + \brief initialize I2S parameter + \param[in] spi_periph: SPIx(x=1,2) + \param[in] mode: I2S operation mode + only one parameter can be selected which is shown as below: + \arg I2S_MODE_SLAVETX: I2S slave transmit mode + \arg I2S_MODE_SLAVERX: I2S slave receive mode + \arg I2S_MODE_MASTERTX: I2S master transmit mode + \arg I2S_MODE_MASTERRX: I2S master receive mode + \param[in] standard: I2S standard + only one parameter can be selected which is shown as below: + \arg I2S_STD_PHILLIPS: I2S phillips standard + \arg I2S_STD_MSB: I2S MSB standard + \arg I2S_STD_LSB: I2S LSB standard + \arg I2S_STD_PCMSHORT: I2S PCM short standard + \arg I2S_STD_PCMLONG: I2S PCM long standard + \param[in] ckpl: I2S idle state clock polarity + only one parameter can be selected which is shown as below: + \arg I2S_CKPL_LOW: I2S clock polarity low level + \arg I2S_CKPL_HIGH: I2S clock polarity high level + \param[out] none + \retval none +*/ +void i2s_init(uint32_t spi_periph, uint32_t mode, uint32_t standard, uint32_t ckpl) +{ + uint32_t reg = 0U; + reg = SPI_I2SCTL(spi_periph); + reg &= I2S_INIT_MASK; + + /* enable I2S mode */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)mode; + /* select I2S standard */ + reg |= (uint32_t)standard; + /* select I2S polarity */ + reg |= (uint32_t)ckpl; + + /* write to SPI_I2SCTL register */ + SPI_I2SCTL(spi_periph) = (uint32_t)reg; +} + +/*! + \brief configure I2S prescaler + \param[in] spi_periph: SPIx(x=1,2) + \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 the I2S clock source */ + if(SPI1 == ((uint32_t)spi_periph)){ + /* I2S1 clock source selection */ + clks = I2S1_CLOCK_SEL; + }else{ + /* I2S2 clock source selection */ + clks = I2S2_CLOCK_SEL; + } + + if(0U != (RCU_CFG1 & clks)){ + /* get RCU PLL2 clock multiplication factor */ + clks = (uint32_t)((RCU_CFG1 & I2S_CLOCK_MUL_MASK) >> RCU_CFG1_PLL2MF_OFFSET); + + if((clks > 5U) && (clks < 15U)){ + /* multiplier is between 8 and 16 */ + clks += 2U; + }else{ + if(15U == clks){ + /* multiplier is 20 */ + clks = 20U; + } + } + + /* get the PREDV1 value */ + i2sclock = (uint32_t)(((RCU_CFG1 & I2S_CLOCK_DIV_MASK) >> RCU_CFG1_PREDV1_OFFSET) + 1U); + /* calculate I2S clock based on PLL2 and PREDV1 */ + i2sclock = (uint32_t)((HXTAL_VALUE / i2sclock) * clks * 2U); + }else{ + /* get system clock */ + i2sclock = rcu_clock_freq_get(CK_SYS); + } + + /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */ + if(I2S_MCKOUT_ENABLE == mckout){ + clks = (uint32_t)(((i2sclock / 256U) * 10U) / audiosample); + }else{ + if(I2S_FRAMEFORMAT_DT16B_CH16B == frameformat){ + clks = (uint32_t)(((i2sclock / 32U) *10U ) / audiosample); + }else{ + clks = (uint32_t)(((i2sclock / 64U) *10U ) / audiosample); + } + } + + /* remove the floating point */ + clks = (clks + 5U) / 10U; + i2sof = (clks & 0x00000001U); + i2sdiv = ((clks - i2sof) / 2U); + i2sof = (i2sof << 8U); + + /* set the default values */ + if((i2sdiv < 2U) || (i2sdiv > 255U)){ + i2sdiv = 2U; + i2sof = 0U; + } + /* configure SPI_I2SPSC */ + SPI_I2SPSC(spi_periph) = (uint32_t)(i2sdiv | i2sof | mckout); + + /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN | SPI_I2SCTL_CHLEN)); + /* configure data frame format */ + SPI_I2SCTL(spi_periph) |= (uint32_t)frameformat; +} + +/*! + \brief enable I2S + \param[in] spi_periph: SPIx(x=1,2) + \param[out] none + \retval none +*/ +void i2s_enable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN; +} + +/*! + \brief disable I2S + \param[in] spi_periph: SPIx(x=1,2) + \param[out] none + \retval none +*/ +void i2s_disable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN); +} + +/*! + \brief enable SPI NSS output + \param[in] spi_periph: SPIx(x=0,1,2) + \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,2) + \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,2) + \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,2) + \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,2) + \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,2) + \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,2) + \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); + /* configure SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) |= (uint32_t)frame_format; +} + +/*! + \brief SPI transmit data + \param[in] spi_periph: SPIx(x=0,1,2) + \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,2) + \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,2) + \param[in] transfer_direction: SPI transfer direction + only one parameter can be selected which is shown as below: + \arg SPI_BIDIRECTIONAL_TRANSMIT: SPI work in transmit-only mode + \arg SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode + \param[out] none + \retval none +*/ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction) +{ + if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction){ + /* set the transmit-only mode */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT; + }else{ + /* set the receive-only mode */ + SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE; + } +} + +/*! + \brief set SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1,2) + \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,2) + \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,2) + \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,2) + \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,2) + \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,2) + \param[in] crc: SPI crc value + only one parameter can be selected which is shown as below: + \arg SPI_CRC_TX: get transmit crc value + \arg SPI_CRC_RX: get receive crc value + \param[out] none + \retval 16-bit CRC value +*/ +uint16_t spi_crc_get(uint32_t spi_periph,uint8_t crc) +{ + if(SPI_CRC_TX == crc){ + return ((uint16_t)(SPI_TCRC(spi_periph))); + }else{ + return ((uint16_t)(SPI_RCRC(spi_periph))); + } +} + +/*! + \brief enable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1,2) + \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,2) + \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,2) + \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,2) + \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 SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1,2) + \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,2) + \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,2) + \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,2) + \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,2) + \param[out] none + \retval none +*/ +void spi_crc_error_clear(uint32_t spi_periph) +{ + SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR); +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_timer.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..e13e1cd29bb4a610b8fd9353355752e99bdd31e1 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_timer.c @@ -0,0 +1,1965 @@ +/*! + \file gd32vf103_timer.c + \brief TIMER driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_timer.h" + +/* TIMER init parameter mask */ +#define ALIGNEDMODE_MASK ((uint32_t)0x00000060U) /*!< TIMER init parameter aligne dmode mask */ +#define COUNTERDIRECTION_MASK ((uint32_t)0x00000010U) /*!< TIMER init parameter counter direction mask */ +#define CLOCKDIVISION_MASK ((uint32_t)0x00000300U) /*!< TIMER init parameter clock division value mask */ + +/*! + \brief deinit a timer + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval none +*/ +void timer_deinit(uint32_t timer_periph) +{ + switch(timer_periph){ + case TIMER0: + /* reset TIMER0 */ + rcu_periph_reset_enable(RCU_TIMER0RST); + rcu_periph_reset_disable(RCU_TIMER0RST); + break; + case TIMER1: + /* reset TIMER1 */ + rcu_periph_reset_enable(RCU_TIMER1RST); + rcu_periph_reset_disable(RCU_TIMER1RST); + break; + case TIMER2: + /* reset TIMER2 */ + rcu_periph_reset_enable(RCU_TIMER2RST); + rcu_periph_reset_disable(RCU_TIMER2RST); + break; + case TIMER3: + /* reset TIMER3 */ + rcu_periph_reset_enable(RCU_TIMER3RST); + rcu_periph_reset_disable(RCU_TIMER3RST); + break; + case TIMER4: + /* reset TIMER4 */ + rcu_periph_reset_enable(RCU_TIMER4RST); + rcu_periph_reset_disable(RCU_TIMER4RST); + break; + case TIMER5: + /* reset TIMER5 */ + rcu_periph_reset_enable(RCU_TIMER5RST); + rcu_periph_reset_disable(RCU_TIMER5RST); + break; + case TIMER6: + /* reset TIMER6 */ + rcu_periph_reset_enable(RCU_TIMER6RST); + rcu_periph_reset_disable(RCU_TIMER6RST); + break; + + default: + break; + } +} + +/*! + \brief initialize TIMER init parameter struct with a default value + \param[in] initpara: init parameter struct + \param[out] none + \retval none +*/ +void timer_struct_para_init(timer_parameter_struct* initpara) +{ + /* initialize the init parameter struct member with the default value */ + initpara->prescaler = 0U; + initpara->alignedmode = TIMER_COUNTER_EDGE; + initpara->counterdirection = TIMER_COUNTER_UP; + initpara->period = 65535U; + initpara->clockdivision = TIMER_CKDIV_DIV1; + initpara->repetitioncounter = 0U; +} + +/*! + \brief initialize TIMER counter + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] initpara: init parameter struct + prescaler: prescaler value of the counter clock, 0~65535 + alignedmode: TIMER_COUNTER_EDGE, TIMER_COUNTER_CENTER_DOWN, TIMER_COUNTER_CENTER_UP, + TIMER_COUNTER_CENTER_BOTH + counterdirection: TIMER_COUNTER_UP, TIMER_COUNTER_DOWN + period: counter auto reload value, 0~65535 + clockdivision: TIMER_CKDIV_DIV1, TIMER_CKDIV_DIV2, TIMER_CKDIV_DIV4 + repetitioncounter: counter repetition value, 0~255 + \param[out] none + \retval none +*/ +void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara) +{ + /* configure the counter prescaler value */ + TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler; + + /* configure the counter direction and aligned mode */ + if((TIMER0 == timer_periph) || (TIMER1 == timer_periph) || (TIMER2 == timer_periph) + || (TIMER3 == timer_periph) || (TIMER4 == timer_periph) ){ + TIMER_CTL0(timer_periph) &= (~(uint32_t)(TIMER_CTL0_DIR | TIMER_CTL0_CAM)); + TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->alignedmode & ALIGNEDMODE_MASK); + TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->counterdirection & COUNTERDIRECTION_MASK); + }else{ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_DIR); + TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->counterdirection & COUNTERDIRECTION_MASK); + } + + /* configure the autoreload value */ + TIMER_CAR(timer_periph) = (uint32_t)initpara->period; + + if((TIMER5 != timer_periph) && (TIMER6 != timer_periph)){ + /* reset the CKDIV bit */ + TIMER_CTL0(timer_periph) &= (~(uint32_t)TIMER_CTL0_CKDIV); + TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->clockdivision & CLOCKDIVISION_MASK); + } + + if (TIMER0 == timer_periph) { + /* configure the repetition counter value */ + TIMER_CREP(timer_periph) = (uint32_t)initpara->repetitioncounter; + } + + /* generate an update event */ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; +} + +/*! + \brief enable a timer + \param[in] timer_periph: TIMERx(x=0..6) + \param[out] none + \retval none +*/ +void timer_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief disable a timer + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval none +*/ +void timer_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief enable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0..6) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief disable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0..6) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief enable the update event + \param[in] timer_periph: TIMERx(x=0..6) + \param[out] none + \retval none +*/ +void timer_update_event_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPDIS; +} + +/*! + \brief disable the update event + \param[in] timer_periph: TIMERx(x=0..6) + \param[out] none + \retval none +*/ +void timer_update_event_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_CTL0_UPDIS; +} + +/*! + \brief set TIMER counter alignment mode + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] aligned: + only one parameter can be selected which is shown as below: + \arg TIMER_COUNTER_EDGE: edge-aligned mode + \arg TIMER_COUNTER_CENTER_DOWN: center-aligned and counting down assert mode + \arg TIMER_COUNTER_CENTER_UP: center-aligned and counting up assert mode + \arg TIMER_COUNTER_CENTER_BOTH: center-aligned and counting up/down assert mode + \param[out] none + \retval none +*/ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned) +{ + TIMER_CTL0(timer_periph) &= (uint32_t)(~TIMER_CTL0_CAM); + TIMER_CTL0(timer_periph) |= (uint32_t)aligned; +} + +/*! + \brief set TIMER counter up direction + \param[in] timer_periph: TIMERx(x=0..4) + \param[out] none + \retval none +*/ +void timer_counter_up_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief set TIMER counter down direction + \param[in] timer_periph: TIMERx(x=0..4) + \param[out] none + \retval none +*/ +void timer_counter_down_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief configure TIMER prescaler + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] prescaler: prescaler value + \param[in] pscreload: prescaler reload mode + only one parameter can be selected which is shown as below: + \arg TIMER_PSC_RELOAD_NOW: the prescaler is loaded right now + \arg TIMER_PSC_RELOAD_UPDATE: the prescaler is loaded at the next update event + \param[out] none + \retval none +*/ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint32_t pscreload) +{ + TIMER_PSC(timer_periph) = (uint32_t)prescaler; + + if(TIMER_PSC_RELOAD_NOW == pscreload){ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; + } +} + +/*! + \brief configure TIMER repetition register value + \param[in] timer_periph: TIMERx(x=0) + \param[in] repetition: the counter repetition value, 0~255 + \param[out] none + \retval none +*/ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition) +{ + TIMER_CREP(timer_periph) = (uint32_t)repetition; +} + +/*! + \brief configure TIMER autoreload register value + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] autoreload: the counter auto-reload value + \param[out] none + \retval none +*/ +void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload) +{ + TIMER_CAR(timer_periph) = (uint32_t)autoreload; +} + +/*! + \brief configure TIMER counter register value + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] counter: the counter value + \param[out] none + \retval none +*/ +void timer_counter_value_config(uint32_t timer_periph, uint16_t counter) +{ + TIMER_CNT(timer_periph) = (uint32_t)counter; +} + +/*! + \brief read TIMER counter value + \param[in] timer_periph: TIMERx(x=0..6) + \param[out] none + \retval counter value +*/ +uint32_t timer_counter_read(uint32_t timer_periph) +{ + uint32_t count_value = 0U; + count_value = TIMER_CNT(timer_periph); + return (count_value); +} + +/*! + \brief read TIMER prescaler value + \param[in] timer_periph: TIMERx(x=0..6) + \param[out] none + \retval prescaler register value +*/ +uint16_t timer_prescaler_read(uint32_t timer_periph) +{ + uint16_t prescaler_value = 0U; + prescaler_value = (uint16_t) (TIMER_PSC(timer_periph)); + return (prescaler_value); +} + +/*! + \brief configure TIMER single pulse mode + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] spmode: + only one parameter can be selected which is shown as below: + \arg TIMER_SP_MODE_SINGLE: single pulse mode + \arg TIMER_SP_MODE_REPETITIVE: repetitive pulse mode + \param[out] none + \retval none +*/ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode) +{ + if(TIMER_SP_MODE_SINGLE == spmode){ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_SPM; + }else if(TIMER_SP_MODE_REPETITIVE == spmode){ + TIMER_CTL0(timer_periph) &= ~((uint32_t)TIMER_CTL0_SPM); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER update source + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] update: + only one parameter can be selected which is shown as below: + \arg TIMER_UPDATE_SRC_GLOBAL: update generate by setting of UPG bit or the counter overflow/underflow, + or the slave mode controller trigger + \arg TIMER_UPDATE_SRC_REGULAR: update generate only by counter overflow/underflow + \param[out] none + \retval none +*/ +void timer_update_source_config(uint32_t timer_periph, uint32_t update) +{ + if(TIMER_UPDATE_SRC_REGULAR == update){ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS; + }else if(TIMER_UPDATE_SRC_GLOBAL == update){ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable the TIMER DMA + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] dma: specify which DMA to enable + one or more parameters can be selected which are shown as below: + \arg TIMER_DMA_UPD: update DMA enable, TIMERx(x=0..6) + \arg TIMER_DMA_CH0D: channel 0 DMA enable, TIMERx(x=0..4) + \arg TIMER_DMA_CH1D: channel 1 DMA enable, TIMERx(x=0..4) + \arg TIMER_DMA_CH2D: channel 2 DMA enable, TIMERx(x=0..4) + \arg TIMER_DMA_CH3D: channel 3 DMA enable, TIMERx(x=0..4) + \arg TIMER_DMA_CMTD: channel commutation DMA request enable, TIMERx(x=0) + \arg TIMER_DMA_TRGD: trigger DMA enable, TIMERx(x=0..4) + \param[out] none + \retval none +*/ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; +} + +/*! + \brief disable the TIMER DMA + \param[in] timer_periph: TIMERxTIMERx(x=0..6) + \param[in] dma: specify which DMA to disbale + one or more parameters can be selected which are shown as below: + \arg TIMER_DMA_UPD: update DMA enable, TIMERx(x=0..6) + \arg TIMER_DMA_CH0D: channel 0 DMA enable, TIMERx(x=0..4) + \arg TIMER_DMA_CH1D: channel 1 DMA enable, TIMERx(x=0..4) + \arg TIMER_DMA_CH2D: channel 2 DMA enable, TIMERx(x=0..4) + \arg TIMER_DMA_CH3D: channel 3 DMA enable, TIMERx(x=0..4) + \arg TIMER_DMA_CMTD: channel commutation DMA request enable, TIMERx(x=0) + \arg TIMER_DMA_TRGD: trigger DMA enable, TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(dma)); +} + +/*! + \brief channel DMA request source selection + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] dma_request: channel DMA request source selection + only one parameter can be selected which is shown as below: + \arg TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel n is sent when channel n event occurs + \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel n is sent when update event occurs + \param[out] none + \retval none +*/ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint32_t dma_request) +{ + if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS; + }else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request){ + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_DMAS; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure the TIMER DMA transfer + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] dma_baseaddr: + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATA_CTL0: DMA transfer address is TIMER_CTL0, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP, TIMERx(x=0) + \arg TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV, TIMERx(x=0..4) + \arg TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP, TIMERx(x=0) + \arg TIMER_DMACFG_DMATA_DMACFG: DMA transfer address is TIMER_DMACFG, TIMERx(x=0..4) + \param[in] dma_lenth: + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATC_xTRANSFER(x=1..6): DMA transfer x time + \param[out] none + \retval none +*/ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth) +{ + TIMER_DMACFG(timer_periph) &= (~(uint32_t)(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC)); + TIMER_DMACFG(timer_periph) |= (uint32_t)(dma_baseaddr | dma_lenth); +} + +/*! + \brief software generate events + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] event: the timer software event generation sources + one or more parameters can be selected which are shown as below: + \arg TIMER_EVENT_SRC_UPG: update event generation, TIMERx(x=0..6) + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation, TIMERx(x=0..4) + \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation, TIMERx(x=0..4) + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation, TIMERx(x=0..4) + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation, TIMERx(x=0..4) + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation, TIMERx(x=0) + \arg TIMER_EVENT_SRC_TRGG: trigger event generation, TIMERx(x=0..4) + \arg TIMER_EVENT_SRC_BRKG: break event generation, TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_event_software_generate(uint32_t timer_periph, uint16_t event) +{ + TIMER_SWEVG(timer_periph) |= (uint32_t)event; +} + +/*! + \brief initialize TIMER break parameter struct with a default value + \param[in] breakpara: TIMER break parameter struct + \param[out] none + \retval none +*/ +void timer_break_struct_para_init(timer_break_parameter_struct* breakpara) +{ + /* initialize the break parameter struct member with the default value */ + breakpara->runoffstate = TIMER_ROS_STATE_DISABLE; + breakpara->ideloffstate = TIMER_IOS_STATE_DISABLE; + breakpara->deadtime = 0U; + breakpara->breakpolarity = TIMER_BREAK_POLARITY_LOW; + breakpara->outputautostate = TIMER_OUTAUTO_DISABLE; + breakpara->protectmode = TIMER_CCHP_PROT_OFF; + breakpara->breakstate = TIMER_BREAK_DISABLE; +} + +/*! + \brief configure TIMER break function + \param[in] timer_periph: TIMERx(x=0) + \param[in] breakpara: TIMER break parameter struct + runoffstate: TIMER_ROS_STATE_ENABLE, TIMER_ROS_STATE_DISABLE + ideloffstate: TIMER_IOS_STATE_ENABLE, TIMER_IOS_STATE_DISABLE + deadtime: 0~255 + breakpolarity: TIMER_BREAK_POLARITY_LOW, TIMER_BREAK_POLARITY_HIGH + outputautostate: TIMER_OUTAUTO_ENABLE, TIMER_OUTAUTO_DISABLE + protectmode: TIMER_CCHP_PROT_OFF, TIMER_CCHP_PROT_0, TIMER_CCHP_PROT_1, TIMER_CCHP_PROT_2 + breakstate: TIMER_BREAK_ENABLE, TIMER_BREAK_DISABLE + \param[out] none + \retval none +*/ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara) +{ + TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate)) | + ((uint32_t)(breakpara->ideloffstate))| + ((uint32_t)(breakpara->deadtime)) | + ((uint32_t)(breakpara->breakpolarity)) | + ((uint32_t)(breakpara->outputautostate)) | + ((uint32_t)(breakpara->protectmode)) | + ((uint32_t)(breakpara->breakstate))); +} + +/*! + \brief enable TIMER break function + \param[in] timer_periph: TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_break_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief disable TIMER break function + \param[in] timer_periph: TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_break_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief enable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_automatic_output_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief disable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_automatic_output_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief enable or disable TIMER primary output function + \param[in] timer_periph: TIMERx(x=0) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue){ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_POEN; + }else{ + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_POEN); + } +} + +/*! + \brief enable or disable channel capture/compare control shadow register + \param[in] timer_periph: TIMERx(x=0) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCSE; + }else{ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCSE); + } +} + +/*! + \brief configure TIMER channel control shadow register update control + \param[in] timer_periph: TIMERx(x=0) + \param[in] ccuctl: channel control shadow register update control + only one parameter can be selected which is shown as below: + \arg TIMER_UPDATECTL_CCU: the shadow registers update by when CMTG bit is set + \arg TIMER_UPDATECTL_CCUTRI: the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint32_t ccuctl) +{ + if(TIMER_UPDATECTL_CCU == ccuctl){ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC); + }else if(TIMER_UPDATECTL_CCUTRI == ccuctl){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief initialize TIMER channel output parameter struct with a default value + \param[in] ocpara: TIMER channel n output parameter struct + \param[out] none + \retval none +*/ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara) +{ + /* initialize the channel output parameter struct member with the default value */ + ocpara->outputstate = TIMER_CCX_DISABLE; + ocpara->outputnstate = TIMER_CCXN_DISABLE; + ocpara->ocpolarity = TIMER_OC_POLARITY_HIGH; + ocpara->ocnpolarity = TIMER_OCN_POLARITY_HIGH; + ocpara->ocidlestate = TIMER_OC_IDLE_STATE_LOW; + ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; +} + +/*! + \brief configure TIMER channel output function + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[in] ocpara: TIMER channeln output parameter struct + outputstate: TIMER_CCX_ENABLE, TIMER_CCX_DISABLE + outputnstate: TIMER_CCXN_ENABLE, TIMER_CCXN_DISABLE + ocpolarity: TIMER_OC_POLARITY_HIGH, TIMER_OC_POLARITY_LOW + ocnpolarity: TIMER_OCN_POLARITY_HIGH, TIMER_OCN_POLARITY_LOW + ocidlestate: TIMER_OC_IDLE_STATE_LOW, TIMER_OC_IDLE_STATE_HIGH + ocnidlestate: TIMER_OCN_IDLE_STATE_LOW, TIMER_OCN_IDLE_STATE_HIGH + \param[out] none + \retval none +*/ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct* ocpara) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputstate; + /* reset the CH0P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + /* set the CH0P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocpolarity; + + if (TIMER0 == timer_periph) { + /* reset the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); + /* set the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputnstate; + /* reset the CH0NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP); + /* set the CH0NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocnpolarity; + /* reset the ISO0 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0); + /* set the ISO0 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocidlestate; + /* reset the ISO0N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0N); + /* set the ISO0N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocnidlestate; + } + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH0MS; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputstate) << 4U); + /* reset the CH1P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + /* set the CH1P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 4U); + + if (TIMER0 == timer_periph) { + /* reset the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); + /* set the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 4U); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 4U); + /* reset the ISO1 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1); + /* set the ISO1 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 2U); + /* reset the ISO1N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1N); + /* set the ISO1N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 2U); + } + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH1MS; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputstate) << 8U); + /* reset the CH2P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + /* set the CH2P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 8U); + + if (TIMER0 == timer_periph) { + /* reset the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); + /* set the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 8U); + /* reset the CH2NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP); + /* set the CH2NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 8U); + /* reset the ISO2 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2); + /* set the ISO2 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 4U); + /* reset the ISO2N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2N); + /* set the ISO2N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 4U); + } + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH2MS; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &=(~(uint32_t)TIMER_CHCTL2_CH3EN); + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputstate) << 12U); + /* reset the CH3P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + /* set the CH3P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 12U); + + if (TIMER0 == timer_periph) { + /* reset the ISO3 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3); + /* set the ISO3 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 6U); + } + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH3MS; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output compare mode + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[in] ocmode: channel output compare mode + only one parameter can be selected which is shown as below: + \arg TIMER_OC_MODE_TIMING: timing mode + \arg TIMER_OC_MODE_ACTIVE: active mode + \arg TIMER_OC_MODE_INACTIVE: inactive mode + \arg TIMER_OC_MODE_TOGGLE: toggle mode + \arg TIMER_OC_MODE_LOW: force low mode + \arg TIMER_OC_MODE_HIGH: force high mode + \arg TIMER_OC_MODE_PWM0: PWM mode 0 + \arg TIMER_OC_MODE_PWM1: PWM mode 1 + \param[out] none + \retval none +*/ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output pulse value + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[in] pulse: channel output pulse value + \param[out] none + \retval none +*/ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = (uint32_t)pulse; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output shadow function + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[in] ocshadow: channel output shadow state + only one parameter can be selected which is shown as below: + \arg TIMER_OC_SHADOW_ENABLE: channel output shadow state enable + \arg TIMER_OC_SHADOW_DISABLE: channel output shadow state disable + \param[out] none + \retval none +*/ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output fast function + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[in] ocfast: channel output fast function + only one parameter can be selected which is shown as below: + \arg TIMER_OC_FAST_ENABLE: channel output fast function enable + \arg TIMER_OC_FAST_DISABLE: channel output fast function disable + \param[out] none + \retval none +*/ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output clear function + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..41)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[in] occlear: channel output clear function + only one parameter can be selected which is shown as below: + \arg TIMER_OC_CLEAR_ENABLE: channel output clear function enable + \arg TIMER_OC_CLEAR_DISABLE: channel output clear function disable + \param[out] none + \retval none +*/ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output polarity + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[in] ocpolarity: channel output polarity + only one parameter can be selected which is shown as below: + \arg TIMER_OC_POLARITY_HIGH: channel output polarity is high + \arg TIMER_OC_POLARITY_LOW: channel output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output polarity + \param[in] timer_periph: TIMERx(x=0) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0)) + \param[in] ocnpolarity: channel complementary output polarity + only one parameter can be selected which is shown as below: + \arg TIMER_OCN_POLARITY_HIGH: channel complementary output polarity is high + \arg TIMER_OCN_POLARITY_LOW: channel complementary output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel enable state + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[in] state: TIMER channel enable state + only one parameter can be selected which is shown as below: + \arg TIMER_CCX_ENABLE: channel enable + \arg TIMER_CCX_DISABLE: channel disable + \param[out] none + \retval none +*/ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)state; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output enable state + \param[in] timer_periph: TIMERx(x=0) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0 + \arg TIMER_CH_1: TIMER channel 1 + \arg TIMER_CH_2: TIMER channel 2 + \param[in] ocnstate: TIMER channel complementary output enable state + only one parameter can be selected which is shown as below: + \arg TIMER_CCXN_ENABLE: channel complementary enable + \arg TIMER_CCXN_DISABLE: channel complementary disable + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnstate; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 8U); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER channel input parameter struct with a default value + \param[in] icpara: TIMER channel intput parameter struct + \param[out] none + \retval none +*/ +void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara) +{ + /* initialize the channel input parameter struct member with the default value */ + icpara->icpolarity = TIMER_IC_POLARITY_RISING; + icpara->icselection = TIMER_IC_SELECTION_DIRECTTI; + icpara->icprescaler = TIMER_IC_PSC_DIV1; + icpara->icfilter = 0U; +} + +/*! + \brief configure TIMER input capture parameter + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[in] icpara: TIMER channel intput parameter struct + icpolarity: TIMER_IC_POLARITY_RISING, TIMER_IC_POLARITY_FALLING, + TIMER_IC_POLARITY_BOTH_EDGE(only for TIMER1~TIMER8) + icselection: TIMER_IC_SELECTION_DIRECTTI, TIMER_IC_SELECTION_INDIRECTTI, + TIMER_IC_SELECTION_ITS + icprescaler: TIMER_IC_PSC_DIV1, TIMER_IC_PSC_DIV2, TIMER_IC_PSC_DIV4, + TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpara) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpara->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpara->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U); + + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + break; + + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + + /* reset the CH2P and CH2NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P | TIMER_CHCTL2_CH2NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 8U); + + /* reset the CH2MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection)); + + /* reset the CH2CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U); + + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + + /* reset the CH3P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH3P)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 12U); + + /* reset the CH3MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U); + + /* reset the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN; + break; + default: + break; + } + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, channel, (uint16_t)(icpara->icprescaler)); +} + +/*! + \brief configure TIMER channel input capture prescaler value + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[in] prescaler: channel input capture prescaler value + only one parameter can be selected which is shown as below: + \arg TIMER_IC_PSC_DIV1: no prescaler + \arg TIMER_IC_PSC_DIV2: divided by 2 + \arg TIMER_IC_PSC_DIV4: divided by 4 + \arg TIMER_IC_PSC_DIV8: divided by 8 + \param[out] none + \retval none +*/ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC); + TIMER_CHCTL0(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPPSC); + TIMER_CHCTL0(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPPSC); + TIMER_CHCTL1(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPPSC); + TIMER_CHCTL1(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + default: + break; + } +} + +/*! + \brief read TIMER channel capture compare register value + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4)) + \param[out] none + \retval channel capture compare register value +*/ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel) +{ + uint32_t count_value = 0U; + + switch(channel){ + case TIMER_CH_0: + /* read TIMER channel 0 capture compare register value */ + count_value = TIMER_CH0CV(timer_periph); + break; + case TIMER_CH_1: + /* read TIMER channel 1 capture compare register value */ + count_value = TIMER_CH1CV(timer_periph); + break; + case TIMER_CH_2: + /* read TIMER channel 2 capture compare register value */ + count_value = TIMER_CH2CV(timer_periph); + break; + case TIMER_CH_3: + /* read TIMER channel 3 capture compare register value */ + count_value = TIMER_CH3CV(timer_periph); + break; + default: + break; + } + return (count_value); +} + +/*! + \brief configure TIMER input pwm capture function + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0 + \arg TIMER_CH_1: TIMER channel 1 + \param[in] icpwm: TIMER channel intput pwm parameter struct + icpolarity: TIMER_IC_POLARITY_RISING, TIMER_IC_POLARITY_FALLING + icselection: TIMER_IC_SELECTION_DIRECTTI, TIMER_IC_SELECTION_INDIRECTTI + icprescaler: TIMER_IC_PSC_DIV1, TIMER_IC_PSC_DIV2, TIMER_IC_PSC_DIV4, + TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm) +{ + uint16_t icpolarity = 0x0U; + uint16_t icselection = 0x0U; + + /* Set channel input polarity */ + if(TIMER_IC_POLARITY_RISING == icpwm->icpolarity){ + icpolarity = TIMER_IC_POLARITY_FALLING; + }else{ + icpolarity = TIMER_IC_POLARITY_RISING; + } + /* Set channel input mode selection */ + if(TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection){ + icselection = TIMER_IC_SELECTION_INDIRECTTI; + }else{ + icselection = TIMER_IC_SELECTION_DIRECTTI; + } + + if(TIMER_CH_0 == channel){ + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpwm->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpwm->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_0, (uint16_t)(icpwm->icprescaler)); + + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpolarity<< 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icselection << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icfilter) << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_1, (uint16_t)(icpwm->icprescaler)); + }else{ + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icpolarity) << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icselection) << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icfilter) << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_1, (uint16_t)(icpwm->icprescaler)); + + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)icpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)icselection; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_0, (uint16_t)(icpwm->icprescaler)); + } +} + +/*! + \brief configure TIMER hall sensor mode + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] hallmode: + only one parameter can be selected which is shown as below: + \arg TIMER_HALLINTERFACE_ENABLE: TIMER hall sensor mode enable + \arg TIMER_HALLINTERFACE_DISABLE: TIMER hall sensor mode disable + \param[out] none + \retval none +*/ +void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode) +{ + if(TIMER_HALLINTERFACE_ENABLE == hallmode){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_TI0S; + }else if(TIMER_HALLINTERFACE_DISABLE == hallmode){ + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_TI0S; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief select TIMER input trigger source + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] intrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0..4)) + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0..4)) + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0..4)) + \arg TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3(TIMERx(x=0..4)) + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector(TIMERx(x=0..4)) + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0(TIMERx(x=0..4)) + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1(TIMERx(x=0..4)) + \arg TIMER_SMCFG_TRGSEL_ETIFP: filtered external trigger input(TIMERx(x=0..4)) + \param[out] none + \retval none +*/ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_TRGS); + TIMER_SMCFG(timer_periph) |= (uint32_t)intrigger; +} + +/*! + \brief select TIMER master mode output trigger source + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] outrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_TRI_OUT_SRC_RESET: the UPG bit as trigger output(TIMERx(x=0..6)) + \arg TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output(TIMERx(x=0..6)) + \arg TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output(TIMERx(x=0..6)) + \arg TIMER_TRI_OUT_SRC_CH0: a capture or a compare match occurred in channel 0 as trigger output TRGO(TIMERx(x=0..4)) + \arg TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output(TIMERx(x=0..4)) + \arg TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output(TIMERx(x=0..4)) + \arg TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output(TIMERx(x=0..4)) + \arg TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output(TIMERx(x=0..4)) + \param[out] none + \retval none +*/ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger) +{ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_MMC); + TIMER_CTL1(timer_periph) |= (uint32_t)outrigger; +} + +/*! + \brief select TIMER slave mode + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] slavemode: + only one parameter can be selected which is shown as below: + \arg TIMER_SLAVE_MODE_DISABLE: slave mode disable + \arg TIMER_ENCODER_MODE0: encoder mode 0 + \arg TIMER_ENCODER_MODE1: encoder mode 1 + \arg TIMER_ENCODER_MODE2: encoder mode 2 + \arg TIMER_SLAVE_MODE_RESTART: restart mode + \arg TIMER_SLAVE_MODE_PAUSE: pause mode + \arg TIMER_SLAVE_MODE_EVENT: event mode + \arg TIMER_SLAVE_MODE_EXTERNAL0: external clock mode 0 + \param[out] none + \retval none +*/ + +void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + TIMER_SMCFG(timer_periph) |= (uint32_t)slavemode; +} + +/*! + \brief configure TIMER master slave mode + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] masterslave: + only one parameter can be selected which is shown as below: + \arg TIMER_MASTER_SLAVE_MODE_ENABLE: master slave mode enable + \arg TIMER_MASTER_SLAVE_MODE_DISABLE: master slave mode disable + \param[out] none + \retval none +*/ +void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave) +{ + if(TIMER_MASTER_SLAVE_MODE_ENABLE == masterslave){ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_MSM; + }else if(TIMER_MASTER_SLAVE_MODE_DISABLE == masterslave){ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_MSM; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER external trigger input + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] extprescaler: + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_ETP | TIMER_SMCFG_ETPSC | TIMER_SMCFG_ETFC)); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extprescaler | extpolarity); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extfilter << 8U); +} + +/*! + \brief configure TIMER quadrature decoder mode + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] decomode: + only one parameter can be selected which is shown as below: + \arg TIMER_ENCODER_MODE0: counter counts on CI0FE0 edge depending on CI1FE1 level + \arg TIMER_ENCODER_MODE1: counter counts on CI1FE1 edge depending on CI0FE0 level + \arg TIMER_ENCODER_MODE2: counter counts on both CI0FE0 and CI1FE1 edges depending on the level of the other input + \param[in] ic0polarity: + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[in] ic1polarity: + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[out] none + \retval none +*/ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity) +{ + /* configure the quadrature decoder mode */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + TIMER_SMCFG(timer_periph) |= (uint32_t)decomode; + /* configure input capture selection */ + TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS)) & ((~(uint32_t)TIMER_CHCTL0_CH1MS))); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI | ((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U)); + /* configure channel input capture polarity */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ic0polarity | ((uint32_t)ic1polarity << 4U)); +} + +/*! + \brief configure TIMER internal clock mode + \param[in] timer_periph: TIMERx(x=0..4) + \param[out] none + \retval none +*/ +void timer_internal_clock_config(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; +} + +/*! + \brief configure TIMER the internal trigger as external clock input + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] intrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0 + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1 + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2 + \arg TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3 + \param[out] none + \retval none +*/ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger) +{ + timer_input_trigger_source_select(timer_periph, intrigger); + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external trigger as external clock input + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] extrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0 + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: active low or falling edge active + \arg TIMER_IC_POLARITY_FALLING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity, uint32_t extfilter) +{ + if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger){ + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)extpolarity << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(extfilter << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + }else{ + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)extpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)TIMER_IC_SELECTION_DIRECTTI; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(extfilter << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + } + /* select TIMER input trigger source */ + timer_input_trigger_source_select(timer_periph, extrigger); + /* reset the SMC bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + /* set the SMC bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external clock mode0 + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] extprescaler: + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter); + /* reset the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_SMC | TIMER_SMCFG_TRGS)); + /* set the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)(TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_ETIFP); +} + +/*! + \brief configure TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0..4) + \param[in] extprescaler: + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter); + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief disable TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0..4) + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_disable(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief enable the TIMER interrupt + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: specify which interrupt to enable + one or more parameters can be selected which are shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0..6) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4) + \arg TIMER_INT_CH3: channel 3 interrupt enable, TIMERx(x=0..4) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) interrupt; +} + +/*! + \brief disable the TIMER interrupt + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] interrupt: specify which interrupt to disbale + one or more parameters can be selected which are shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0..6) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)interrupt); +} + +/*! + \brief get timer interrupt flag + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] interrupt: the timer interrupt bits + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0..6) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag, TIMERx(x=0..4) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag, TIMERx(x=0..4) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag, TIMERx(x=0..4) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag, TIMERx(x=0..4) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0) + \arg TIMER_INT_FLAG_BRK: break interrupt flag, TIMERx(x=0) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt) +{ + uint32_t val; + val = (TIMER_DMAINTEN(timer_periph) & interrupt); + if((RESET != (TIMER_INTF(timer_periph) & interrupt)) && (RESET != val)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER interrupt flag + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] interrupt: the timer interrupt bits + one or more parameters can be selected which are shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0..6) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag, TIMERx(x=0..4) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag, TIMERx(x=0..4) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag, TIMERx(x=0..4) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag, TIMERx(x=0..4) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0) + \arg TIMER_INT_FLAG_BRK: break interrupt flag, TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_INTF(timer_periph) = (~(uint32_t)interrupt); +} + +/*! + \brief get TIMER flags + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag, TIMERx(x=0..6) + \arg TIMER_FLAG_CH0: channel 0 flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH1: channel 1 flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH2: channel 2 flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH3: channel 3 flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CMT: channel commutation flag, TIMERx(x=0) + \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0) + \arg TIMER_FLAG_BRK: break flag, TIMERx(x=0) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0..4) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) +{ + if(RESET != (TIMER_INTF(timer_periph) & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER flags + \param[in] timer_periph: TIMERx(x=0..6) + \param[in] flag: the timer interrupt flags + one or more parameters can be selected which are shown as below: + \arg TIMER_FLAG_UP: update flag, TIMERx(x=0..6) + \arg TIMER_FLAG_CH0: channel 0 flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH1: channel 1 flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH2: channel 2 flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH3: channel 3 flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CMT: channel commutation flag, TIMERx(x=0) + \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0) + \arg TIMER_FLAG_BRK: break flag, TIMERx(x=0) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0..4) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0..4) + \param[out] none + \retval none +*/ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag) +{ + TIMER_INTF(timer_periph) = (~(uint32_t)flag); +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_usart.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_usart.c new file mode 100644 index 0000000000000000000000000000000000000000..77c9a5159b199994cdd1c9069559a9bbe0ac5fb7 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_usart.c @@ -0,0 +1,764 @@ +/*! + \file gd32vf103_usart.c + \brief USART driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_usart.h" + +/*! + \brief reset USART/UART + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_deinit(uint32_t usart_periph) +{ + switch(usart_periph){ + case USART0: + /* reset USART0 */ + rcu_periph_reset_enable(RCU_USART0RST); + rcu_periph_reset_disable(RCU_USART0RST); + break; + case USART1: + /* reset USART1 */ + rcu_periph_reset_enable(RCU_USART1RST); + rcu_periph_reset_disable(RCU_USART1RST); + break; + case USART2: + /* reset USART2 */ + rcu_periph_reset_enable(RCU_USART2RST); + rcu_periph_reset_disable(RCU_USART2RST); + break; + case UART3: + /* reset UART3 */ + rcu_periph_reset_enable(RCU_UART3RST); + rcu_periph_reset_disable(RCU_UART3RST); + break; + case UART4: + /* reset UART4 */ + rcu_periph_reset_enable(RCU_UART4RST); + rcu_periph_reset_disable(RCU_UART4RST); + break; + default: + break; + } +} + +/*! + \brief configure USART baud rate value + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] baudval: baud rate value + \param[out] none + \retval none +*/ +void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval) +{ + uint32_t uclk=0U, intdiv=0U, fradiv=0U, udiv=0U; + switch(usart_periph){ + /* get clock frequency */ + case USART0: + /* get USART0 clock */ + uclk=rcu_clock_freq_get(CK_APB2); + break; + case USART1: + /* get USART1 clock */ + uclk=rcu_clock_freq_get(CK_APB1); + break; + case USART2: + /* get USART2 clock */ + uclk=rcu_clock_freq_get(CK_APB1); + break; + case UART3: + /* get UART3 clock */ + uclk=rcu_clock_freq_get(CK_APB1); + break; + case UART4: + /* get UART4 clock */ + uclk=rcu_clock_freq_get(CK_APB1); + break; + default: + break; + } + /* oversampling by 16, configure the value of USART_BAUD */ + udiv = (uclk+baudval/2U)/baudval; + intdiv = udiv & (0x0000fff0U); + fradiv = udiv & (0x0000000fU); + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); +} + +/*! + \brief configure USART parity + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] paritycfg: configure USART parity + only one parameter can be selected which is shown as below: + \arg USART_PM_NONE: no parity + \arg USART_PM_ODD: odd parity + \arg USART_PM_EVEN: even parity + \param[out] none + \retval none +*/ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg) +{ + /* clear USART_CTL0 PM,PCEN bits */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN); + /* configure USART parity mode */ + USART_CTL0(usart_periph) |= paritycfg ; +} + +/*! + \brief configure USART word length + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] wlen: USART word length configure + only one parameter can be selected which is shown as below: + \arg USART_WL_8BIT: 8 bits + \arg USART_WL_9BIT: 9 bits + \param[out] none + \retval none +*/ +void usart_word_length_set(uint32_t usart_periph, uint32_t wlen) +{ + /* clear USART_CTL0 WL bit */ + USART_CTL0(usart_periph) &= ~USART_CTL0_WL; + /* configure USART word length */ + USART_CTL0(usart_periph) |= wlen; +} + +/*! + \brief configure USART stop bit length + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] stblen: USART stop bit configure + only one parameter can be selected which is shown as below: + \arg USART_STB_1BIT: 1 bit + \arg USART_STB_0_5BIT: 0.5 bit, not available for UARTx(x=3,4) + \arg USART_STB_2BIT: 2 bits + \arg USART_STB_1_5BIT: 1.5 bits, not available for UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen) +{ + /* clear USART_CTL1 STB bits */ + USART_CTL1(usart_periph) &= ~USART_CTL1_STB; + /* configure USART stop bits */ + USART_CTL1(usart_periph) |= stblen; +} + +/*! + \brief enable USART + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UEN; +} + +/*! + \brief disable USART + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); +} + +/*! + \brief configure USART transmitter + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] txconfig: enable or disable USART transmitter + only one parameter can be selected which is shown as below: + \arg USART_TRANSMIT_ENABLE: enable USART transmission + \arg USART_TRANSMIT_DISABLE: disable USART transmission + \param[out] none + \retval none +*/ +void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL0(usart_periph); + ctl &= ~USART_CTL0_TEN; + ctl |= txconfig; + /* configure transfer mode */ + USART_CTL0(usart_periph) = ctl; +} + +/*! + \brief configure USART receiver + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] rxconfig: enable or disable USART receiver + only one parameter can be selected which is shown as below: + \arg USART_RECEIVE_ENABLE: enable USART reception + \arg USART_RECEIVE_DISABLE: disable USART reception + \param[out] none + \retval none +*/ +void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL0(usart_periph); + ctl &= ~USART_CTL0_REN; + ctl |= rxconfig; + /* configure receiver mode */ + USART_CTL0(usart_periph) = ctl; +} + +/*! + \brief USART transmit data function + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void usart_data_transmit(uint32_t usart_periph, uint32_t data) +{ + USART_DATA(usart_periph) = USART_DATA_DATA & data; +} + +/*! + \brief USART receive data function + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval data of received +*/ +uint16_t usart_data_receive(uint32_t usart_periph) +{ + return (uint16_t)(GET_BITS(USART_DATA(usart_periph), 0U, 8U)); +} + +/*! + \brief configure the address of the USART in wake up by address match mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] addr: address of USART/UART + \param[out] none + \retval none +*/ +void usart_address_config(uint32_t usart_periph, uint8_t addr) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & addr); +} + +/*! + \brief receiver in mute mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_mute_mode_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_RWU; +} + +/*! + \brief receiver in active mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_mute_mode_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_RWU); +} + +/*! + \brief configure wakeup method in mute mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] wmethod: two methods be used to enter or exit the mute mode + only one parameter can be selected which is shown as below: + \arg USART_WM_IDLE: idle line + \arg USART_WM_ADDR: address mask + \param[out] none + \retval none +*/ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_WM); + USART_CTL0(usart_periph) |= wmethod; +} + +/*! + \brief enable LIN mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_lin_mode_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_LMEN; +} + +/*! + \brief disable LIN mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_lin_mode_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); +} + +/*! + \brief configure lin break frame length + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] lblen: lin break frame length + only one parameter can be selected which is shown as below: + \arg USART_LBLEN_10B: 10 bits + \arg USART_LBLEN_11B: 11 bits + \param[out] none + \retval none +*/ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN); + USART_CTL1(usart_periph) |= (USART_CTL1_LBLEN & lblen); +} + +/*! + \brief send break frame + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_send_break(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_SBKCMD; +} + +/*! + \brief enable half duplex mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_halfduplex_enable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) |= USART_CTL2_HDEN; +} + +/*! + \brief disable half duplex mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_halfduplex_disable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN); +} + +/*! + \brief enable CK pin in synchronous mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_synchronous_clock_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_CKEN; +} + +/*! + \brief disable CK pin in synchronous mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_synchronous_clock_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN); +} + +/*! + \brief configure USART synchronous mode parameters + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] clen: CK length + only one parameter can be selected which is shown as below: + \arg USART_CLEN_NONE: there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame + \arg USART_CLEN_EN: there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame + \param[in] cph: clock phase + only one parameter can be selected which is shown as below: + \arg USART_CPH_1CK: first clock transition is the first data capture edge + \arg USART_CPH_2CK: second clock transition is the first data capture edge + \param[in] cpl: clock polarity + only one parameter can be selected which is shown as below: + \arg USART_CPL_LOW: steady low value on CK pin + \Rag USART_CPL_HIGH: steady high value on CK pin + \param[out] none + \retval none +*/ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl) +{ + uint32_t ctl = 0U; + + /* read USART_CTL1 register */ + ctl = USART_CTL1(usart_periph); + ctl &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL); + /* set CK length, CK phase, CK polarity */ + ctl |= (USART_CTL1_CLEN & clen) | (USART_CTL1_CPH & cph) | (USART_CTL1_CPL & cpl); + + USART_CTL1(usart_periph) = ctl; +} + +/*! + \brief configure guard time value in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] gaut: guard time value + \param[out] none + \retval none +*/ +void usart_guard_time_config(uint32_t usart_periph,uint32_t gaut) +{ + USART_GP(usart_periph) &= ~(USART_GP_GUAT); + USART_GP(usart_periph) |= (USART_GP_GUAT & ((gaut)<<8)); +} + +/*! + \brief enable smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_enable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) |= USART_CTL2_SCEN; +} + +/*! + \brief disable smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_disable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN); +} + +/*! + \brief enable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) |= USART_CTL2_NKEN; +} + +/*! + \brief disable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN); +} + +/*! + \brief enable IrDA mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_irda_mode_enable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) |= USART_CTL2_IREN; +} + +/*! + \brief disable IrDA mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[out] none + \retval none +*/ +void usart_irda_mode_disable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN); +} + +/*! + \brief configure the peripheral clock prescaler in USART IrDA low-power mode + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] psc: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_prescaler_config(uint32_t usart_periph, uint8_t psc) +{ + USART_GP(usart_periph) &= ~(USART_GP_PSC); + USART_GP(usart_periph) |= psc; +} + +/*! + \brief configure IrDA low-power + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] irlp: IrDA low-power or normal + only one parameter can be selected which is shown as below: + \arg USART_IRLP_LOW: low-power + \arg USART_IRLP_NORMAL: normal + \param[out] none + \retval none +*/ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP); + USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp); +} + +/*! + \brief configure hardware flow control RTS + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] rtsconfig: enable or disable RTS + only one parameter can be selected which is shown as below: + \arg USART_RTS_ENABLE: enable RTS + \arg USART_RTS_DISABLE: disable RTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL2(usart_periph); + ctl &= ~USART_CTL2_RTSEN; + ctl |= rtsconfig; + /* configure RTS */ + USART_CTL2(usart_periph) = ctl; +} + +/*! + \brief configure hardware flow control CTS + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] ctsconfig: enable or disable CTS + only one parameter can be selected which is shown as below: + \arg USART_CTS_ENABLE: enable CTS + \arg USART_CTS_DISABLE: disable CTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL2(usart_periph); + ctl &= ~USART_CTL2_CTSEN; + ctl |= ctsconfig; + /* configure CTS */ + USART_CTL2(usart_periph) = ctl; +} + +/*! + \brief configure USART DMA reception + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3) + \param[in] dmacmd: enable or disable DMA for reception + only one parameter can be selected which is shown as below: + \arg USART_DENR_ENABLE: DMA enable for reception + \arg USART_DENR_DISABLE: DMA disable for reception + \param[out] none + \retval none +*/ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL2(usart_periph); + ctl &= ~USART_CTL2_DENR; + ctl |= dmacmd; + /* configure DMA reception */ + USART_CTL2(usart_periph) = ctl; +} + +/*! + \brief configure USART DMA transmission + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3) + \param[in] dmacmd: enable or disable DMA for transmission + only one parameter can be selected which is shown as below: + \arg USART_DENT_ENABLE: DMA enable for transmission + \arg USART_DENT_DISABLE: DMA disable for transmission + \param[out] none + \retval none +*/ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL2(usart_periph); + ctl &= ~USART_CTL2_DENT; + ctl |= dmacmd; + /* configure DMA transmission */ + USART_CTL2(usart_periph) = ctl; +} + +/*! + \brief get flag in STAT register + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] flag: USART flags, refer to usart_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_LBDF: LIN break detected flag + \arg USART_FLAG_TBE: transmit data buffer empty + \arg USART_FLAG_TC: transmission complete + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_IDLEF: IDLE frame detected flag + \arg USART_FLAG_ORERR: overrun error + \arg USART_FLAG_NERR: noise error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_PERR: parity error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag) +{ + if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear flag in STAT register + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] flag: USART flags, refer to usart_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_LBDF: LIN break detected flag + \arg USART_FLAG_TC: transmission complete + \arg USART_FLAG_RBNE: read data buffer not empty + \param[out] none + \retval none +*/ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) +{ + USART_REG_VAL(usart_periph, flag) &= ~BIT(USART_BIT_POS(flag)); +} + +/*! + \brief enable USART interrupt + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] int_flag + only one parameter can be selected which is shown as below: + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_TBE: transmitter buffer empty interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt + \arg USART_INT_IDLE: IDLE line detected interrupt + \arg USART_INT_LBD: LIN break detected interrupt + \arg USART_INT_ERR: error interrupt + \arg USART_INT_CTS: CTS interrupt + \param[out] none + \retval none +*/ +void usart_interrupt_enable(uint32_t usart_periph, uint32_t int_flag) +{ + USART_REG_VAL(usart_periph, int_flag) |= BIT(USART_BIT_POS(int_flag)); +} + +/*! + \brief disable USART interrupt + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] int_flag + only one parameter can be selected which is shown as below: + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_TBE: transmitter buffer empty interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt + \arg USART_INT_IDLE: IDLE line detected interrupt + \arg USART_INT_LBD: LIN break detected interrupt + \arg USART_INT_ERR: error interrupt + \arg USART_INT_CTS: CTS interrupt + \param[out] none + \retval none +*/ +void usart_interrupt_disable(uint32_t usart_periph, uint32_t int_flag) +{ + USART_REG_VAL(usart_periph, int_flag) &= ~BIT(USART_BIT_POS(int_flag)); +} + +/*! + \brief get USART interrupt and flag status + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] int_flag + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_PERR: parity error interrupt and flag + \arg USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag + \arg USART_INT_FLAG_TC: transmission complete interrupt and flag + \arg USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag + \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag + \arg USART_INT_FLAG_IDLE: IDLE line detected interrupt and flag + \arg USART_INT_FLAG_LBD: LIN break detected interrupt and flag + \arg USART_INT_FLAG_CTS: CTS interrupt and flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag + \arg USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U; + /* get the interrupt enable bit status */ + intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag))); + + if(flagstatus && intenable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear USART interrupt flag in STAT register + \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4) + \param[in] flag: USART interrupt flag + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_CTS: CTS change flag + \arg USART_INT_FLAG_LBD: LIN break detected flag + \arg USART_INT_FLAG_TC: transmission complete + \arg USART_INT_FLAG_RBNE: read data buffer not empty + \param[out] none + \retval none +*/ +void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t flag) +{ + USART_REG_VAL2(usart_periph, flag) &= ~BIT(USART_BIT_POS2(flag)); +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_wwdgt.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_wwdgt.c new file mode 100644 index 0000000000000000000000000000000000000000..e441348602e5060d3f5642af031aa569e965cf8b --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/Source/gd32vf103_wwdgt.c @@ -0,0 +1,146 @@ +/*! + \file gd32vf103_wwdgt.c + \brief WWDGT driver + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 "gd32vf103_wwdgt.h" + +/* write value to WWDGT_CTL_CNT bit field */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) +/* write value to WWDGT_CFG_WIN bit field */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) + +/*! + \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 = 0U; + + reg = (WWDGT_CTL & (~WWDGT_CTL_CNT)); + reg |= CTL_CNT(counter_value); + + WWDGT_CTL = 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 = 0U, reg_ctl = 0U; + + /* clear WIN and PSC bits, clear CNT bit */ + reg_cfg = (WWDGT_CFG &(~(WWDGT_CFG_WIN|WWDGT_CFG_PSC))); + reg_ctl = (WWDGT_CTL &(~WWDGT_CTL_CNT)); + + /* configure WIN and PSC bits, configure CNT bit */ + reg_cfg |= CFG_WIN(window); + reg_cfg |= prescaler; + reg_ctl |= CTL_CNT(counter); + + WWDGT_CTL = reg_ctl; + WWDGT_CFG = reg_cfg; +} + +/*! + \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 &= (~WWDGT_STAT_EWIF); +} diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/gd32vf103.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/gd32vf103.h new file mode 100644 index 0000000000000000000000000000000000000000..5bc3d94aecee97ad6b2ae7c4eff91f3c6ebf2721 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/gd32vf103.h @@ -0,0 +1,230 @@ +/*! + \file gd32vf103.h + \brief general definitions for GD32VF103 + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 +*/ + +/* + 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 GD32VF103_H +#define GD32VF103_H + +#ifdef cplusplus + extern "C" { +#endif + + /* IO definitions (access restrictions to peripheral registers) */ + /** + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. + */ + #ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ + #else + #define __I volatile const /*!< Defines 'read only' permissions */ + #endif + #define __O volatile /*!< Defines 'write only' permissions */ + #define __IO volatile /*!< Defines 'read / write' permissions */ + + +#define HXTAL_VALUE ((uint32_t)8000000) /*!< value of the external oscillator in Hz */ + +/* define startup timeout value of high speed crystal oscillator (HXTAL) */ +#if !defined (HXTAL_STARTUP_TIMEOUT) +#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0xFFFF) +#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 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 */ + +/* define interrupt number */ +typedef enum IRQn +{ + CLIC_INT_RESERVED = 0, /*!< RISC-V reserved */ + CLIC_INT_SFT = 3, /*!< Software interrupt */ + CLIC_INT_TMR = 7, /*!< CPU Timer interrupt */ + CLIC_INT_BWEI = 17, /*!< Bus Error interrupt */ + CLIC_INT_PMOVI = 18, /*!< Performance Monitor */ + + /* interruput numbers */ + WWDGT_IRQn = 19, /*!< window watchDog timer interrupt */ + LVD_IRQn = 20, /*!< LVD through EXTI line detect interrupt */ + TAMPER_IRQn = 21, /*!< tamper through EXTI line detect */ + RTC_IRQn = 22, /*!< RTC alarm interrupt */ + FMC_IRQn = 23, /*!< FMC interrupt */ + RCU_CTC_IRQn = 24, /*!< RCU and CTC interrupt */ + EXTI0_IRQn = 25, /*!< EXTI line 0 interrupts */ + EXTI1_IRQn = 26, /*!< EXTI line 1 interrupts */ + EXTI2_IRQn = 27, /*!< EXTI line 2 interrupts */ + EXTI3_IRQn = 28, /*!< EXTI line 3 interrupts */ + EXTI4_IRQn = 29, /*!< EXTI line 4 interrupts */ + DMA0_Channel0_IRQn = 30, /*!< DMA0 channel0 interrupt */ + DMA0_Channel1_IRQn = 31, /*!< DMA0 channel1 interrupt */ + DMA0_Channel2_IRQn = 32, /*!< DMA0 channel2 interrupt */ + DMA0_Channel3_IRQn = 33, /*!< DMA0 channel3 interrupt */ + DMA0_Channel4_IRQn = 34, /*!< DMA0 channel4 interrupt */ + DMA0_Channel5_IRQn = 35, /*!< DMA0 channel5 interrupt */ + DMA0_Channel6_IRQn = 36, /*!< DMA0 channel6 interrupt */ + ADC0_1_IRQn = 37, /*!< ADC0 and ADC1 interrupt */ + CAN0_TX_IRQn = 38, /*!< CAN0 TX interrupts */ + CAN0_RX0_IRQn = 39, /*!< CAN0 RX0 interrupts */ + CAN0_RX1_IRQn = 40, /*!< CAN0 RX1 interrupts */ + CAN0_EWMC_IRQn = 41, /*!< CAN0 EWMC interrupts */ + EXTI5_9_IRQn = 42, /*!< EXTI[9:5] interrupts */ + TIMER0_BRK_IRQn = 43, /*!< TIMER0 break interrupts */ + TIMER0_UP_IRQn = 44, /*!< TIMER0 update interrupts */ + TIMER0_TRG_CMT_IRQn = 45, /*!< TIMER0 trigger and commutation interrupts */ + TIMER0_Channel_IRQn = 46, /*!< TIMER0 channel capture compare interrupts */ + TIMER1_IRQn = 47, /*!< TIMER1 interrupt */ + TIMER2_IRQn = 48, /*!< TIMER2 interrupt */ + TIMER3_IRQn = 49, /*!< TIMER3 interrupts */ + I2C0_EV_IRQn = 50, /*!< I2C0 event interrupt */ + I2C0_ER_IRQn = 51, /*!< I2C0 error interrupt */ + I2C1_EV_IRQn = 52, /*!< I2C1 event interrupt */ + I2C1_ER_IRQn = 53, /*!< I2C1 error interrupt */ + SPI0_IRQn = 54, /*!< SPI0 interrupt */ + SPI1_IRQn = 55, /*!< SPI1 interrupt */ + USART0_IRQn = 56, /*!< USART0 interrupt */ + USART1_IRQn = 57, /*!< USART1 interrupt */ + USART2_IRQn = 58, /*!< USART2 interrupt */ + EXTI10_15_IRQn = 59, /*!< EXTI[15:10] interrupts */ + RTC_ALARM_IRQn = 60, /*!< RTC alarm interrupt EXTI */ + USBFS_WKUP_IRQn = 61, /*!< USBFS wakeup interrupt */ + + EXMC_IRQn = 67, /*!< EXMC global interrupt */ + + TIMER4_IRQn = 69, /*!< TIMER4 global interrupt */ + SPI2_IRQn = 70, /*!< SPI2 global interrupt */ + UART3_IRQn = 71, /*!< UART3 global interrupt */ + UART4_IRQn = 72, /*!< UART4 global interrupt */ + TIMER5_IRQn = 73, /*!< TIMER5 global interrupt */ + TIMER6_IRQn = 74, /*!< TIMER6 global interrupt */ + DMA1_Channel0_IRQn = 75, /*!< DMA1 channel0 global interrupt */ + DMA1_Channel1_IRQn = 76, /*!< DMA1 channel1 global interrupt */ + DMA1_Channel2_IRQn = 77, /*!< DMA1 channel2 global interrupt */ + DMA1_Channel3_IRQn = 78, /*!< DMA1 channel3 global interrupt */ + DMA1_Channel4_IRQn = 79, /*!< DMA1 channel3 global interrupt */ + + CAN1_TX_IRQn = 82, /*!< CAN1 TX interrupt */ + CAN1_RX0_IRQn = 83, /*!< CAN1 RX0 interrupt */ + CAN1_RX1_IRQn = 84, /*!< CAN1 RX1 interrupt */ + CAN1_EWMC_IRQn = 85, /*!< CAN1 EWMC interrupt */ + USBFS_IRQn = 86, /*!< USBFS global interrupt */ + + ECLIC_NUM_INTERRUPTS +} IRQn_Type; + +/* includes */ +#include "system_gd32vf103.h" +#include + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {FALSE = 0, TRUE = !FALSE} bool; +typedef enum {RESET = 0, SET = 1,MAX = 0X7FFFFFFF} 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) /*!< SRAM0 base address */ +#define OB_BASE ((uint32_t)0x1FFFF800U) /*!< OB base address */ +#define DBG_BASE ((uint32_t)0xE0042000U) /*!< DBG base address */ +#define EXMC_BASE ((uint32_t)0xA0000000U) /*!< EXMC register 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)0x40018000U) /*!< ahb1 base address */ +#define AHB3_BUS_BASE ((uint32_t)0x60000000U) /*!< ahb3 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 CAN_BASE (APB1_BUS_BASE + 0x00006400U) /*!< CAN base address */ +#define BKP_BASE (APB1_BUS_BASE + 0x00006C00U) /*!< BKP base address */ +#define PMU_BASE (APB1_BUS_BASE + 0x00007000U) /*!< PMU base address */ +#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */ + +/* advanced peripheral bus 2 memory map */ +#define AFIO_BASE (APB2_BUS_BASE + 0x00000000U) /*!< AFIO base address */ +#define EXTI_BASE (APB2_BUS_BASE + 0x00000400U) /*!< EXTI base address */ +#define GPIO_BASE (APB2_BUS_BASE + 0x00000800U) /*!< GPIO 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 + 0x00008000U) /*!< DMA base address */ +#define RCU_BASE (AHB1_BUS_BASE + 0x00009000U) /*!< RCU base address */ +#define FMC_BASE (AHB1_BUS_BASE + 0x0000A000U) /*!< FMC base address */ +#define CRC_BASE (AHB1_BUS_BASE + 0x0000B000U) /*!< CRC base address */ +#define USBFS_BASE (AHB1_BUS_BASE + 0x0FFE8000U) /*!< USBFS base address */ + +/* define marco USE_STDPERIPH_DRIVER */ +#if !defined USE_STDPERIPH_DRIVER +#define USE_STDPERIPH_DRIVER +#endif +#ifdef USE_STDPERIPH_DRIVER +#include "gd32vf103_libopt.h" +#endif /* USE_STDPERIPH_DRIVER */ + +#ifdef cplusplus +} +#endif +#endif diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/system_gd32vf103.c b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/system_gd32vf103.c new file mode 100644 index 0000000000000000000000000000000000000000..613ef2fa7545ec7e798ef2c6510414594936763a --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/system_gd32vf103.c @@ -0,0 +1,998 @@ +/*! + \file system_gd32vf103.c + \brief RISC-V Device Peripheral Access Layer Source File for + GD32VF103 Device Series + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 + */ + +/* + 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. + */ + +/* This file refers the RISC-V standard, some adjustments are made according to GigaDevice chips */ + +#include "gd32vf103.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 */ +/* use IRC8M */ +//#define __SYSTEM_CLOCK_48M_PLL_IRC8M (uint32_t)(48000000) +//#define __SYSTEM_CLOCK_72M_PLL_IRC8M (uint32_t)(72000000) +//#define __SYSTEM_CLOCK_108M_PLL_IRC8M (uint32_t)(108000000) +/********************************************************************/ +//#define __SYSTEM_CLOCK_HXTAL (HXTAL_VALUE) +//#define __SYSTEM_CLOCK_24M_PLL_HXTAL (uint32_t)(24000000) +/********************************************************************/ + +//#define __SYSTEM_CLOCK_36M_PLL_HXTAL (uint32_t)(36000000) +//#define __SYSTEM_CLOCK_48M_PLL_HXTAL (uint32_t)(48000000) +//#define __SYSTEM_CLOCK_56M_PLL_HXTAL (uint32_t)(56000000) +//#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) +//#define __SYSTEM_CLOCK_96M_PLL_HXTAL (uint32_t)(96000000) +#define __SYSTEM_CLOCK_108M_PLL_HXTAL (uint32_t)(108000000) + +#define SEL_IRC8M 0x00U +#define SEL_HXTAL 0x01U +#define SEL_PLL 0x02U + +/* set the system clock frequency and declare the system clock configuration function */ +#ifdef __SYSTEM_CLOCK_48M_PLL_IRC8M +uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_IRC8M; +static void system_clock_48m_irc8m(void); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M; +static void system_clock_72m_irc8m(void); +#elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_IRC8M; +static void system_clock_108m_irc8m(void); + +#elif defined (__SYSTEM_CLOCK_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL; +static void system_clock_hxtal(void); +#elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_24M_PLL_HXTAL; +static void system_clock_24m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_36M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_36M_PLL_HXTAL; +static void system_clock_36m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_HXTAL; +static void system_clock_48m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_56M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_56M_PLL_HXTAL; +static void system_clock_56m_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_96M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_96M_PLL_HXTAL; +static void system_clock_96m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_HXTAL; +static void system_clock_108m_hxtal(void); +#else +uint32_t SystemCoreClock = IRC8M_VALUE; +#endif /* __SYSTEM_CLOCK_48M_PLL_IRC8M */ + +/* configure the system clock */ +static void system_clock_config(void); + +/*! + \brief configure the system clock + \param[in] none + \param[out] none + \retval none + */ +static void system_clock_config(void) { +#ifdef __SYSTEM_CLOCK_HXTAL + system_clock_hxtal(); +#elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL) + system_clock_24m_hxtal(); +#elif defined (__SYSTEM_CLOCK_36M_PLL_HXTAL) + system_clock_36m_hxtal(); +#elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL) + system_clock_48m_hxtal(); +#elif defined (__SYSTEM_CLOCK_56M_PLL_HXTAL) + system_clock_56m_hxtal(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) + system_clock_72m_hxtal(); +#elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL) + system_clock_96m_hxtal(); +#elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL) + system_clock_108m_hxtal(); + +#elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M) + system_clock_48m_irc8m(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M) + system_clock_72m_irc8m(); +#elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M) + system_clock_108m_irc8m(); +#endif /* __SYSTEM_CLOCK_HXTAL */ +} + +/*! + \brief setup the microcontroller system, initialize the system + \param[in] none + \param[out] none + \retval none + */ +void SystemInit(void) { + /* reset the RCC clock configuration to the default reset state */ + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + + /* reset SCS, AHBPSC, APB1PSC, APB2PSC, ADCPSC, CKOUT0SEL bits */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC + | RCU_CFG0_APB2PSC | + RCU_CFG0_ADCPSC | RCU_CFG0_ADCPSC_2 | RCU_CFG0_CKOUT0SEL); + + /* reset HXTALEN, CKMEN, PLLEN bits */ + RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN); + + /* Reset HXTALBPS bit */ + RCU_CTL &= ~(RCU_CTL_HXTALBPS); + + /* reset PLLSEL, PREDV0_LSB, PLLMF, USBFSPSC bits */ + + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF | + RCU_CFG0_USBFSPSC | RCU_CFG0_PLLMF_4); + RCU_CFG1 = 0x00000000U; + + /* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */ + RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN + | RCU_CTL_HXTALEN); + /* disable all interrupts */ + RCU_INT = 0x00FF0000U; + + /* Configure the System clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */ + system_clock_config(); +} + +/*! + \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 scss; + uint32_t pllsel, predv0sel, pllmf, ck_src; + uint32_t predv0, predv1, pll1mf; + + scss = GET_BITS(RCU_CFG0, 2, 3); + + switch (scss) { + /* 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: + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = (RCU_CFG0 & RCU_CFG0_PLLSEL); + + if (RCU_PLLSRC_IRC8M_DIV2 == pllsel) { + /* PLL clock source is IRC8M/2 */ + ck_src = IRC8M_VALUE / 2U; + } else { + /* PLL clock source is HXTAL */ + ck_src = HXTAL_VALUE; + + predv0sel = (RCU_CFG1 & RCU_CFG1_PREDV0SEL); + + /* source clock use PLL1 */ + if (RCU_PREDV0SRC_CKPLL1 == predv0sel) { + predv1 = ((RCU_CFG1 & RCU_CFG1_PREDV1) >> 4) + 1U; + pll1mf = ((RCU_CFG1 & RCU_CFG1_PLL1MF) >> 8) + 2U; + if (17U == pll1mf) { + pll1mf = 20U; + } + ck_src = (ck_src / predv1) * pll1mf; + } + predv0 = (RCU_CFG1 & RCU_CFG1_PREDV0) + 1U; + ck_src /= predv0; + } + + /* PLL multiplication factor */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + + if ((RCU_CFG0 & RCU_CFG0_PLLMF_4)) { + pllmf |= 0x10U; + } + + if (pllmf >= 15U) { + pllmf += 1U; + } else { + pllmf += 2U; + } + + SystemCoreClock = ck_src * pllmf; + + if (15U == pllmf) { + /* PLL source clock multiply by 6.5 */ + SystemCoreClock = ck_src * 6U + ck_src / 2U; + } + + break; + + /* IRC8M is selected as CK_SYS */ + default: + SystemCoreClock = IRC8M_VALUE; + break; + } +} + +#ifdef __SYSTEM_CLOCK_HXTAL +/*! + \brief configure the system clock to HXTAL + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* select HXTAL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_HXTAL; + + /* wait until HXTAL is selected as system clock */ + while(0 == (RCU_CFG0 & RCU_SCSS_HXTAL)){ + } +} + +#elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL) +/*! + \brief configure the system clock to 24M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_24m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_PREDIV0) * 6 = 24 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL6); + + if(HXTAL_VALUE==25000000){ + /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10); + + /* enable PLL1 */ + RCU_CTL |= RCU_CTL_PLL1EN; + /* wait till PLL1 is ready */ + while((RCU_CTL & RCU_CTL_PLL1STB) == 0){ + } + + }else if(HXTAL_VALUE==8000000){ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 ); + } + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_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_36M_PLL_HXTAL) +/*! + \brief configure the system clock to 36M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_36m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_PREDIV0) * 9 = 36 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL9); + + if(HXTAL_VALUE==25000000){ + /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10); + + /* enable PLL1 */ + RCU_CTL |= RCU_CTL_PLL1EN; + /* wait till PLL1 is ready */ + while((RCU_CTL & RCU_CTL_PLL1STB) == 0){ + } + + }else if(HXTAL_VALUE==8000000){ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 ); + } + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_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_48M_PLL_HXTAL) +/*! + \brief configure the system clock to 48M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_48m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_PREDIV0) * 12 = 48 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL12); + + if(HXTAL_VALUE==25000000){ + + /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10); + + /* enable PLL1 */ + RCU_CTL |= RCU_CTL_PLL1EN; + /* wait till PLL1 is ready */ + while((RCU_CTL & RCU_CTL_PLL1STB) == 0){ + } + + }else if(HXTAL_VALUE==8000000){ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 ); + } + + + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_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_56M_PLL_HXTAL) +/*! + \brief configure the system clock to 56M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_56m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_PREDIV0) * 14 = 56 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL14); + + if(HXTAL_VALUE==25000000){ + + /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10); + + /* enable PLL1 */ + RCU_CTL |= RCU_CTL_PLL1EN; + /* wait till PLL1 is ready */ + while((RCU_CTL & RCU_CTL_PLL1STB) == 0){ + } + + }else if(HXTAL_VALUE==8000000){ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 ); + } + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_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_HXTAL) +/*! + \brief configure the system clock to 72M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) 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_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_PREDIV0) * 18 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL18); + + + if(HXTAL_VALUE==25000000){ + + /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10); + + /* enable PLL1 */ + RCU_CTL |= RCU_CTL_PLL1EN; + /* wait till PLL1 is ready */ + while((RCU_CTL & RCU_CTL_PLL1STB) == 0){ + } + + }else if(HXTAL_VALUE==8000000){ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 ); + } + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_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(MD/HD/XD:8M; CL:25M) 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_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + if(HXTAL_VALUE==25000000){ + + /* CK_PLL = (CK_PREDIV0) * 24 = 96 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL24); + + /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10); + /* enable PLL1 */ + RCU_CTL |= RCU_CTL_PLL1EN; + /* wait till PLL1 is ready */ + while((RCU_CTL & RCU_CTL_PLL1STB) == 0){ + } + + }else if(HXTAL_VALUE==8000000){ + /* CK_PLL = (CK_PREDIV0) * 24 = 96 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL24); + + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 ); + } + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_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 108M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) 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_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } while ((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if (0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { + while (1) { + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_PREDIV0) * 27 = 108 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL27); + + if (HXTAL_VALUE == 25000000) { + /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */ + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF + | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PREDV1_DIV5 | RCU_PLL1_MUL8 + | RCU_PREDV0_DIV10); + + /* enable PLL1 */ + RCU_CTL |= RCU_CTL_PLL1EN; + /* wait till PLL1 is ready */ + while (0U == (RCU_CTL & RCU_CTL_PLL1STB)) { + } + + /* enable PLL1 */ + RCU_CTL |= RCU_CTL_PLL2EN; + /* wait till PLL1 is ready */ + while (0U == (RCU_CTL & RCU_CTL_PLL2STB)) { + } + } else if (HXTAL_VALUE == 8000000) { + RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF + | RCU_CFG1_PREDV0); + RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 | RCU_PREDV1_DIV2 + | RCU_PLL1_MUL20 | RCU_PLL2_MUL20); + + /* enable PLL1 */ + RCU_CTL |= RCU_CTL_PLL1EN; + /* wait till PLL1 is ready */ + while (0U == (RCU_CTL & RCU_CTL_PLL1STB)) { + } + + /* enable PLL2 */ + RCU_CTL |= RCU_CTL_PLL2EN; + /* wait till PLL1 is ready */ + while (0U == (RCU_CTL & RCU_CTL_PLL2STB)) { + } + + } + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while (0U == (RCU_CTL & RCU_CTL_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_48M_PLL_IRC8M) +/*! + \brief configure the system clock to 48M by PLL which selects IRC8M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_48m_irc8m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + + /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB); + } + while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){ + while(1){ + } + } + + /* IRC8M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_IRC8M/2) * 12 = 48 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= RCU_PLL_MUL12; + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_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) +/*! + \brief configure the system clock to 72M by PLL which selects IRC8M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_72m_irc8m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + + /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB); + } + while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){ + while(1){ + } + } + + /* IRC8M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_IRC8M/2) * 18 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= RCU_PLL_MUL18; + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_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) +/*! + \brief configure the system clock to 108M by PLL which selects IRC8M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_108m_irc8m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + + /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB); + } + while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){ + while(1){ + } + } + + /* IRC8M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_IRC8M/2) * 27 = 108 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= RCU_PLL_MUL27; + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_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)){ + } +} + +#endif diff --git a/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/system_gd32vf103.h b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/system_gd32vf103.h new file mode 100644 index 0000000000000000000000000000000000000000..a31319bd752724faf70af00494998eb0c507624b --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/GD32VF103_standard_peripheral/system_gd32vf103.h @@ -0,0 +1,60 @@ +/*! + \file system_gd32vf103.h + \brief RISC-V Device Peripheral Access Layer Header File for + GD32VF103 Device Series + + \version 2019-6-5, V1.0.0, firmware for GD32VF103 + */ + +/* + 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. + */ + +/* This file refers the RISC-V standard, some adjustments are made according to GigaDevice chips */ + +#ifndef SYSTEM_GD32VF103_H +#define SYSTEM_GD32VF103_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* system clock frequency (core clock) */ +extern uint32_t SystemCoreClock; + +/* function declarations */ +/* initialize the system and update the SystemCoreClock variable */ +extern void SystemInit(void); +/* update the SystemCoreClock with current core clock retrieved from cpu registers */ +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_GD32VF103_H */ diff --git a/bsp/gd32vf103v-eval/libraries/n22/drivers/core_v5.h b/bsp/gd32vf103v-eval/libraries/n22/drivers/core_v5.h new file mode 100644 index 0000000000000000000000000000000000000000..3ce586e90e06f519a7f4a610588f1887ae4f6673 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/drivers/core_v5.h @@ -0,0 +1,127 @@ +#ifndef __CORE_V5_H__ +#define __CORE_V5_H__ + +#define MSTATUS_UIE 0x00000001 +#define MSTATUS_SIE 0x00000002 +#define MSTATUS_HIE 0x00000004 +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_UPIE 0x00000010 +#define MSTATUS_SPIE 0x00000020 +#define MSTATUS_HPIE 0x00000040 +#define MSTATUS_MPIE 0x00000080 +#define MSTATUS_SPP 0x00000100 +#define MSTATUS_HPP 0x00000600 +#define MSTATUS_MPP 0x00001800 +#define MSTATUS_FS 0x00006000 +#define MSTATUS_XS 0x00018000 +#define MSTATUS_MPRV 0x00020000 +#define MSTATUS_PUM 0x00040000 +#define MSTATUS_MXR 0x00080000 +#define MSTATUS_VM 0x1F000000 +#define MSTATUS32_SD 0x80000000 +#define MSTATUS64_SD 0x8000000000000000 + +#if __riscv_xlen == 64 +#define MCAUSE_INT 0x8000000000000000UL +#define MCAUSE_CAUSE 0x7FFFFFFFFFFFFFFFUL +#else +#define MCAUSE_INT 0x80000000UL +#define MCAUSE_CAUSE 0x7FFFFFFFUL +#endif + +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_S_EXT 9 +#define IRQ_H_EXT 10 +#define IRQ_M_EXT 11 +#define IRQ_COP 12 +#define IRQ_HOST 13 + +/* Machine mode MCAUSE */ +#define TRAP_M_I_ACC_FAULT 1 /* Instruction access fault */ +#define TRAP_M_L_ACC_FAULT 5 /* Data load access fault */ +#define TRAP_M_S_ACC_FAULT 7 /* Data store access fault */ +#define TRAP_U_ECALL 8 +#define TRAP_S_ECALL 9 +#define TRAP_H_ECALL 10 +#define TRAP_M_ECALL 11 +#define TRAP_M_I_PAGE_FAULT 12 /* Instruction page fault */ +#define TRAP_M_L_PAGE_FAULT 13 /* Data load page fault */ +#define TRAP_M_S_PAGE_FAULT 15 /* Data store page fault */ +#define TRAP_M_STACKOVF 32 +#define TRAP_M_STACKUDF 33 + +/* Supervisor mode SCAUSE */ +#define TRAP_S_I_ACC_FAULT 1 /* Instruction access fault */ +#define TRAP_S_L_ACC_FAULT 5 /* Data load access fault */ +#define TRAP_S_S_ACC_FAULT 7 /* Data store access fault */ +#define TRAP_S_I_PAGE_FAULT 12 /* Instruction page fault */ +#define TRAP_S_L_PAGE_FAULT 13 /* Data load page fault */ +#define TRAP_S_S_PAGE_FAULT 15 /* Data store page fault */ + +#define MIP_SSIP (1 << IRQ_S_SOFT) +#define MIP_HSIP (1 << IRQ_H_SOFT) +#define MIP_MSIP (1 << IRQ_M_SOFT) +#define MIP_STIP (1 << IRQ_S_TIMER) +#define MIP_HTIP (1 << IRQ_H_TIMER) +#define MIP_MTIP (1 << IRQ_M_TIMER) +#define MIP_SEIP (1 << IRQ_S_EXT) +#define MIP_HEIP (1 << IRQ_H_EXT) +#define MIP_MEIP (1 << IRQ_M_EXT) + +/* MILMB and MDLMB */ +#define MILMB_IEN (0x1UL) +#define MDLMB_DEN (0x1UL) + +#if __riscv_xlen == 64 +# define SLL32 sllw +# define STORE sd +# define LOAD ld +# define LWU lwu +# define LOG_REGBYTES 3 +#else +# define SLL32 sll +# define STORE sw +# define LOAD lw +# define LWU lw +# define LOG_REGBYTES 2 +#endif +#define REGBYTES (1 << LOG_REGBYTES) + +#if __riscv_flen == 64 +# define FPSTORE fsd +# define FPLOAD fld +# define LOG_FPREGBYTES 3 +#else +# define FPSTORE fsw +# define FPLOAD flw +# define LOG_FPREGBYTES 2 +#endif +#define FPREGBYTES (1 << LOG_FPREGBYTES) + +#define STR(S) #S +#define XSTR(S) STR(S) + +#define PUSH XSTR(STORE) +#define POP XSTR(LOAD) +#define REGSIZE XSTR(REGBYTES) +#define FPPUSH XSTR(FPSTORE) +#define FPPOP XSTR(FPLOAD) +#define FPREGSIZE XSTR(FPREGBYTES) + +#ifndef __ASSEMBLER__ + + +#define read_csr(reg) __nds__csrr(reg) +#define write_csr(reg, val) __nds__csrw(val, reg) +#define swap_csr(reg, val) __nds__csrrw(val, reg) +#define set_csr(reg, bit) __nds__csrrs(bit, reg) +#define clear_csr(reg, bit) __nds__csrrc(bit, reg) + +#endif + +#endif // __CORE_V5_H__ diff --git a/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_eclic.h b/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_eclic.h new file mode 100644 index 0000000000000000000000000000000000000000..a91c3aafc45447208b6f6f518f1e3bc1e88abfef --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_eclic.h @@ -0,0 +1,47 @@ +// See LICENSE file for licence details + +#ifndef N22_ECLIC_H +#define N22_ECLIC_H +#include + +#define ECLICINTCTLBITS 4 + +//ECLIC memory map +// Offset +// 0x0000 1B RW ecliccfg +#define ECLIC_CFG_OFFSET 0x0 +// 0x0004 4B R eclicinfo +#define ECLIC_INFO_OFFSET 0x4 +// 0x000B 1B RW mintthresh +#define ECLIC_MTH_OFFSET 0xB +// +// 0x1000+4*i 1B/input RW eclicintip[i] +#define ECLIC_INT_IP_OFFSET _AC(0x1000,UL) +// 0x1001+4*i 1B/input RW eclicintie[i] +#define ECLIC_INT_IE_OFFSET _AC(0x1001,UL) +// 0x1002+4*i 1B/input RW eclicintattr[i] +#define ECLIC_INT_ATTR_OFFSET _AC(0x1002,UL) + +#define ECLIC_INT_ATTR_SHV 0x01 +#define ECLIC_INT_ATTR_TRIG_LEVEL 0x00 +#define ECLIC_INT_ATTR_TRIG_EDGE 0x02 +#define ECLIC_INT_ATTR_TRIG_POS 0x00 +#define ECLIC_INT_ATTR_TRIG_NEG 0x04 + +// 0x1003+4*i 1B/input RW eclicintctl[i] +#define ECLIC_INT_CTRL_OFFSET _AC(0x1003,UL) +// +// ... +// +#define ECLIC_ADDR_BASE 0xd2000000 + + +#define ECLIC_CFG_NLBITS_MASK _AC(0x1E,UL) +#define ECLIC_CFG_NLBITS_LSB (1u) + +#define MSIP_HANDLER eclic_msip_handler +#define MTIME_HANDLER eclic_mtip_handler +#define BWEI_HANDLER eclic_bwei_handler +#define PMOVI_HANDLER eclic_pmovi_handler + +#endif diff --git a/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_func.c b/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_func.c new file mode 100644 index 0000000000000000000000000000000000000000..1f89ffd8da5dd978e068cc1eba6c40b6683ae0e0 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_func.c @@ -0,0 +1,279 @@ +// See LICENSE for license details. +#include +#include +#include +#include +#include + +#include "riscv_encoding.h" +#include "n22_func.h" + +void switch_m2u_mode() { + clear_csr(mstatus, MSTATUS_MPP); + //printf("\nIn the m2u function, the mstatus is 0x%x\n", read_csr(mstatus)); + //printf("\nIn the m2u function, the mepc is 0x%x\n", read_csr(mepc)); + asm volatile ("la x6, 1f ":::"x6"); + asm volatile ("csrw mepc, x6":::); + asm volatile ("mret":::); + asm volatile ("1:":::); +} + +uint32_t mtime_lo(void) { + return *(volatile uint32_t *) (TMR_CTRL_ADDR + TMR_MTIME); +} + +uint32_t mtime_hi(void) { + return *(volatile uint32_t *) (TMR_CTRL_ADDR + TMR_MTIME + 4); +} + +void enable_timer_interrupt(void) { + *(volatile uint32_t *) (TMR_CTRL_ADDR + TMR_MTIME + 0xffc) = 1; +} + +void clear_timer_interrupt(void) { + *(volatile uint32_t *) (TMR_CTRL_ADDR + TMR_MTIME + 0xffc) = 0; +} + +void close_timer(void) { + *(volatile uint32_t *) (TMR_CTRL_ADDR + TMR_MTIME + 0xff8) = 1; +} + +void open_timer(void) { + *(volatile uint32_t *) (TMR_CTRL_ADDR + TMR_MTIME + 0xff8) = 0; +} + +uint64_t get_timer_value() { + while (1) { + uint32_t hi = mtime_hi(); + uint32_t lo = mtime_lo(); + + if (hi == mtime_hi()) + return ((uint64_t) hi << 32) | lo; + } +} + +uint32_t get_timer_freq() { + return TMR_FREQ; +} + +uint64_t get_instret_value() { + while (1) { + uint32_t hi = read_csr(minstreth); + uint32_t lo = read_csr(minstret); + if (hi == read_csr(minstreth)) + return ((uint64_t) hi << 32) | lo; + } +} + +uint64_t get_cycle_value() { + while (1) { + uint32_t hi = read_csr(mcycleh); + uint32_t lo = read_csr(mcycle); + if (hi == read_csr(mcycleh)) + return ((uint64_t) hi << 32) | lo; + } +} +// Note that there are no assertions or bounds checking on these +// parameter values. + +void eclic_init(uint32_t num_irq) { + typedef volatile uint32_t vuint32_t; + + //clear cfg register + *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET) = 0; + + //clear minthresh register + *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET) = 0; + + //clear all IP/IE/ATTR/CTRL bits for all interrupt sources + vuint32_t * ptr; + + vuint32_t * base = (vuint32_t*) (ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET); + vuint32_t * upper = (vuint32_t*) (base + num_irq * 4); + + for (ptr = base; ptr < upper; ptr = ptr + 4) { + *ptr = 0; + } + eclic_set_nlbits(ECLIC_GROUP_LEVEL2_PRIO2); +} + +void eclic_enable_interrupt(uint32_t source) { + *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_INT_IE_OFFSET + source * 4) = + 1; +} + +void eclic_disable_interrupt(uint32_t source) { + *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_INT_IE_OFFSET + source * 4) = + 0; +} + +void eclic_set_pending(uint32_t source) { + *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET + source * 4) = + 1; +} + +void eclic_clear_pending(uint32_t source) { + *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET + source * 4) = + 0; +} + +void eclic_set_intctrl(uint32_t source, uint8_t intctrl) { + *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_INT_CTRL_OFFSET + source * 4) = + intctrl; +} + +uint8_t eclic_get_intctrl(uint32_t source) { + return *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_INT_CTRL_OFFSET + + source * 4); +} + +void eclic_set_intattr(uint32_t source, uint8_t intattr) { + *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_INT_ATTR_OFFSET + source * 4) = + intattr; +} + +uint8_t eclic_get_intattr(uint32_t source) { + return *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_INT_ATTR_OFFSET + + source * 4); +} + +void eclic_set_ecliccfg(uint8_t ecliccfg) { + *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET) = ecliccfg; +} + +uint8_t eclic_get_ecliccfg() { + return *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET); +} + +void eclic_set_mth(uint8_t mth) { + *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET) = mth; +} + +uint8_t eclic_get_mth() { + return *(volatile uint8_t*) (ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET); +} + +void eclic_set_nlbits(uint8_t nlbits) { + //shift nlbits to correct position + uint8_t nlbits_shifted = nlbits << ECLIC_CFG_NLBITS_LSB; + + //read the current ecliccfg + uint8_t old_ecliccfg = eclic_get_ecliccfg(); + uint8_t new_ecliccfg = (old_ecliccfg & (~ECLIC_CFG_NLBITS_MASK)) + | (ECLIC_CFG_NLBITS_MASK & nlbits_shifted); + + eclic_set_ecliccfg(new_ecliccfg); +} + +uint8_t eclic_get_nlbits(void) { + //extract nlbits + uint8_t nlbits = eclic_get_ecliccfg(); + nlbits = (nlbits & ECLIC_CFG_NLBITS_MASK) >> ECLIC_CFG_NLBITS_LSB; + return nlbits; +} + +//sets an interrupt level based encoding of nlbits and ECLICINTCTLBITS +uint8_t eclic_set_int_level(uint32_t source, uint8_t level) { + //extract nlbits + uint8_t nlbits = eclic_get_nlbits(); + if (nlbits > ECLICINTCTLBITS) { + nlbits = ECLICINTCTLBITS; + } + + //shift level into correct bit position + level = level << (8 - nlbits); + + //write to eclicintctrl + uint8_t current_intctrl = eclic_get_intctrl(source); + //shift intctrl left to mask off unused bits + current_intctrl = current_intctrl << nlbits; + //shift intctrl into correct bit position + current_intctrl = current_intctrl >> nlbits; + + eclic_set_intctrl(source, (current_intctrl | level)); + + return level; +} + +//gets an interrupt level based encoding of nlbits +uint8_t eclic_get_int_level(uint32_t source) { + //extract nlbits + uint8_t nlbits = eclic_get_nlbits(); + if (nlbits > ECLICINTCTLBITS) { + nlbits = ECLICINTCTLBITS; + } + + uint8_t intctrl = eclic_get_intctrl(source); + + //shift intctrl + intctrl = intctrl >> (8 - nlbits); + //shift intctrl + uint8_t level = intctrl << (8 - nlbits); + + return level; +} + +//sets an interrupt priority based encoding of nlbits and ECLICINTCTLBITS +uint8_t eclic_set_int_priority(uint32_t source, uint8_t priority) { + //extract nlbits + uint8_t nlbits = eclic_get_nlbits(); + if (nlbits >= ECLICINTCTLBITS) { + nlbits = ECLICINTCTLBITS; + return 0; + } + + //shift priority into correct bit position + priority = priority << (8 - ECLICINTCTLBITS); + + //write to eclicintctrl + uint8_t current_intctrl = eclic_get_intctrl(source); + //shift intctrl right to mask off unused bits + current_intctrl = current_intctrl >> (8 - nlbits); + //shift intctrl into correct bit position + current_intctrl = current_intctrl << (8 - nlbits); + + eclic_set_intctrl(source, (current_intctrl | priority)); + + return priority; +} + +//gets an interrupt priority based encoding of nlbits +uint8_t eclic_get_int_priority(uint32_t source) { + //extract nlbits + uint8_t nlbits = eclic_get_nlbits(); + if (nlbits > ECLICINTCTLBITS) { + nlbits = ECLICINTCTLBITS; + } + + uint8_t intctrl = eclic_get_intctrl(source); + + //shift intctrl + intctrl = intctrl << nlbits; + //shift intctrl + uint8_t priority = intctrl >> (nlbits + (8 - ECLICINTCTLBITS)); + + return priority; +} + +void eclic_mode_enable() { + uint32_t mtvec_value = read_csr(mtvec); + mtvec_value = mtvec_value & 0xFFFFFFC0; + mtvec_value = mtvec_value | 0x00000003; + write_csr(mtvec, mtvec_value); +} + +void eclic_set_shv(uint32_t source, uint8_t shv) { + uint8_t attr = eclic_get_intattr(source); + if (shv) { + attr |= 0x01; + eclic_set_intattr(source, attr); + } +} + +void eclic_set_trig(uint32_t source, uint8_t trig) { + uint8_t attr = eclic_get_intattr(source); + if ((trig & 0x1)) { + attr |= (trig << 1); + eclic_set_intattr(source, attr); + } +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_func.h b/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_func.h new file mode 100644 index 0000000000000000000000000000000000000000..614efebec0cae29a919e3f28ca09be3ab8182ab8 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_func.h @@ -0,0 +1,82 @@ +// See LICENSE file for licence details + +#ifndef N22_FUNC_H +#define N22_FUNC_H + + +#include "n22_tmr.h" +#include "n22_eclic.h" + +#define ECLIC_GROUP_LEVEL0_PRIO4 0 +#define ECLIC_GROUP_LEVEL1_PRIO3 1 +#define ECLIC_GROUP_LEVEL2_PRIO2 2 +#define ECLIC_GROUP_LEVEL3_PRIO1 3 +#define ECLIC_GROUP_LEVEL4_PRIO0 4 + +void switch_m2u_mode(); +uint32_t get_tmr_freq(); +uint32_t mtime_lo(void); +uint32_t mtime_hi(void); +uint64_t get_timer_value(); +uint64_t get_instret_value(); +uint64_t get_cycle_value(); + +void eclic_init(uint32_t num_irq); + +void eclic_enable_interrupt(uint32_t source); +void eclic_disable_interrupt(uint32_t source); + +void eclic_set_pending(uint32_t source); +void eclic_clear_pending(uint32_t source); + +void eclic_set_intctrl(uint32_t source, uint8_t intctrl); +uint8_t eclic_get_intctrl(uint32_t source); + +void eclic_set_intattr(uint32_t source, uint8_t intattr); +uint8_t eclic_get_intattr(uint32_t source); + +void eclic_set_ecliccfg(uint8_t ecliccfg); +uint8_t eclic_get_ecliccfg(); + +void eclic_set_mth(uint8_t mth); +uint8_t eclic_get_mth(); + +void eclic_set_nlbits(uint8_t nlbits); +uint8_t eclic_get_nlbits(); + +uint8_t eclic_set_int_level(uint32_t source, uint8_t level); +uint8_t eclic_get_int_level(uint32_t source); + +uint8_t eclic_set_int_priority(uint32_t source, uint8_t priority); +uint8_t eclic_get_int_priority(uint32_t source); + +void eclic_mode_enable(); +void eclic_set_shv(uint32_t source, uint8_t shv); +void eclic_set_trig(uint32_t source, uint8_t trig); + +///** \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 ("wfi"); +} + +void close_timer(void); +void open_timer(void); +void enable_timer_interrupt(void); +void clear_timer_interrupt(void); + +#endif diff --git a/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_tmr.h b/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_tmr.h new file mode 100644 index 0000000000000000000000000000000000000000..2645f73304177b4d5810752b3b6008e0e636f5b2 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/drivers/n22_tmr.h @@ -0,0 +1,17 @@ +// See LICENSE file for licence details + +#ifndef N22_TMR_H +#define N22_TMR_H + +#define TMR_MSIP 0xFFC +#define TMR_MSIP_size 0x4 +#define TMR_MTIMECMP 0x8 +#define TMR_MTIMECMP_size 0x8 +#define TMR_MTIME 0x0 +#define TMR_MTIME_size 0x8 + +#define TMR_CTRL_ADDR 0xd1000000 +#define TMR_REG(offset) _REG32(TMR_CTRL_ADDR, offset) +#define TMR_FREQ ((uint32_t)SystemCoreClock/4) //units HZ + +#endif diff --git a/bsp/gd32vf103v-eval/libraries/n22/drivers/riscv_bits.h b/bsp/gd32vf103v-eval/libraries/n22/drivers/riscv_bits.h new file mode 100644 index 0000000000000000000000000000000000000000..bfe656feb0768ef6ff437aa7669be155845602dd --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/drivers/riscv_bits.h @@ -0,0 +1,36 @@ +// See LICENSE for license details. +#ifndef _RISCV_BITS_H +#define _RISCV_BITS_H + +#define likely(x) __builtin_expect((x), 1) +#define unlikely(x) __builtin_expect((x), 0) + +#define ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b)) +#define ROUNDDOWN(a, b) ((a)/(b)*(b)) + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi) + +#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1))) +#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1)))) + +#define STR(x) XSTR(x) +#define XSTR(x) #x + +#if __riscv_xlen == 64 +# define SLL32 sllw +# define STORE sd +# define LOAD ld +# define LWU lwu +# define LOG_REGBYTES 3 +#else +# define SLL32 sll +# define STORE sw +# define LOAD lw +# define LWU lw +# define LOG_REGBYTES 2 +#endif +#define REGBYTES (1 << LOG_REGBYTES) + +#endif diff --git a/bsp/gd32vf103v-eval/libraries/n22/drivers/riscv_const.h b/bsp/gd32vf103v-eval/libraries/n22/drivers/riscv_const.h new file mode 100644 index 0000000000000000000000000000000000000000..d5dec8acaab5ee5d56537846428c27d23e735f9f --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/drivers/riscv_const.h @@ -0,0 +1,18 @@ +// See LICENSE for license details. +/* Derived from */ + +#ifndef _RISCV_CONST_H +#define _RISCV_CONST_H + +#ifdef __ASSEMBLER__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define _AC(X,Y) (X##Y) +#define _AT(T,X) ((T)(X)) +#endif /* !__ASSEMBLER__*/ + +#define _BITUL(x) (_AC(1,UL) << (x)) +#define _BITULL(x) (_AC(1,ULL) << (x)) + +#endif /* _NUCLEI_CONST_H */ diff --git a/bsp/gd32vf103v-eval/libraries/n22/drivers/riscv_encoding.h b/bsp/gd32vf103v-eval/libraries/n22/drivers/riscv_encoding.h new file mode 100644 index 0000000000000000000000000000000000000000..6f0ac416cacfb5960ca61bebae60e441eb028b39 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/drivers/riscv_encoding.h @@ -0,0 +1,1342 @@ +// See LICENSE for license details. + +#ifndef RISCV_CSR_ENCODING_H +#define RISCV_CSR_ENCODING_H + +#define MSTATUS_UIE 0x00000001 +#define MSTATUS_SIE 0x00000002 +#define MSTATUS_HIE 0x00000004 +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_UPIE 0x00000010 +#define MSTATUS_SPIE 0x00000020 +#define MSTATUS_HPIE 0x00000040 +#define MSTATUS_MPIE 0x00000080 +#define MSTATUS_SPP 0x00000100 +#define MSTATUS_MPP 0x00001800 +#define MSTATUS_FS 0x00006000 +#define MSTATUS_XS 0x00018000 +#define MSTATUS_MPRV 0x00020000 +#define MSTATUS_PUM 0x00040000 +#define MSTATUS_MXR 0x00080000 +#define MSTATUS_VM 0x1F000000 +#define MSTATUS32_SD 0x80000000 +#define MSTATUS64_SD 0x8000000000000000 + +#define SSTATUS_UIE 0x00000001 +#define SSTATUS_SIE 0x00000002 +#define SSTATUS_UPIE 0x00000010 +#define SSTATUS_SPIE 0x00000020 +#define SSTATUS_SPP 0x00000100 +#define SSTATUS_FS 0x00006000 +#define SSTATUS_XS 0x00018000 +#define SSTATUS_PUM 0x00040000 +#define SSTATUS32_SD 0x80000000 +#define SSTATUS64_SD 0x8000000000000000 + +#define DCSR_XDEBUGVER (3U<<30) +#define DCSR_NDRESET (1<<29) +#define DCSR_FULLRESET (1<<28) +#define DCSR_EBREAKM (1<<15) +#define DCSR_EBREAKH (1<<14) +#define DCSR_EBREAKS (1<<13) +#define DCSR_EBREAKU (1<<12) +#define DCSR_STOPCYCLE (1<<10) +#define DCSR_STOPTIME (1<<9) +#define DCSR_CAUSE (7<<6) +#define DCSR_DEBUGINT (1<<5) +#define DCSR_HALT (1<<3) +#define DCSR_STEP (1<<2) +#define DCSR_PRV (3<<0) + +#define DCSR_CAUSE_NONE 0 +#define DCSR_CAUSE_SWBP 1 +#define DCSR_CAUSE_HWBP 2 +#define DCSR_CAUSE_DEBUGINT 3 +#define DCSR_CAUSE_STEP 4 +#define DCSR_CAUSE_HALT 5 + +#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4)) +#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5)) +#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11)) + +#define MCONTROL_SELECT (1<<19) +#define MCONTROL_TIMING (1<<18) +#define MCONTROL_ACTION (0x3f<<12) +#define MCONTROL_CHAIN (1<<11) +#define MCONTROL_MATCH (0xf<<7) +#define MCONTROL_M (1<<6) +#define MCONTROL_H (1<<5) +#define MCONTROL_S (1<<4) +#define MCONTROL_U (1<<3) +#define MCONTROL_EXECUTE (1<<2) +#define MCONTROL_STORE (1<<1) +#define MCONTROL_LOAD (1<<0) + +#define MCONTROL_TYPE_NONE 0 +#define MCONTROL_TYPE_MATCH 2 + +#define MCONTROL_ACTION_DEBUG_EXCEPTION 0 +#define MCONTROL_ACTION_DEBUG_MODE 1 +#define MCONTROL_ACTION_TRACE_START 2 +#define MCONTROL_ACTION_TRACE_STOP 3 +#define MCONTROL_ACTION_TRACE_EMIT 4 + +#define MCONTROL_MATCH_EQUAL 0 +#define MCONTROL_MATCH_NAPOT 1 +#define MCONTROL_MATCH_GE 2 +#define MCONTROL_MATCH_LT 3 +#define MCONTROL_MATCH_MASK_LOW 4 +#define MCONTROL_MATCH_MASK_HIGH 5 + +#define MIP_SSIP (1 << IRQ_S_SOFT) +#define MIP_HSIP (1 << IRQ_H_SOFT) +#define MIP_MSIP (1 << IRQ_M_SOFT) +#define MIP_STIP (1 << IRQ_S_TIMER) +#define MIP_HTIP (1 << IRQ_H_TIMER) +#define MIP_MTIP (1 << IRQ_M_TIMER) +#define MIP_SEIP (1 << IRQ_S_EXT) +#define MIP_HEIP (1 << IRQ_H_EXT) +#define MIP_MEIP (1 << IRQ_M_EXT) + +#define MIE_SSIE MIP_SSIP +#define MIE_HSIE MIP_HSIP +#define MIE_MSIE MIP_MSIP +#define MIE_STIE MIP_STIP +#define MIE_HTIE MIP_HTIP +#define MIE_MTIE MIP_MTIP +#define MIE_SEIE MIP_SEIP +#define MIE_HEIE MIP_HEIP +#define MIE_MEIE MIP_MEIP + +#define SIP_SSIP MIP_SSIP +#define SIP_STIP MIP_STIP + +#define PRV_U 0 +#define PRV_S 1 +#define PRV_H 2 +#define PRV_M 3 + +#define VM_MBARE 0 +#define VM_MBB 1 +#define VM_MBBID 2 +#define VM_SV32 8 +#define VM_SV39 9 +#define VM_SV48 10 + +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_S_EXT 9 +#define IRQ_H_EXT 10 +#define IRQ_M_EXT 11 +#define IRQ_COP 12 +#define IRQ_HOST 13 + +#define DEFAULT_RSTVEC 0x00001000 +#define DEFAULT_NMIVEC 0x00001004 +#define DEFAULT_MTVEC 0x00001010 +#define CONFIG_STRING_ADDR 0x0000100C +#define EXT_IO_BASE 0x40000000 +#define DRAM_BASE 0x80000000 + +// page table entry (PTE) fields +#define PTE_V 0x001 // Valid +#define PTE_R 0x002 // Read +#define PTE_W 0x004 // Write +#define PTE_X 0x008 // Execute +#define PTE_U 0x010 // User +#define PTE_G 0x020 // Global +#define PTE_A 0x040 // Accessed +#define PTE_D 0x080 // Dirty +#define PTE_SOFT 0x300 // Reserved for Software + +#define PTE_PPN_SHIFT 10 + +#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) + +#ifdef __riscv + +#ifdef __riscv64 +# define MSTATUS_SD MSTATUS64_SD +# define SSTATUS_SD SSTATUS64_SD +# define RISCV_PGLEVEL_BITS 9 +#else +# define MSTATUS_SD MSTATUS32_SD +# define SSTATUS_SD SSTATUS32_SD +# define RISCV_PGLEVEL_BITS 10 +#endif +#define RISCV_PGSHIFT 12 +#define RISCV_PGSIZE (1 << RISCV_PGSHIFT) + +#ifndef __ASSEMBLER__ + +#ifdef __GNUC__ + +#define read_csr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define write_csr(reg, val) ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ + else \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) + +#define swap_csr(reg, val) ({ unsigned long __tmp; \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \ + else \ + asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \ + __tmp; }) + +#define set_csr(reg, bit) ({ unsigned long __tmp; \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ + else \ + asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ + __tmp; }) + +#define clear_csr(reg, bit) ({ unsigned long __tmp; \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ + else \ + asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ + __tmp; }) + +#define rdtime() read_csr(time) +#define rdcycle() read_csr(cycle) +#define rdinstret() read_csr(instret) + +#endif + +#endif + +#endif + +#endif +/* Automatically generated by parse-opcodes */ +#ifndef RISCV_ENCODING_H +#define RISCV_ENCODING_H +#define MATCH_BEQ 0x63 +#define MASK_BEQ 0x707f +#define MATCH_BNE 0x1063 +#define MASK_BNE 0x707f +#define MATCH_BLT 0x4063 +#define MASK_BLT 0x707f +#define MATCH_BGE 0x5063 +#define MASK_BGE 0x707f +#define MATCH_BLTU 0x6063 +#define MASK_BLTU 0x707f +#define MATCH_BGEU 0x7063 +#define MASK_BGEU 0x707f +#define MATCH_JALR 0x67 +#define MASK_JALR 0x707f +#define MATCH_JAL 0x6f +#define MASK_JAL 0x7f +#define MATCH_LUI 0x37 +#define MASK_LUI 0x7f +#define MATCH_AUIPC 0x17 +#define MASK_AUIPC 0x7f +#define MATCH_ADDI 0x13 +#define MASK_ADDI 0x707f +#define MATCH_SLLI 0x1013 +#define MASK_SLLI 0xfc00707f +#define MATCH_SLTI 0x2013 +#define MASK_SLTI 0x707f +#define MATCH_SLTIU 0x3013 +#define MASK_SLTIU 0x707f +#define MATCH_XORI 0x4013 +#define MASK_XORI 0x707f +#define MATCH_SRLI 0x5013 +#define MASK_SRLI 0xfc00707f +#define MATCH_SRAI 0x40005013 +#define MASK_SRAI 0xfc00707f +#define MATCH_ORI 0x6013 +#define MASK_ORI 0x707f +#define MATCH_ANDI 0x7013 +#define MASK_ANDI 0x707f +#define MATCH_ADD 0x33 +#define MASK_ADD 0xfe00707f +#define MATCH_SUB 0x40000033 +#define MASK_SUB 0xfe00707f +#define MATCH_SLL 0x1033 +#define MASK_SLL 0xfe00707f +#define MATCH_SLT 0x2033 +#define MASK_SLT 0xfe00707f +#define MATCH_SLTU 0x3033 +#define MASK_SLTU 0xfe00707f +#define MATCH_XOR 0x4033 +#define MASK_XOR 0xfe00707f +#define MATCH_SRL 0x5033 +#define MASK_SRL 0xfe00707f +#define MATCH_SRA 0x40005033 +#define MASK_SRA 0xfe00707f +#define MATCH_OR 0x6033 +#define MASK_OR 0xfe00707f +#define MATCH_AND 0x7033 +#define MASK_AND 0xfe00707f +#define MATCH_ADDIW 0x1b +#define MASK_ADDIW 0x707f +#define MATCH_SLLIW 0x101b +#define MASK_SLLIW 0xfe00707f +#define MATCH_SRLIW 0x501b +#define MASK_SRLIW 0xfe00707f +#define MATCH_SRAIW 0x4000501b +#define MASK_SRAIW 0xfe00707f +#define MATCH_ADDW 0x3b +#define MASK_ADDW 0xfe00707f +#define MATCH_SUBW 0x4000003b +#define MASK_SUBW 0xfe00707f +#define MATCH_SLLW 0x103b +#define MASK_SLLW 0xfe00707f +#define MATCH_SRLW 0x503b +#define MASK_SRLW 0xfe00707f +#define MATCH_SRAW 0x4000503b +#define MASK_SRAW 0xfe00707f +#define MATCH_LB 0x3 +#define MASK_LB 0x707f +#define MATCH_LH 0x1003 +#define MASK_LH 0x707f +#define MATCH_LW 0x2003 +#define MASK_LW 0x707f +#define MATCH_LD 0x3003 +#define MASK_LD 0x707f +#define MATCH_LBU 0x4003 +#define MASK_LBU 0x707f +#define MATCH_LHU 0x5003 +#define MASK_LHU 0x707f +#define MATCH_LWU 0x6003 +#define MASK_LWU 0x707f +#define MATCH_SB 0x23 +#define MASK_SB 0x707f +#define MATCH_SH 0x1023 +#define MASK_SH 0x707f +#define MATCH_SW 0x2023 +#define MASK_SW 0x707f +#define MATCH_SD 0x3023 +#define MASK_SD 0x707f +#define MATCH_FENCE 0xf +#define MASK_FENCE 0x707f +#define MATCH_FENCE_I 0x100f +#define MASK_FENCE_I 0x707f +#define MATCH_MUL 0x2000033 +#define MASK_MUL 0xfe00707f +#define MATCH_MULH 0x2001033 +#define MASK_MULH 0xfe00707f +#define MATCH_MULHSU 0x2002033 +#define MASK_MULHSU 0xfe00707f +#define MATCH_MULHU 0x2003033 +#define MASK_MULHU 0xfe00707f +#define MATCH_DIV 0x2004033 +#define MASK_DIV 0xfe00707f +#define MATCH_DIVU 0x2005033 +#define MASK_DIVU 0xfe00707f +#define MATCH_REM 0x2006033 +#define MASK_REM 0xfe00707f +#define MATCH_REMU 0x2007033 +#define MASK_REMU 0xfe00707f +#define MATCH_MULW 0x200003b +#define MASK_MULW 0xfe00707f +#define MATCH_DIVW 0x200403b +#define MASK_DIVW 0xfe00707f +#define MATCH_DIVUW 0x200503b +#define MASK_DIVUW 0xfe00707f +#define MATCH_REMW 0x200603b +#define MASK_REMW 0xfe00707f +#define MATCH_REMUW 0x200703b +#define MASK_REMUW 0xfe00707f +#define MATCH_AMOADD_W 0x202f +#define MASK_AMOADD_W 0xf800707f +#define MATCH_AMOXOR_W 0x2000202f +#define MASK_AMOXOR_W 0xf800707f +#define MATCH_AMOOR_W 0x4000202f +#define MASK_AMOOR_W 0xf800707f +#define MATCH_AMOAND_W 0x6000202f +#define MASK_AMOAND_W 0xf800707f +#define MATCH_AMOMIN_W 0x8000202f +#define MASK_AMOMIN_W 0xf800707f +#define MATCH_AMOMAX_W 0xa000202f +#define MASK_AMOMAX_W 0xf800707f +#define MATCH_AMOMINU_W 0xc000202f +#define MASK_AMOMINU_W 0xf800707f +#define MATCH_AMOMAXU_W 0xe000202f +#define MASK_AMOMAXU_W 0xf800707f +#define MATCH_AMOSWAP_W 0x800202f +#define MASK_AMOSWAP_W 0xf800707f +#define MATCH_LR_W 0x1000202f +#define MASK_LR_W 0xf9f0707f +#define MATCH_SC_W 0x1800202f +#define MASK_SC_W 0xf800707f +#define MATCH_AMOADD_D 0x302f +#define MASK_AMOADD_D 0xf800707f +#define MATCH_AMOXOR_D 0x2000302f +#define MASK_AMOXOR_D 0xf800707f +#define MATCH_AMOOR_D 0x4000302f +#define MASK_AMOOR_D 0xf800707f +#define MATCH_AMOAND_D 0x6000302f +#define MASK_AMOAND_D 0xf800707f +#define MATCH_AMOMIN_D 0x8000302f +#define MASK_AMOMIN_D 0xf800707f +#define MATCH_AMOMAX_D 0xa000302f +#define MASK_AMOMAX_D 0xf800707f +#define MATCH_AMOMINU_D 0xc000302f +#define MASK_AMOMINU_D 0xf800707f +#define MATCH_AMOMAXU_D 0xe000302f +#define MASK_AMOMAXU_D 0xf800707f +#define MATCH_AMOSWAP_D 0x800302f +#define MASK_AMOSWAP_D 0xf800707f +#define MATCH_LR_D 0x1000302f +#define MASK_LR_D 0xf9f0707f +#define MATCH_SC_D 0x1800302f +#define MASK_SC_D 0xf800707f +#define MATCH_ECALL 0x73 +#define MASK_ECALL 0xffffffff +#define MATCH_EBREAK 0x100073 +#define MASK_EBREAK 0xffffffff +#define MATCH_URET 0x200073 +#define MASK_URET 0xffffffff +#define MATCH_SRET 0x10200073 +#define MASK_SRET 0xffffffff +#define MATCH_HRET 0x20200073 +#define MASK_HRET 0xffffffff +#define MATCH_MRET 0x30200073 +#define MASK_MRET 0xffffffff +#define MATCH_DRET 0x7b200073 +#define MASK_DRET 0xffffffff +#define MATCH_SFENCE_VM 0x10400073 +#define MASK_SFENCE_VM 0xfff07fff +#define MATCH_WFI 0x10500073 +#define MASK_WFI 0xffffffff +#define MATCH_CSRRW 0x1073 +#define MASK_CSRRW 0x707f +#define MATCH_CSRRS 0x2073 +#define MASK_CSRRS 0x707f +#define MATCH_CSRRC 0x3073 +#define MASK_CSRRC 0x707f +#define MATCH_CSRRWI 0x5073 +#define MASK_CSRRWI 0x707f +#define MATCH_CSRRSI 0x6073 +#define MASK_CSRRSI 0x707f +#define MATCH_CSRRCI 0x7073 +#define MASK_CSRRCI 0x707f +#define MATCH_FADD_S 0x53 +#define MASK_FADD_S 0xfe00007f +#define MATCH_FSUB_S 0x8000053 +#define MASK_FSUB_S 0xfe00007f +#define MATCH_FMUL_S 0x10000053 +#define MASK_FMUL_S 0xfe00007f +#define MATCH_FDIV_S 0x18000053 +#define MASK_FDIV_S 0xfe00007f +#define MATCH_FSGNJ_S 0x20000053 +#define MASK_FSGNJ_S 0xfe00707f +#define MATCH_FSGNJN_S 0x20001053 +#define MASK_FSGNJN_S 0xfe00707f +#define MATCH_FSGNJX_S 0x20002053 +#define MASK_FSGNJX_S 0xfe00707f +#define MATCH_FMIN_S 0x28000053 +#define MASK_FMIN_S 0xfe00707f +#define MATCH_FMAX_S 0x28001053 +#define MASK_FMAX_S 0xfe00707f +#define MATCH_FSQRT_S 0x58000053 +#define MASK_FSQRT_S 0xfff0007f +#define MATCH_FADD_D 0x2000053 +#define MASK_FADD_D 0xfe00007f +#define MATCH_FSUB_D 0xa000053 +#define MASK_FSUB_D 0xfe00007f +#define MATCH_FMUL_D 0x12000053 +#define MASK_FMUL_D 0xfe00007f +#define MATCH_FDIV_D 0x1a000053 +#define MASK_FDIV_D 0xfe00007f +#define MATCH_FSGNJ_D 0x22000053 +#define MASK_FSGNJ_D 0xfe00707f +#define MATCH_FSGNJN_D 0x22001053 +#define MASK_FSGNJN_D 0xfe00707f +#define MATCH_FSGNJX_D 0x22002053 +#define MASK_FSGNJX_D 0xfe00707f +#define MATCH_FMIN_D 0x2a000053 +#define MASK_FMIN_D 0xfe00707f +#define MATCH_FMAX_D 0x2a001053 +#define MASK_FMAX_D 0xfe00707f +#define MATCH_FCVT_S_D 0x40100053 +#define MASK_FCVT_S_D 0xfff0007f +#define MATCH_FCVT_D_S 0x42000053 +#define MASK_FCVT_D_S 0xfff0007f +#define MATCH_FSQRT_D 0x5a000053 +#define MASK_FSQRT_D 0xfff0007f +#define MATCH_FLE_S 0xa0000053 +#define MASK_FLE_S 0xfe00707f +#define MATCH_FLT_S 0xa0001053 +#define MASK_FLT_S 0xfe00707f +#define MATCH_FEQ_S 0xa0002053 +#define MASK_FEQ_S 0xfe00707f +#define MATCH_FLE_D 0xa2000053 +#define MASK_FLE_D 0xfe00707f +#define MATCH_FLT_D 0xa2001053 +#define MASK_FLT_D 0xfe00707f +#define MATCH_FEQ_D 0xa2002053 +#define MASK_FEQ_D 0xfe00707f +#define MATCH_FCVT_W_S 0xc0000053 +#define MASK_FCVT_W_S 0xfff0007f +#define MATCH_FCVT_WU_S 0xc0100053 +#define MASK_FCVT_WU_S 0xfff0007f +#define MATCH_FCVT_L_S 0xc0200053 +#define MASK_FCVT_L_S 0xfff0007f +#define MATCH_FCVT_LU_S 0xc0300053 +#define MASK_FCVT_LU_S 0xfff0007f +#define MATCH_FMV_X_S 0xe0000053 +#define MASK_FMV_X_S 0xfff0707f +#define MATCH_FCLASS_S 0xe0001053 +#define MASK_FCLASS_S 0xfff0707f +#define MATCH_FCVT_W_D 0xc2000053 +#define MASK_FCVT_W_D 0xfff0007f +#define MATCH_FCVT_WU_D 0xc2100053 +#define MASK_FCVT_WU_D 0xfff0007f +#define MATCH_FCVT_L_D 0xc2200053 +#define MASK_FCVT_L_D 0xfff0007f +#define MATCH_FCVT_LU_D 0xc2300053 +#define MASK_FCVT_LU_D 0xfff0007f +#define MATCH_FMV_X_D 0xe2000053 +#define MASK_FMV_X_D 0xfff0707f +#define MATCH_FCLASS_D 0xe2001053 +#define MASK_FCLASS_D 0xfff0707f +#define MATCH_FCVT_S_W 0xd0000053 +#define MASK_FCVT_S_W 0xfff0007f +#define MATCH_FCVT_S_WU 0xd0100053 +#define MASK_FCVT_S_WU 0xfff0007f +#define MATCH_FCVT_S_L 0xd0200053 +#define MASK_FCVT_S_L 0xfff0007f +#define MATCH_FCVT_S_LU 0xd0300053 +#define MASK_FCVT_S_LU 0xfff0007f +#define MATCH_FMV_S_X 0xf0000053 +#define MASK_FMV_S_X 0xfff0707f +#define MATCH_FCVT_D_W 0xd2000053 +#define MASK_FCVT_D_W 0xfff0007f +#define MATCH_FCVT_D_WU 0xd2100053 +#define MASK_FCVT_D_WU 0xfff0007f +#define MATCH_FCVT_D_L 0xd2200053 +#define MASK_FCVT_D_L 0xfff0007f +#define MATCH_FCVT_D_LU 0xd2300053 +#define MASK_FCVT_D_LU 0xfff0007f +#define MATCH_FMV_D_X 0xf2000053 +#define MASK_FMV_D_X 0xfff0707f +#define MATCH_FLW 0x2007 +#define MASK_FLW 0x707f +#define MATCH_FLD 0x3007 +#define MASK_FLD 0x707f +#define MATCH_FSW 0x2027 +#define MASK_FSW 0x707f +#define MATCH_FSD 0x3027 +#define MASK_FSD 0x707f +#define MATCH_FMADD_S 0x43 +#define MASK_FMADD_S 0x600007f +#define MATCH_FMSUB_S 0x47 +#define MASK_FMSUB_S 0x600007f +#define MATCH_FNMSUB_S 0x4b +#define MASK_FNMSUB_S 0x600007f +#define MATCH_FNMADD_S 0x4f +#define MASK_FNMADD_S 0x600007f +#define MATCH_FMADD_D 0x2000043 +#define MASK_FMADD_D 0x600007f +#define MATCH_FMSUB_D 0x2000047 +#define MASK_FMSUB_D 0x600007f +#define MATCH_FNMSUB_D 0x200004b +#define MASK_FNMSUB_D 0x600007f +#define MATCH_FNMADD_D 0x200004f +#define MASK_FNMADD_D 0x600007f +#define MATCH_C_NOP 0x1 +#define MASK_C_NOP 0xffff +#define MATCH_C_ADDI16SP 0x6101 +#define MASK_C_ADDI16SP 0xef83 +#define MATCH_C_JR 0x8002 +#define MASK_C_JR 0xf07f +#define MATCH_C_JALR 0x9002 +#define MASK_C_JALR 0xf07f +#define MATCH_C_EBREAK 0x9002 +#define MASK_C_EBREAK 0xffff +#define MATCH_C_LD 0x6000 +#define MASK_C_LD 0xe003 +#define MATCH_C_SD 0xe000 +#define MASK_C_SD 0xe003 +#define MATCH_C_ADDIW 0x2001 +#define MASK_C_ADDIW 0xe003 +#define MATCH_C_LDSP 0x6002 +#define MASK_C_LDSP 0xe003 +#define MATCH_C_SDSP 0xe002 +#define MASK_C_SDSP 0xe003 +#define MATCH_C_ADDI4SPN 0x0 +#define MASK_C_ADDI4SPN 0xe003 +#define MATCH_C_FLD 0x2000 +#define MASK_C_FLD 0xe003 +#define MATCH_C_LW 0x4000 +#define MASK_C_LW 0xe003 +#define MATCH_C_FLW 0x6000 +#define MASK_C_FLW 0xe003 +#define MATCH_C_FSD 0xa000 +#define MASK_C_FSD 0xe003 +#define MATCH_C_SW 0xc000 +#define MASK_C_SW 0xe003 +#define MATCH_C_FSW 0xe000 +#define MASK_C_FSW 0xe003 +#define MATCH_C_ADDI 0x1 +#define MASK_C_ADDI 0xe003 +#define MATCH_C_JAL 0x2001 +#define MASK_C_JAL 0xe003 +#define MATCH_C_LI 0x4001 +#define MASK_C_LI 0xe003 +#define MATCH_C_LUI 0x6001 +#define MASK_C_LUI 0xe003 +#define MATCH_C_SRLI 0x8001 +#define MASK_C_SRLI 0xec03 +#define MATCH_C_SRAI 0x8401 +#define MASK_C_SRAI 0xec03 +#define MATCH_C_ANDI 0x8801 +#define MASK_C_ANDI 0xec03 +#define MATCH_C_SUB 0x8c01 +#define MASK_C_SUB 0xfc63 +#define MATCH_C_XOR 0x8c21 +#define MASK_C_XOR 0xfc63 +#define MATCH_C_OR 0x8c41 +#define MASK_C_OR 0xfc63 +#define MATCH_C_AND 0x8c61 +#define MASK_C_AND 0xfc63 +#define MATCH_C_SUBW 0x9c01 +#define MASK_C_SUBW 0xfc63 +#define MATCH_C_ADDW 0x9c21 +#define MASK_C_ADDW 0xfc63 +#define MATCH_C_J 0xa001 +#define MASK_C_J 0xe003 +#define MATCH_C_BEQZ 0xc001 +#define MASK_C_BEQZ 0xe003 +#define MATCH_C_BNEZ 0xe001 +#define MASK_C_BNEZ 0xe003 +#define MATCH_C_SLLI 0x2 +#define MASK_C_SLLI 0xe003 +#define MATCH_C_FLDSP 0x2002 +#define MASK_C_FLDSP 0xe003 +#define MATCH_C_LWSP 0x4002 +#define MASK_C_LWSP 0xe003 +#define MATCH_C_FLWSP 0x6002 +#define MASK_C_FLWSP 0xe003 +#define MATCH_C_MV 0x8002 +#define MASK_C_MV 0xf003 +#define MATCH_C_ADD 0x9002 +#define MASK_C_ADD 0xf003 +#define MATCH_C_FSDSP 0xa002 +#define MASK_C_FSDSP 0xe003 +#define MATCH_C_SWSP 0xc002 +#define MASK_C_SWSP 0xe003 +#define MATCH_C_FSWSP 0xe002 +#define MASK_C_FSWSP 0xe003 +#define MATCH_CUSTOM0 0xb +#define MASK_CUSTOM0 0x707f +#define MATCH_CUSTOM0_RS1 0x200b +#define MASK_CUSTOM0_RS1 0x707f +#define MATCH_CUSTOM0_RS1_RS2 0x300b +#define MASK_CUSTOM0_RS1_RS2 0x707f +#define MATCH_CUSTOM0_RD 0x400b +#define MASK_CUSTOM0_RD 0x707f +#define MATCH_CUSTOM0_RD_RS1 0x600b +#define MASK_CUSTOM0_RD_RS1 0x707f +#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b +#define MASK_CUSTOM0_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM1 0x2b +#define MASK_CUSTOM1 0x707f +#define MATCH_CUSTOM1_RS1 0x202b +#define MASK_CUSTOM1_RS1 0x707f +#define MATCH_CUSTOM1_RS1_RS2 0x302b +#define MASK_CUSTOM1_RS1_RS2 0x707f +#define MATCH_CUSTOM1_RD 0x402b +#define MASK_CUSTOM1_RD 0x707f +#define MATCH_CUSTOM1_RD_RS1 0x602b +#define MASK_CUSTOM1_RD_RS1 0x707f +#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b +#define MASK_CUSTOM1_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM2 0x5b +#define MASK_CUSTOM2 0x707f +#define MATCH_CUSTOM2_RS1 0x205b +#define MASK_CUSTOM2_RS1 0x707f +#define MATCH_CUSTOM2_RS1_RS2 0x305b +#define MASK_CUSTOM2_RS1_RS2 0x707f +#define MATCH_CUSTOM2_RD 0x405b +#define MASK_CUSTOM2_RD 0x707f +#define MATCH_CUSTOM2_RD_RS1 0x605b +#define MASK_CUSTOM2_RD_RS1 0x707f +#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b +#define MASK_CUSTOM2_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM3 0x7b +#define MASK_CUSTOM3 0x707f +#define MATCH_CUSTOM3_RS1 0x207b +#define MASK_CUSTOM3_RS1 0x707f +#define MATCH_CUSTOM3_RS1_RS2 0x307b +#define MASK_CUSTOM3_RS1_RS2 0x707f +#define MATCH_CUSTOM3_RD 0x407b +#define MASK_CUSTOM3_RD 0x707f +#define MATCH_CUSTOM3_RD_RS1 0x607b +#define MASK_CUSTOM3_RD_RS1 0x707f +#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b +#define MASK_CUSTOM3_RD_RS1_RS2 0x707f +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3 +#define CSR_CYCLE 0xc00 +#define CSR_TIME 0xc01 +#define CSR_INSTRET 0xc02 +#define CSR_HPMCOUNTER3 0xc03 +#define CSR_HPMCOUNTER4 0xc04 +#define CSR_HPMCOUNTER5 0xc05 +#define CSR_HPMCOUNTER6 0xc06 +#define CSR_HPMCOUNTER7 0xc07 +#define CSR_HPMCOUNTER8 0xc08 +#define CSR_HPMCOUNTER9 0xc09 +#define CSR_HPMCOUNTER10 0xc0a +#define CSR_HPMCOUNTER11 0xc0b +#define CSR_HPMCOUNTER12 0xc0c +#define CSR_HPMCOUNTER13 0xc0d +#define CSR_HPMCOUNTER14 0xc0e +#define CSR_HPMCOUNTER15 0xc0f +#define CSR_HPMCOUNTER16 0xc10 +#define CSR_HPMCOUNTER17 0xc11 +#define CSR_HPMCOUNTER18 0xc12 +#define CSR_HPMCOUNTER19 0xc13 +#define CSR_HPMCOUNTER20 0xc14 +#define CSR_HPMCOUNTER21 0xc15 +#define CSR_HPMCOUNTER22 0xc16 +#define CSR_HPMCOUNTER23 0xc17 +#define CSR_HPMCOUNTER24 0xc18 +#define CSR_HPMCOUNTER25 0xc19 +#define CSR_HPMCOUNTER26 0xc1a +#define CSR_HPMCOUNTER27 0xc1b +#define CSR_HPMCOUNTER28 0xc1c +#define CSR_HPMCOUNTER29 0xc1d +#define CSR_HPMCOUNTER30 0xc1e +#define CSR_HPMCOUNTER31 0xc1f +#define CSR_SSTATUS 0x100 +#define CSR_SIE 0x104 +#define CSR_STVEC 0x105 +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_SBADADDR 0x143 +#define CSR_SIP 0x144 +#define CSR_SPTBR 0x180 +#define CSR_MSTATUS 0x300 +#define CSR_MISA 0x301 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 +#define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 +#define CSR_MCOUNTEREN 0x306 +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MBADADDR 0x343 +#define CSR_MIP 0x344 +#define CSR_TSELECT 0x7a0 +#define CSR_TDATA1 0x7a1 +#define CSR_TDATA2 0x7a2 +#define CSR_TDATA3 0x7a3 +#define CSR_DCSR 0x7b0 +#define CSR_DPC 0x7b1 +#define CSR_DSCRATCH 0x7b2 +#define CSR_MCYCLE 0xb00 +#define CSR_MINSTRET 0xb02 +#define CSR_MHPMCOUNTER3 0xb03 +#define CSR_MHPMCOUNTER4 0xb04 +#define CSR_MHPMCOUNTER5 0xb05 +#define CSR_MHPMCOUNTER6 0xb06 +#define CSR_MHPMCOUNTER7 0xb07 +#define CSR_MHPMCOUNTER8 0xb08 +#define CSR_MHPMCOUNTER9 0xb09 +#define CSR_MHPMCOUNTER10 0xb0a +#define CSR_MHPMCOUNTER11 0xb0b +#define CSR_MHPMCOUNTER12 0xb0c +#define CSR_MHPMCOUNTER13 0xb0d +#define CSR_MHPMCOUNTER14 0xb0e +#define CSR_MHPMCOUNTER15 0xb0f +#define CSR_MHPMCOUNTER16 0xb10 +#define CSR_MHPMCOUNTER17 0xb11 +#define CSR_MHPMCOUNTER18 0xb12 +#define CSR_MHPMCOUNTER19 0xb13 +#define CSR_MHPMCOUNTER20 0xb14 +#define CSR_MHPMCOUNTER21 0xb15 +#define CSR_MHPMCOUNTER22 0xb16 +#define CSR_MHPMCOUNTER23 0xb17 +#define CSR_MHPMCOUNTER24 0xb18 +#define CSR_MHPMCOUNTER25 0xb19 +#define CSR_MHPMCOUNTER26 0xb1a +#define CSR_MHPMCOUNTER27 0xb1b +#define CSR_MHPMCOUNTER28 0xb1c +#define CSR_MHPMCOUNTER29 0xb1d +#define CSR_MHPMCOUNTER30 0xb1e +#define CSR_MHPMCOUNTER31 0xb1f +#define CSR_MUCOUNTEREN 0x320 +#define CSR_MSCOUNTEREN 0x321 +#define CSR_MHPMEVENT3 0x323 +#define CSR_MHPMEVENT4 0x324 +#define CSR_MHPMEVENT5 0x325 +#define CSR_MHPMEVENT6 0x326 +#define CSR_MHPMEVENT7 0x327 +#define CSR_MHPMEVENT8 0x328 +#define CSR_MHPMEVENT9 0x329 +#define CSR_MHPMEVENT10 0x32a +#define CSR_MHPMEVENT11 0x32b +#define CSR_MHPMEVENT12 0x32c +#define CSR_MHPMEVENT13 0x32d +#define CSR_MHPMEVENT14 0x32e +#define CSR_MHPMEVENT15 0x32f +#define CSR_MHPMEVENT16 0x330 +#define CSR_MHPMEVENT17 0x331 +#define CSR_MHPMEVENT18 0x332 +#define CSR_MHPMEVENT19 0x333 +#define CSR_MHPMEVENT20 0x334 +#define CSR_MHPMEVENT21 0x335 +#define CSR_MHPMEVENT22 0x336 +#define CSR_MHPMEVENT23 0x337 +#define CSR_MHPMEVENT24 0x338 +#define CSR_MHPMEVENT25 0x339 +#define CSR_MHPMEVENT26 0x33a +#define CSR_MHPMEVENT27 0x33b +#define CSR_MHPMEVENT28 0x33c +#define CSR_MHPMEVENT29 0x33d +#define CSR_MHPMEVENT30 0x33e +#define CSR_MHPMEVENT31 0x33f +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14 +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 +#define CSR_HPMCOUNTER3H 0xc83 +#define CSR_HPMCOUNTER4H 0xc84 +#define CSR_HPMCOUNTER5H 0xc85 +#define CSR_HPMCOUNTER6H 0xc86 +#define CSR_HPMCOUNTER7H 0xc87 +#define CSR_HPMCOUNTER8H 0xc88 +#define CSR_HPMCOUNTER9H 0xc89 +#define CSR_HPMCOUNTER10H 0xc8a +#define CSR_HPMCOUNTER11H 0xc8b +#define CSR_HPMCOUNTER12H 0xc8c +#define CSR_HPMCOUNTER13H 0xc8d +#define CSR_HPMCOUNTER14H 0xc8e +#define CSR_HPMCOUNTER15H 0xc8f +#define CSR_HPMCOUNTER16H 0xc90 +#define CSR_HPMCOUNTER17H 0xc91 +#define CSR_HPMCOUNTER18H 0xc92 +#define CSR_HPMCOUNTER19H 0xc93 +#define CSR_HPMCOUNTER20H 0xc94 +#define CSR_HPMCOUNTER21H 0xc95 +#define CSR_HPMCOUNTER22H 0xc96 +#define CSR_HPMCOUNTER23H 0xc97 +#define CSR_HPMCOUNTER24H 0xc98 +#define CSR_HPMCOUNTER25H 0xc99 +#define CSR_HPMCOUNTER26H 0xc9a +#define CSR_HPMCOUNTER27H 0xc9b +#define CSR_HPMCOUNTER28H 0xc9c +#define CSR_HPMCOUNTER29H 0xc9d +#define CSR_HPMCOUNTER30H 0xc9e +#define CSR_HPMCOUNTER31H 0xc9f +#define CSR_MCYCLEH 0xb80 +#define CSR_MINSTRETH 0xb82 +#define CSR_MHPMCOUNTER3H 0xb83 +#define CSR_MHPMCOUNTER4H 0xb84 +#define CSR_MHPMCOUNTER5H 0xb85 +#define CSR_MHPMCOUNTER6H 0xb86 +#define CSR_MHPMCOUNTER7H 0xb87 +#define CSR_MHPMCOUNTER8H 0xb88 +#define CSR_MHPMCOUNTER9H 0xb89 +#define CSR_MHPMCOUNTER10H 0xb8a +#define CSR_MHPMCOUNTER11H 0xb8b +#define CSR_MHPMCOUNTER12H 0xb8c +#define CSR_MHPMCOUNTER13H 0xb8d +#define CSR_MHPMCOUNTER14H 0xb8e +#define CSR_MHPMCOUNTER15H 0xb8f +#define CSR_MHPMCOUNTER16H 0xb90 +#define CSR_MHPMCOUNTER17H 0xb91 +#define CSR_MHPMCOUNTER18H 0xb92 +#define CSR_MHPMCOUNTER19H 0xb93 +#define CSR_MHPMCOUNTER20H 0xb94 +#define CSR_MHPMCOUNTER21H 0xb95 +#define CSR_MHPMCOUNTER22H 0xb96 +#define CSR_MHPMCOUNTER23H 0xb97 +#define CSR_MHPMCOUNTER24H 0xb98 +#define CSR_MHPMCOUNTER25H 0xb99 +#define CSR_MHPMCOUNTER26H 0xb9a +#define CSR_MHPMCOUNTER27H 0xb9b +#define CSR_MHPMCOUNTER28H 0xb9c +#define CSR_MHPMCOUNTER29H 0xb9d +#define CSR_MHPMCOUNTER30H 0xb9e +#define CSR_MHPMCOUNTER31H 0xb9f + +#define CSR_MTVT 0x307 +#define CSR_MNXTI 0x345 + +#define CSR_MNVEC 0x7C3 + +#define CSR_MIRQ_ENTRY 0x7EC +#define CSR_MINTSEL_JAL 0x7ED +#define CSR_PUSHMCAUSE 0x7EE +#define CSR_PUSHMEPC 0x7EF +#define CSR_PUSHMXSTATUS 0x7EB +#define CSR_WFE 0x810 +#define CSR_SLEEPVALUE 0x811 +#define CSR_TXEVT 0x812 + +#define CSR_MMISC_CTL 0x7d0 +#define CSR_MXSTATUS 0x7c4 + + +#define CAUSE_MISALIGNED_FETCH 0x0 +#define CAUSE_FAULT_FETCH 0x1 +#define CAUSE_ILLEGAL_INSTRUCTION 0x2 +#define CAUSE_BREAKPOINT 0x3 +#define CAUSE_MISALIGNED_LOAD 0x4 +#define CAUSE_FAULT_LOAD 0x5 +#define CAUSE_MISALIGNED_STORE 0x6 +#define CAUSE_FAULT_STORE 0x7 +#define CAUSE_USER_ECALL 0x8 +#define CAUSE_SUPERVISOR_ECALL 0x9 +#define CAUSE_HYPERVISOR_ECALL 0xa +#define CAUSE_MACHINE_ECALL 0xb +#endif +#ifdef DECLARE_INSN +DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) +DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) +DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) +DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) +DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) +DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) +DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) +DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) +DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) +DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) +DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) +DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) +DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) +DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) +DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) +DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) +DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) +DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) +DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) +DECLARE_INSN(add, MATCH_ADD, MASK_ADD) +DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) +DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) +DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) +DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) +DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) +DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) +DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) +DECLARE_INSN(or, MATCH_OR, MASK_OR) +DECLARE_INSN(and, MATCH_AND, MASK_AND) +DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) +DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) +DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) +DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) +DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) +DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) +DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) +DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) +DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) +DECLARE_INSN(lb, MATCH_LB, MASK_LB) +DECLARE_INSN(lh, MATCH_LH, MASK_LH) +DECLARE_INSN(lw, MATCH_LW, MASK_LW) +DECLARE_INSN(ld, MATCH_LD, MASK_LD) +DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) +DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) +DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) +DECLARE_INSN(sb, MATCH_SB, MASK_SB) +DECLARE_INSN(sh, MATCH_SH, MASK_SH) +DECLARE_INSN(sw, MATCH_SW, MASK_SW) +DECLARE_INSN(sd, MATCH_SD, MASK_SD) +DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) +DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) +DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) +DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) +DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) +DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) +DECLARE_INSN(div, MATCH_DIV, MASK_DIV) +DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) +DECLARE_INSN(rem, MATCH_REM, MASK_REM) +DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) +DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) +DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) +DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) +DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) +DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) +DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) +DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) +DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) +DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) +DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) +DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) +DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) +DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) +DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) +DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) +DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) +DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) +DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) +DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) +DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) +DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) +DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) +DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) +DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) +DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) +DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) +DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) +DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) +DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) +DECLARE_INSN(uret, MATCH_URET, MASK_URET) +DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) +DECLARE_INSN(hret, MATCH_HRET, MASK_HRET) +DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) +DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) +DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM) +DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) +DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) +DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) +DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) +DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) +DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) +DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) +DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) +DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) +DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) +DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) +DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) +DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) +DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) +DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) +DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) +DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) +DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) +DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) +DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) +DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) +DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) +DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) +DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) +DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) +DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) +DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) +DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) +DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) +DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) +DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) +DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) +DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) +DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) +DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) +DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) +DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) +DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) +DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) +DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S) +DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) +DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) +DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) +DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) +DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) +DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) +DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) +DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) +DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) +DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) +DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) +DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X) +DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) +DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) +DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) +DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) +DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) +DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) +DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) +DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) +DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) +DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) +DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) +DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) +DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) +DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) +DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) +DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) +DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) +DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) +DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) +DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) +DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) +DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK) +DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) +DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) +DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) +DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) +DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) +DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) +DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) +DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) +DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) +DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) +DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) +DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) +DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) +DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) +DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) +DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) +DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) +DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) +DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI) +DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) +DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR) +DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR) +DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND) +DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) +DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) +DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) +DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) +DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) +DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) +DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP) +DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) +DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP) +DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) +DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) +DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP) +DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) +DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP) +DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0) +DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1) +DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2) +DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD) +DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1) +DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2) +DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1) +DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1) +DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2) +DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD) +DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1) +DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2) +DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2) +DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1) +DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2) +DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD) +DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1) +DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2) +DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3) +DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1) +DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) +DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) +DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) +DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) +#endif +#ifdef DECLARE_CSR +DECLARE_CSR(fflags, CSR_FFLAGS) +DECLARE_CSR(frm, CSR_FRM) +DECLARE_CSR(fcsr, CSR_FCSR) +DECLARE_CSR(cycle, CSR_CYCLE) +DECLARE_CSR(time, CSR_TIME) +DECLARE_CSR(instret, CSR_INSTRET) +DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3) +DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4) +DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5) +DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6) +DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7) +DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8) +DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9) +DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10) +DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11) +DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12) +DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13) +DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14) +DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15) +DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16) +DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17) +DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18) +DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19) +DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20) +DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21) +DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22) +DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23) +DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24) +DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25) +DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26) +DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27) +DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28) +DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29) +DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30) +DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31) +DECLARE_CSR(sstatus, CSR_SSTATUS) +DECLARE_CSR(sie, CSR_SIE) +DECLARE_CSR(stvec, CSR_STVEC) +DECLARE_CSR(sscratch, CSR_SSCRATCH) +DECLARE_CSR(sepc, CSR_SEPC) +DECLARE_CSR(scause, CSR_SCAUSE) +DECLARE_CSR(sbadaddr, CSR_SBADADDR) +DECLARE_CSR(sip, CSR_SIP) +DECLARE_CSR(sptbr, CSR_SPTBR) +DECLARE_CSR(mstatus, CSR_MSTATUS) +DECLARE_CSR(misa, CSR_MISA) +DECLARE_CSR(medeleg, CSR_MEDELEG) +DECLARE_CSR(mideleg, CSR_MIDELEG) +DECLARE_CSR(mie, CSR_MIE) +DECLARE_CSR(mtvec, CSR_MTVEC) +DECLARE_CSR(mscratch, CSR_MSCRATCH) +DECLARE_CSR(mepc, CSR_MEPC) +DECLARE_CSR(mcause, CSR_MCAUSE) +DECLARE_CSR(mbadaddr, CSR_MBADADDR) +DECLARE_CSR(mip, CSR_MIP) +DECLARE_CSR(tselect, CSR_TSELECT) +DECLARE_CSR(tdata1, CSR_TDATA1) +DECLARE_CSR(tdata2, CSR_TDATA2) +DECLARE_CSR(tdata3, CSR_TDATA3) +DECLARE_CSR(dcsr, CSR_DCSR) +DECLARE_CSR(dpc, CSR_DPC) +DECLARE_CSR(dscratch, CSR_DSCRATCH) +DECLARE_CSR(mcycle, CSR_MCYCLE) +DECLARE_CSR(minstret, CSR_MINSTRET) +DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3) +DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4) +DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5) +DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6) +DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7) +DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8) +DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9) +DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10) +DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11) +DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12) +DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13) +DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14) +DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15) +DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16) +DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17) +DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18) +DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19) +DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20) +DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21) +DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22) +DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23) +DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24) +DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25) +DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26) +DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27) +DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28) +DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29) +DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30) +DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31) +DECLARE_CSR(mucounteren, CSR_MUCOUNTEREN) +DECLARE_CSR(mscounteren, CSR_MSCOUNTEREN) +DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3) +DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4) +DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5) +DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6) +DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7) +DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8) +DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9) +DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10) +DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11) +DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12) +DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13) +DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14) +DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15) +DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16) +DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17) +DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18) +DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19) +DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20) +DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21) +DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22) +DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23) +DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24) +DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25) +DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26) +DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27) +DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28) +DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29) +DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30) +DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31) +DECLARE_CSR(mvendorid, CSR_MVENDORID) +DECLARE_CSR(marchid, CSR_MARCHID) +DECLARE_CSR(mimpid, CSR_MIMPID) +DECLARE_CSR(mhartid, CSR_MHARTID) +DECLARE_CSR(cycleh, CSR_CYCLEH) +DECLARE_CSR(timeh, CSR_TIMEH) +DECLARE_CSR(instreth, CSR_INSTRETH) +DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H) +DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H) +DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H) +DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H) +DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H) +DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H) +DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H) +DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H) +DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H) +DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H) +DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H) +DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H) +DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H) +DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H) +DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H) +DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H) +DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H) +DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H) +DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H) +DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H) +DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H) +DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H) +DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H) +DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H) +DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H) +DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H) +DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H) +DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H) +DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H) +DECLARE_CSR(mcycleh, CSR_MCYCLEH) +DECLARE_CSR(minstreth, CSR_MINSTRETH) +DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H) +DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H) +DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H) +DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H) +DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H) +DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H) +DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H) +DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H) +DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H) +DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H) +DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H) +DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H) +DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H) +DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H) +DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H) +DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H) +DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H) +DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H) +DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H) +DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H) +DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H) +DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H) +DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H) +DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H) +DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H) +DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H) +DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H) +DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H) +DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H) +#endif +#ifdef DECLARE_CAUSE +DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) +DECLARE_CAUSE("fault fetch", CAUSE_FAULT_FETCH) +DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION) +DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT) +DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD) +DECLARE_CAUSE("fault load", CAUSE_FAULT_LOAD) +DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE) +DECLARE_CAUSE("fault store", CAUSE_FAULT_STORE) +DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL) +DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL) +DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL) +DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL) +#endif diff --git a/bsp/gd32vf103v-eval/libraries/n22/drivers/sections.h b/bsp/gd32vf103v-eval/libraries/n22/drivers/sections.h new file mode 100644 index 0000000000000000000000000000000000000000..6e1f0518bc0bd01d125f3b334e9735bcf686dd4e --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/drivers/sections.h @@ -0,0 +1,17 @@ +// See LICENSE for license details. +#ifndef _SECTIONS_H +#define _SECTIONS_H + +extern unsigned char _rom[]; +extern unsigned char _rom_end[]; + +extern unsigned char _ram[]; +extern unsigned char _ram_end[]; + +extern unsigned char _ftext[]; +extern unsigned char _etext[]; +extern unsigned char _fbss[]; +extern unsigned char _ebss[]; +extern unsigned char _end[]; + +#endif /* _SECTIONS_H */ diff --git a/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103x4.lds b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103x4.lds new file mode 100644 index 0000000000000000000000000000000000000000..fc3d331ede23b761b0e1a2b769b13b8d89f3b4e1 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103x4.lds @@ -0,0 +1,175 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + /* Run in FLASH */ + flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 16k + ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 6k + + /* Run in RAM */ +/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 4k + ram (wxa!ri) : ORIGIN = 0x20001000, LENGTH = 2K +*/ +} + + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash + + .ilalign : + { + . = ALIGN(4); + PROVIDE( _ilm_lma = . ); + } >flash AT>flash + + .ialign : + { + PROVIDE( _ilm = . ); + } >flash AT>flash + + .text : + { + *(.rodata .rodata.*) + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + . = ALIGN(4); + + PROVIDE (__etext = .); + PROVIDE (_etext = .);/*0x80022c8*/ + PROVIDE (etext = .);/*0x80022c8*/ + PROVIDE( _eilm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + . = ALIGN(4); + PROVIDE( _eilm = . ); + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash + + + .data : + { + *(.rdata) + + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/ + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram + + . = ALIGN(8); + PROVIDE( _end = . ); /*0X2000,0340*/ + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103x6.lds b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103x6.lds new file mode 100644 index 0000000000000000000000000000000000000000..3cfe58ac5f164566e0eecb1534904f3a2b8c2aff --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103x6.lds @@ -0,0 +1,175 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + /* Run in FLASH */ + flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 32k + ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 10k + + /* Run in RAM */ +/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 7k + ram (wxa!ri) : ORIGIN = 0x20001C00, LENGTH = 3K +*/ +} + + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash + + .ilalign : + { + . = ALIGN(4); + PROVIDE( _ilm_lma = . ); + } >flash AT>flash + + .ialign : + { + PROVIDE( _ilm = . ); + } >flash AT>flash + + .text : + { + *(.rodata .rodata.*) + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + . = ALIGN(4); + + PROVIDE (__etext = .); + PROVIDE (_etext = .);/*0x80022c8*/ + PROVIDE (etext = .);/*0x80022c8*/ + PROVIDE( _eilm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + . = ALIGN(4); + PROVIDE( _eilm = . ); + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash + + + .data : + { + *(.rdata) + + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/ + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram + + . = ALIGN(8); + PROVIDE( _end = . ); /*0X2000,0340*/ + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103x8.lds b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103x8.lds new file mode 100644 index 0000000000000000000000000000000000000000..a10769dc86755e1168c43706b70fb71b58e292e6 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103x8.lds @@ -0,0 +1,175 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + /* Run in FLASH */ + flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 64k + ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 20k + + /* Run in RAM */ +/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 15k + ram (wxa!ri) : ORIGIN = 0x20003C00, LENGTH = 5K +*/ +} + + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash + + .ilalign : + { + . = ALIGN(4); + PROVIDE( _ilm_lma = . ); + } >flash AT>flash + + .ialign : + { + PROVIDE( _ilm = . ); + } >flash AT>flash + + .text : + { + *(.rodata .rodata.*) + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + . = ALIGN(4); + + PROVIDE (__etext = .); + PROVIDE (_etext = .);/*0x80022c8*/ + PROVIDE (etext = .);/*0x80022c8*/ + PROVIDE( _eilm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + . = ALIGN(4); + PROVIDE( _eilm = . ); + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash + + + .data : + { + *(.rdata) + + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/ + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram + + . = ALIGN(8); + PROVIDE( _end = . ); /*0X2000,0340*/ + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103xB.lds b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103xB.lds new file mode 100644 index 0000000000000000000000000000000000000000..b418fdfcb143c9bad11975195ace4a74df0fb2dc --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103xB.lds @@ -0,0 +1,199 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + /* Run in FLASH */ + flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 128k + ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 32K + + /* Run in RAM */ +/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 24k + ram (wxa!ri) : ORIGIN = 0x20006000, LENGTH = 8K +*/ +} + + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash + + .ilalign : + { + . = ALIGN(4); + PROVIDE( _ilm_lma = . ); + } >flash AT>flash + + .ialign : + { + PROVIDE( _ilm = . ); + } >flash AT>flash + + .text : + { + *(.rodata .rodata.*) + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.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); + + /* section information for modules */ + . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + } >flash AT>flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + . = ALIGN(4); + + PROVIDE (__etext = .); + PROVIDE (_etext = .);/*0x80022c8*/ + PROVIDE (etext = .);/*0x80022c8*/ + PROVIDE( _eilm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + . = ALIGN(4); + PROVIDE( _eilm = . ); + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash + + + .data : + { + *(.rdata) + + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/ + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram + + . = ALIGN(8); + PROVIDE( _end = . ); /*0X2000,0340*/ + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103xB_I2S.lds b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103xB_I2S.lds new file mode 100644 index 0000000000000000000000000000000000000000..f273c1930d6e212d1a7e61edfe452e33b9e0a7c9 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/GD32VF103xB_I2S.lds @@ -0,0 +1,182 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + /* Run in FLASH */ + flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 128k + ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 32K + + /* Run in RAM */ +/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 24k + ram (wxa!ri) : ORIGIN = 0x20006000, LENGTH = 8K +*/ +} + + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash + + .ilalign : + { + . = ALIGN(4); + PROVIDE( _ilm_lma = . ); + } >flash AT>flash + + .ialign : + { + PROVIDE( _ilm = . ); + } >flash AT>flash + + .PrgData ALIGN(0x08004000,4) : AT(ALIGN(0x08004000,4)) + { + KEEP(*(.PrgData)) + } + + .text : + { + *(.rodata .rodata.*) + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + *(.sdata2 .sdata2. *) + } >flash AT>flash + + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + . = ALIGN(4); + + PROVIDE (__etext = .); + PROVIDE (_etext = .);/*0x80022c8*/ + PROVIDE (etext = .);/*0x80022c8*/ + PROVIDE( _eilm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + . = ALIGN(4); + PROVIDE( _eilm = . ); + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash + + + .data : + { + *(.rdata) + + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/ + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram + + . = ALIGN(8); + PROVIDE( _end = . ); /*0X2000,0340*/ + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/entry.S b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/entry.S new file mode 100644 index 0000000000000000000000000000000000000000..f6b18aa71bdb58eed4989ed51ef3cc5e651363dd --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/entry.S @@ -0,0 +1,204 @@ +// See LICENSE for license details + +#ifndef ENTRY_S +#define ENTRY_S + +#include "riscv_encoding.h" +#include "riscv_bits.h" +#include "n22_eclic.h" +#include "n22_tmr.h" + +############################################### +############################################### +# Disable Interrupt +# +.macro DISABLE_MIE + csrc CSR_MSTATUS, MSTATUS_MIE +.endm + + +############################################### +############################################### +#Save caller registers +.macro SAVE_CONTEXT + + STORE x1, 0*REGBYTES(sp) + STORE x5, 1*REGBYTES(sp) + STORE x6, 2*REGBYTES(sp) + STORE x7, 3*REGBYTES(sp) + STORE x10, 4*REGBYTES(sp) + STORE x11, 5*REGBYTES(sp) + STORE x12, 6*REGBYTES(sp) + STORE x13, 7*REGBYTES(sp) + STORE x14, 8*REGBYTES(sp) + STORE x15, 9*REGBYTES(sp) + STORE x16, 10*REGBYTES(sp) + STORE x17, 11*REGBYTES(sp) + STORE x28, 12*REGBYTES(sp) + STORE x29, 13*REGBYTES(sp) + STORE x30, 14*REGBYTES(sp) + STORE x31, 15*REGBYTES(sp) +.endm + + +############################################### +############################################### +#restore caller registers +.macro RESTORE_CONTEXT + LOAD x1, 0*REGBYTES(sp) + LOAD x5, 1*REGBYTES(sp) + LOAD x6, 2*REGBYTES(sp) + LOAD x7, 3*REGBYTES(sp) + LOAD x10, 4*REGBYTES(sp) + LOAD x11, 5*REGBYTES(sp) + LOAD x12, 6*REGBYTES(sp) + LOAD x13, 7*REGBYTES(sp) + LOAD x14, 8*REGBYTES(sp) + LOAD x15, 9*REGBYTES(sp) + LOAD x16, 10*REGBYTES(sp) + LOAD x17, 11*REGBYTES(sp) + LOAD x28, 12*REGBYTES(sp) + LOAD x29, 13*REGBYTES(sp) + LOAD x30, 14*REGBYTES(sp) + LOAD x31, 15*REGBYTES(sp) + +.endm + +############################################### +############################################### +#restore caller registers +.macro RESTORE_CONTEXT_EXCPT_X5 + LOAD x1, 0*REGBYTES(sp) + LOAD x6, 2*REGBYTES(sp) + LOAD x7, 3*REGBYTES(sp) + LOAD x10, 4*REGBYTES(sp) + LOAD x11, 5*REGBYTES(sp) + LOAD x12, 6*REGBYTES(sp) + LOAD x13, 7*REGBYTES(sp) + LOAD x14, 8*REGBYTES(sp) + LOAD x15, 9*REGBYTES(sp) + LOAD x16, 10*REGBYTES(sp) + LOAD x17, 11*REGBYTES(sp) + LOAD x28, 12*REGBYTES(sp) + LOAD x29, 13*REGBYTES(sp) + LOAD x30, 14*REGBYTES(sp) + LOAD x31, 15*REGBYTES(sp) + +.endm + +############################################### +############################################### +#restore caller registers +.macro RESTORE_CONTEXT_ONLY_X5 + LOAD x5, 1*REGBYTES(sp) +.endm + +############################################### +############################################### +# Save the mepc and mstatus +# +.macro SAVE_MEPC_MSTATUS + csrr x5, CSR_MEPC + STORE x5, 16*REGBYTES(sp) + csrr x5, CSR_MSTATUS + STORE x5, 17*REGBYTES(sp) + csrr x5, CSR_MXSTATUS + STORE x5, 18*REGBYTES(sp) +.endm + +############################################### +############################################### +# Restore the mepc and mstatus +# +.macro RESTORE_MEPC_MSTATUS + LOAD x5, 16*REGBYTES(sp) + csrw CSR_MEPC, x5 + LOAD x5, 17*REGBYTES(sp) + csrw CSR_MSTATUS, x5 + LOAD x5, 18*REGBYTES(sp) + csrw CSR_MXSTATUS, x5 +.endm + +############################################### +############################################### +// trap entry point +// + .section .text.entry + .align 6 // In ECLIC mode, the trap entry must be 64bytes aligned + .global trap_entry +.weak trap_entry +trap_entry: + // Allocate the stack space + addi sp, sp, -19*REGBYTES + + // Save the caller saving registers (context) + SAVE_CONTEXT + // Save the MEPC/MStatus reg + SAVE_MEPC_MSTATUS + + // Set the function argument + csrr a0, mcause + mv a1, sp + // Call the function + call handle_trap + + // Restore the MEPC/MStatus reg + RESTORE_MEPC_MSTATUS + // Restore the caller saving registers (context) + RESTORE_CONTEXT + + // De-allocate the stack space + addi sp, sp, 19*REGBYTES + // Return to regular code + mret +############################################### +############################################### +// IRQ entry point +// + .section .text.irq + .align 2 + .global irq_entry +.weak irq_entry +irq_entry: // -------------> This label will be set to MTVT2 register + // Allocate the stack space + addi sp, sp, -19*REGBYTES + + SAVE_CONTEXT// Save 16 regs + + //------This special CSR read operation, which is actually use mcause as operand to directly store it to memory + csrrwi x0, CSR_PUSHMCAUSE, 16 + //------This special CSR read operation, which is actually use mepc as operand to directly store it to memory + csrrwi x0, CSR_PUSHMEPC, 17 + //------This special CSR read operation, which is actually use mxstatus as operand to directly store it to memory + csrrwi x0, CSR_PUSHMXSTATUS, 18 + +service_loop: + //------This special CSR read/write operation, which is actually Claim the ECLIC to find its pending highest + // ID, if the ID is not 0, then automatically enable the mstatus.MIE, and jump to its vector-entry-label, and + // update the link register + csrrw ra, CSR_MINTSEL_JAL, ra + + RESTORE_CONTEXT_EXCPT_X5 + + #---- Critical section with interrupts disabled ----------------------- + DISABLE_MIE # Disable interrupts + + LOAD x5, 18*REGBYTES(sp) + csrw CSR_MXSTATUS, x5 + LOAD x5, 17*REGBYTES(sp) + csrw CSR_MEPC, x5 + LOAD x5, 16*REGBYTES(sp) + csrw CSR_MCAUSE, x5 + + + RESTORE_CONTEXT_ONLY_X5 + + // De-allocate the stack space + addi sp, sp, 19*REGBYTES + // Return to regular code + mret + + + + +#endif diff --git a/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/handlers.c b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/handlers.c new file mode 100644 index 0000000000000000000000000000000000000000..10ff5a794958e2a2dc351a1a72d963c72179fb41 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/handlers.c @@ -0,0 +1,24 @@ +//See LICENSE for license details. +#include +#include +#include +#include "riscv_encoding.h" +#include "n22_func.h" +__attribute__((weak)) uintptr_t handle_nmi() { + write(1, "nmi\n", 5); + _exit(1); + return 0; +} + +__attribute__((weak)) uintptr_t handle_trap(uintptr_t mcause, uintptr_t sp) { + if (mcause == 0xFFF) { + handle_nmi(); + } + write(1, "trap\n", 5); + printf("In trap handler, the mcause is %d\n", mcause); + printf("In trap handler, the mepc is 0x%x\n", read_csr(mepc)); + printf("In trap handler, the mtval is 0x%x\n", read_csr(mbadaddr)); + _exit(mcause); + return 0; +} + diff --git a/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/init.c b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/init.c new file mode 100644 index 0000000000000000000000000000000000000000..ada05ba2c7b95039d87393fc975b4003ada12ca6 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/init.c @@ -0,0 +1,28 @@ +//See LICENSE for license details. +#include +#include +#include +#include +#include "riscv_encoding.h" +#include "n22_func.h" + +void _init() { + SystemInit(); + + //ECLIC init + eclic_init(ECLIC_NUM_INTERRUPTS); + eclic_mode_enable(); + set_csr(mstatus, MSTATUS_MIE); + + //printf("After ECLIC mode enabled, the mtvec value is %x \n\n\r", read_csr(mtvec)); + + // // It must be NOTED: + // // * In the RISC-V arch, if user mode and PMP supported, then by default if PMP is not configured + // // with valid entries, then user mode cannot access any memory, and cannot execute any instructions. + // // * So if switch to user-mode and still want to continue, then you must configure PMP first + //pmp_open_all_space(); + //switch_m2u_mode(); +} + +void _fini() { +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/start.S b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/start.S new file mode 100644 index 0000000000000000000000000000000000000000..953adf3139c625c1c62c527ab59270cfb7941e02 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/env_Eclipse/start.S @@ -0,0 +1,247 @@ +// See LICENSE for license details. + +// See LICENSE for license details. + +#include "riscv_encoding.h" + + .section .init + + .weak eclic_msip_handler + .weak eclic_mtip_handler + .weak eclic_bwei_handler + .weak eclic_pmovi_handler + .weak WWDGT_IRQHandler + .weak LVD_IRQHandler + .weak TAMPER_IRQHandler + .weak RTC_IRQHandler + .weak FMC_IRQHandler + .weak RCU_IRQHandler + .weak EXTI0_IRQHandler + .weak EXTI1_IRQHandler + .weak EXTI2_IRQHandler + .weak EXTI3_IRQHandler + .weak EXTI4_IRQHandler + .weak DMA0_Channel0_IRQHandler + .weak DMA0_Channel1_IRQHandler + .weak DMA0_Channel2_IRQHandler + .weak DMA0_Channel3_IRQHandler + .weak DMA0_Channel4_IRQHandler + .weak DMA0_Channel5_IRQHandler + .weak DMA0_Channel6_IRQHandler + .weak ADC0_1_IRQHandler + .weak CAN0_TX_IRQHandler + .weak CAN0_RX0_IRQHandler + .weak CAN0_RX1_IRQHandler + .weak CAN0_EWMC_IRQHandler + .weak EXTI5_9_IRQHandler + .weak TIMER0_BRK_IRQHandler + .weak TIMER0_UP_IRQHandler + .weak TIMER0_TRG_CMT_IRQHandler + .weak TIMER0_Channel_IRQHandler + .weak TIMER1_IRQHandler + .weak TIMER2_IRQHandler + .weak TIMER3_IRQHandler + .weak I2C0_EV_IRQHandler + .weak I2C0_ER_IRQHandler + .weak I2C1_EV_IRQHandler + .weak I2C1_ER_IRQHandler + .weak SPI0_IRQHandler + .weak SPI1_IRQHandler + .weak USART0_IRQHandler + .weak USART1_IRQHandler + .weak USART2_IRQHandler + .weak EXTI10_15_IRQHandler + .weak RTC_Alarm_IRQHandler + .weak USBFS_WKUP_IRQHandler + .weak EXMC_IRQHandler + .weak TIMER4_IRQHandler + .weak SPI2_IRQHandler + .weak UART3_IRQHandler + .weak UART4_IRQHandler + .weak TIMER5_IRQHandler + .weak TIMER6_IRQHandler + .weak DMA1_Channel0_IRQHandler + .weak DMA1_Channel1_IRQHandler + .weak DMA1_Channel2_IRQHandler + .weak DMA1_Channel3_IRQHandler + .weak DMA1_Channel4_IRQHandler + .weak CAN1_TX_IRQHandler + .weak CAN1_RX0_IRQHandler + .weak CAN1_RX1_IRQHandler + .weak CAN1_EWMC_IRQHandler + .weak USBFS_IRQHandler + + +vector_base: + j _start + .align 2 + .word 0 + .word 0 + .word eclic_msip_handler + .word 0 + .word 0 + .word 0 + .word eclic_mtip_handler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word eclic_bwei_handler + .word eclic_pmovi_handler + .word WWDGT_IRQHandler + .word LVD_IRQHandler + .word TAMPER_IRQHandler + .word RTC_IRQHandler + .word FMC_IRQHandler + .word RCU_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA0_Channel0_IRQHandler + .word DMA0_Channel1_IRQHandler + .word DMA0_Channel2_IRQHandler + .word DMA0_Channel3_IRQHandler + .word DMA0_Channel4_IRQHandler + .word DMA0_Channel5_IRQHandler + .word DMA0_Channel6_IRQHandler + .word ADC0_1_IRQHandler + .word CAN0_TX_IRQHandler + .word CAN0_RX0_IRQHandler + .word CAN0_RX1_IRQHandler + .word CAN0_EWMC_IRQHandler + .word EXTI5_9_IRQHandler + .word TIMER0_BRK_IRQHandler + .word TIMER0_UP_IRQHandler + .word TIMER0_TRG_CMT_IRQHandler + .word TIMER0_Channel_IRQHandler + .word TIMER1_IRQHandler + .word TIMER2_IRQHandler + .word TIMER3_IRQHandler + .word I2C0_EV_IRQHandler + .word I2C0_ER_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word SPI0_IRQHandler + .word SPI1_IRQHandler + .word USART0_IRQHandler + .word USART1_IRQHandler + .word USART2_IRQHandler + .word EXTI10_15_IRQHandler + .word RTC_Alarm_IRQHandler + .word USBFS_WKUP_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word EXMC_IRQHandler + .word 0 + .word TIMER4_IRQHandler + .word SPI2_IRQHandler + .word UART3_IRQHandler + .word UART4_IRQHandler + .word TIMER5_IRQHandler + .word TIMER6_IRQHandler + .word DMA1_Channel0_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word 0 + .word 0 + .word CAN1_TX_IRQHandler + .word CAN1_RX0_IRQHandler + .word CAN1_RX1_IRQHandler + .word CAN1_EWMC_IRQHandler + .word USBFS_IRQHandler + + .globl _start + .type _start,@function + +_start: + + /* Jump to logical address first to ensure correct operation of RAM region */ + la a0, _start + li a1, 1 + slli a1, a1, 29 + bleu a1, a0, _start0800 + srli a1, a1, 2 + bleu a1, a0, _start0800 + la a0, _start0800 + add a0, a0, a1 + jr a0 + +_start0800: + + /* Set the the NMI base to share with mtvec by setting CSR_MMISC_CTL */ + li t0, 0x200 + csrs CSR_MMISC_CTL, t0 + + /* Intial the mtvt*/ + la t0, vector_base + csrw CSR_MTVT, t0 + + /* Intial the mtvt2 and enable it*/ + la t0, irq_entry + csrw CSR_MIRQ_ENTRY, t0 + csrs CSR_MIRQ_ENTRY, 0x1 + + /* Intial the CSR MTVEC for the Trap ane NMI base addr*/ + la t0, trap_entry + csrw CSR_MTVEC, t0 + +#ifdef __riscv_flen + /* Enable FPU */ + li t0, MSTATUS_FS + csrs mstatus, t0 + csrw fcsr, x0 +#endif + +.option push +.option norelax + la gp, __global_pointer$ +.option pop + la sp, _sp + + /* Load data section */ + la a0, _data_lma + la a1, _data + la a2, _edata + bgeu a1, a2, 2f +1: + lw t0, (a0) + sw t0, (a1) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a1, a2, 1b +2: + /* Clear bss section */ + la a0, __bss_start + la a1, _end + bgeu a0, a1, 2f +1: + sw zero, (a0) + addi a0, a0, 4 + bltu a0, a1, 1b +2: + /* Call global constructors */ + la a0, __libc_fini_array + call atexit + call __libc_init_array + + + /* argc = argv = 0 */ + li a0, 0 + li a1, 0 + call entry + tail exit + +1: + j 1b diff --git a/bsp/gd32vf103v-eval/libraries/n22/stubs/_exit.c b/bsp/gd32vf103v-eval/libraries/n22/stubs/_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..8d49dc21f6dec1013c4d7514b24e04e046ed1aa4 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/stubs/_exit.c @@ -0,0 +1,17 @@ +/* See LICENSE of license details. */ + +#include + +#include "stub.h" + + +void _exit(int code) +{ + const char message[] = "\nProgram has exited with code:"; + + write(STDERR_FILENO, message, sizeof(message) - 1); +// write_hex(STDERR_FILENO, code); +// write(STDERR_FILENO, "\n", 1); + + for (;;); +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/stubs/close.c b/bsp/gd32vf103v-eval/libraries/n22/stubs/close.c new file mode 100644 index 0000000000000000000000000000000000000000..618cc6de96bf91136318dddc298ad12fc9ef7b48 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/stubs/close.c @@ -0,0 +1,8 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" + +int _close(int fd) { + return _stub(EBADF); +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/stubs/fstat.c b/bsp/gd32vf103v-eval/libraries/n22/stubs/fstat.c new file mode 100644 index 0000000000000000000000000000000000000000..c30d27cba66f4797c4cd69a5d88fedb3ec145da1 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/stubs/fstat.c @@ -0,0 +1,16 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include "stub.h" + +int _fstat(int fd, struct stat* st) +{ + if (isatty(fd)) { + st->st_mode = S_IFCHR; + return 0; + } + + return _stub(EBADF); +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/stubs/isatty.c b/bsp/gd32vf103v-eval/libraries/n22/stubs/isatty.c new file mode 100644 index 0000000000000000000000000000000000000000..8bb63e1e37df5c62c41e915d019b195bb470bcc2 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/stubs/isatty.c @@ -0,0 +1,10 @@ +/* See LICENSE of license details. */ + +#include + +int _isatty(int fd) { + if (fd == STDOUT_FILENO || fd == STDERR_FILENO) + return 1; + + return 0; +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/stubs/lseek.c b/bsp/gd32vf103v-eval/libraries/n22/stubs/lseek.c new file mode 100644 index 0000000000000000000000000000000000000000..c7be7a93c681105ae210663579a3b328df7b3583 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/stubs/lseek.c @@ -0,0 +1,13 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include "stub.h" + +off_t _lseek(int fd, off_t ptr, int dir) { + if (isatty(fd)) + return 0; + + return _stub(EBADF); +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/stubs/read.c b/bsp/gd32vf103v-eval/libraries/n22/stubs/read.c new file mode 100644 index 0000000000000000000000000000000000000000..54e15f6a30b15597831760fcd62a1c09643461f6 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/stubs/read.c @@ -0,0 +1,31 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include + +#include "stub.h" + +ssize_t _read(int fd, void* ptr, size_t len) +{ + // The below code was copied from freedom-e-sdk, but seems it is definitely wrong, so just comment it out + // Need to implement this function in the future, otherwise cannot use the C scanf function + //uint8_t * current = (uint8_t *)ptr; + //volatile uint32_t * uart_rx = (uint32_t *)(UART0_CTRL_ADDR + UART_REG_RXFIFO); + //volatile uint8_t * uart_rx_cnt = (uint8_t *)(UART0_CTRL_ADDR + UART_REG_RXCTRL + 2); + + //ssize_t result = 0; + + //if (isatty(fd)) { + // for (current = (uint8_t *)ptr; + // (current < ((uint8_t *)ptr) + len) && (*uart_rx_cnt > 0); + // current ++) { + // *current = *uart_rx; + // result++; + // } + // return result; + //} + + return _stub(EBADF); +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/stubs/sbrk.c b/bsp/gd32vf103v-eval/libraries/n22/stubs/sbrk.c new file mode 100644 index 0000000000000000000000000000000000000000..e86debdec6b0a1eb2172d55cd62dc5e0ecd556e9 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/stubs/sbrk.c @@ -0,0 +1,19 @@ +/* See LICENSE of license details. */ + +#include + +void *_sbrk(ptrdiff_t incr) { + extern char _end[]; + + static char *curbrk = _end; +#ifndef __ANDES__ + extern char _heap_end[]; + if ((curbrk + incr < _end) || (curbrk + incr > _heap_end)) +#else + if ((curbrk + incr < _end) ) +#endif + return NULL - 1; + + curbrk += incr; + return curbrk - incr; +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/stubs/stub.h b/bsp/gd32vf103v-eval/libraries/n22/stubs/stub.h new file mode 100644 index 0000000000000000000000000000000000000000..e075daeb8cba307caecb5cd4a613098adbf49633 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/stubs/stub.h @@ -0,0 +1,15 @@ +/* See LICENSE of license details. */ +#ifndef _NUCLEI_SYS_STUB_H +#define _NUCLEI_SYS_STUB_H + +#include +#include + +void write_hex(int fd, unsigned long int hex); + +static inline int _stub(int err) +{ + return -1; +} + +#endif /* _NUCLEI_SYS_STUB_H */ diff --git a/bsp/gd32vf103v-eval/libraries/n22/stubs/write.c b/bsp/gd32vf103v-eval/libraries/n22/stubs/write.c new file mode 100644 index 0000000000000000000000000000000000000000..699ba193f9e716344338bd8caace92183b53064a --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/stubs/write.c @@ -0,0 +1,45 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include +#include +#include + +#include "stub.h" +#include "gd32vf103.h" + +typedef unsigned int size_t; + +extern int _put_char(int ch) __attribute__((weak)); + +ssize_t _write(int fd, const void* ptr, size_t len) { + const uint8_t * current = (const uint8_t *) ptr; + +// if (isatty(fd)) + { + for (size_t jj = 0; jj < len; jj++) { + _put_char(current[jj]); + + if (current[jj] == '\n') { + _put_char('\r'); + } + } + return len; + } + + return _stub(EBADF); +} + +int puts(const char* string) { + return _write(0, (const void *) string, strlen(string)); +} + +int _put_char(int ch) { + usart_data_transmit(USART0, (uint8_t) ch); + while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET) { + } + + return ch; +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/stubs/write_hex.c b/bsp/gd32vf103v-eval/libraries/n22/stubs/write_hex.c new file mode 100644 index 0000000000000000000000000000000000000000..2f499b5ee55819e6c7f22870af021e5ab9bff659 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/stubs/write_hex.c @@ -0,0 +1,17 @@ +/* See LICENSE of license details. */ + +#include +#include + +void write_hex(int fd, unsigned long int hex) { + uint8_t ii; + uint8_t jj; + char towrite; + write(fd, "0x", 2); + for (ii = sizeof(unsigned long int) * 2; ii > 0; ii--) { + jj = ii - 1; + uint8_t digit = ((hex & (0xF << (jj * 4))) >> (jj * 4)); + towrite = digit < 0xA ? ('0' + digit) : ('A' + (digit - 0xA)); + write(fd, &towrite, 1); + } +} diff --git a/bsp/gd32vf103v-eval/libraries/n22/tools/openocd_upload.sh b/bsp/gd32vf103v-eval/libraries/n22/tools/openocd_upload.sh new file mode 100644 index 0000000000000000000000000000000000000000..3e987a7bf9ced87c460054a8052f61638ad7ed17 --- /dev/null +++ b/bsp/gd32vf103v-eval/libraries/n22/tools/openocd_upload.sh @@ -0,0 +1,5 @@ +#! /bin/bash -x + +work/build/openocd/prefix/bin/openocd -f ${2} \ + -c "flash protect 0 0 last off; program ${1} verify; resume 0x20000000; exit" \ + 2>&1 | tee openocd_upload.log diff --git a/bsp/gd32vf103v-eval/rtconfig.h b/bsp/gd32vf103v-eval/rtconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..178ccbfc1f0d1962214a116c594ebbb904e11fbf --- /dev/null +++ b/bsp/gd32vf103v-eval/rtconfig.h @@ -0,0 +1,171 @@ +#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_IDEL_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 +#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 0x40002 + +/* 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_SERIAL_RB_BUFSZ 64 + +/* 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 online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* peripheral libraries and drivers */ + +#define PKG_USING_AT24CXX +#define PKG_USING_AT24CXX_LATEST_VERSION + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + + +/* Privated Packages of RealThread */ + + +/* Network Utilities */ + + +/* Hardware Drivers Config */ + +#define SOC_STM32F429IG + +/* Onboard Peripheral Drivers */ + +#define BSP_USING_USART + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_UART +#define BSP_USING_UART0 + +/* Board extended module Drivers */ + + +#endif diff --git a/bsp/gd32vf103v-eval/rtconfig.py b/bsp/gd32vf103v-eval/rtconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..2d767412bbe1779108f1d0063714a7a54a00b161 --- /dev/null +++ b/bsp/gd32vf103v-eval/rtconfig.py @@ -0,0 +1,63 @@ +import os +ARCH = 'risc-v' +CPU = 'bumblebee' +# toolchains options +CROSS_TOOL = 'gcc' + +#------- toolchains path ------------------------------------------------------- +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'/opt/unknown-gcc/bin' +else: + print('Please make sure your toolchains is GNU GCC!') + exit(0) + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' +#BUILD = 'release' + +CORE = 'risc-v' +MAP_FILE = 'rtthread.map' +LINK_FILE = './libraries/n22/env_Eclipse/GD32VF103xB.lds' +TARGET_NAME = 'rtthread.bin' + +#------- GCC settings ---------------------------------------------------------- +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'riscv-none-embed-' + CC = PREFIX + 'gcc' + CXX= PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -march=rv32imac -mabi=ilp32 -DUSE_PLIC -DUSE_M_TIME -DNO_INIT -mcmodel=medany -msmall-data-limit=8 -L. -nostartfiles -lc ' + CFLAGS = DEVICE + CFLAGS += ' -save-temps=obj' + AFLAGS = '-c'+ DEVICE + ' -x assembler-with-cpp' + AFLAGS += ' -Iplatform -Ilibraries/n22/include -Ilibraries/n22/env_Eclipse' + LFLAGS = DEVICE + LFLAGS += ' -Wl,--gc-sections,-cref,-Map=' + MAP_FILE + LFLAGS += ' -T ' + LINK_FILE + LFLAGS += ' -Wl,-wrap=memset' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -g3' + AFLAGS += ' -g3' + else: + CFLAGS += ' -O2' + + POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n' + POST_ACTION += SIZE + ' $TARGET\n' diff --git a/libcpu/risc-v/bumblebee/SConscript b/libcpu/risc-v/bumblebee/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..b0ae20ba0298e00e05eba2ddc73df9424d22ec79 --- /dev/null +++ b/libcpu/risc-v/bumblebee/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/risc-v/bumblebee/interrupt_gcc.S b/libcpu/risc-v/bumblebee/interrupt_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..5a86e7d748d9a4c4f7c3b922cb796f81da044538 --- /dev/null +++ b/libcpu/risc-v/bumblebee/interrupt_gcc.S @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +#include "cpuport.h" + + .section .text.entry + .align 6 /* In ECLIC mode, the trap entry must be 64bytes aligned */ + .global irq_entry +irq_entry: + + /* save all from thread context */ + addi sp, sp, -32 * REGBYTES + + STORE x1, 1 * REGBYTES(sp) + li t0, 0x80 + STORE t0, 2 * REGBYTES(sp) + + STORE x4, 4 * REGBYTES(sp) + STORE x5, 5 * REGBYTES(sp) + STORE x6, 6 * REGBYTES(sp) + STORE x7, 7 * REGBYTES(sp) + STORE x8, 8 * REGBYTES(sp) + STORE x9, 9 * REGBYTES(sp) + STORE x10, 10 * REGBYTES(sp) + STORE x11, 11 * REGBYTES(sp) + STORE x12, 12 * REGBYTES(sp) + STORE x13, 13 * REGBYTES(sp) + STORE x14, 14 * REGBYTES(sp) + STORE x15, 15 * REGBYTES(sp) + STORE x16, 16 * REGBYTES(sp) + STORE x17, 17 * REGBYTES(sp) + STORE x18, 18 * REGBYTES(sp) + STORE x19, 19 * REGBYTES(sp) + STORE x20, 20 * REGBYTES(sp) + STORE x21, 21 * REGBYTES(sp) + STORE x22, 22 * REGBYTES(sp) + STORE x23, 23 * REGBYTES(sp) + STORE x24, 24 * REGBYTES(sp) + STORE x25, 25 * REGBYTES(sp) + STORE x26, 26 * REGBYTES(sp) + STORE x27, 27 * REGBYTES(sp) + STORE x28, 28 * REGBYTES(sp) + STORE x29, 29 * REGBYTES(sp) + STORE x30, 30 * REGBYTES(sp) + STORE x31, 31 * REGBYTES(sp) + + move s0, sp + + /* switch to interrupt stack */ + la sp, _sp + + /* interrupt handle */ + call rt_interrupt_enter + csrr a0, mcause + csrr a1, mepc + mv a2, sp + csrrw ra, 0x07ED, ra + call rt_interrupt_leave + + /* switch to from thread stack */ + move sp, s0 + + /* need to switch new thread */ + la s0, rt_thread_switch_interrupt_flag + lw s2, 0(s0) + beqz s2, spurious_interrupt + /* clear switch interrupt flag */ + sw zero, 0(s0) + + csrr a0, mepc + STORE a0, 0 * REGBYTES(sp) + + la s0, rt_interrupt_from_thread + LOAD s1, 0(s0) + STORE sp, 0(s1) + + la s0, rt_interrupt_to_thread + LOAD s1, 0(s0) + LOAD sp, 0(s1) + + LOAD a0, 0 * REGBYTES(sp) + csrw mepc, a0 + +spurious_interrupt: + LOAD x1, 1 * REGBYTES(sp) + + /* Remain in M-mode after mret */ + li t0, 0x00001800 + csrs mstatus, t0 + LOAD t0, 2 * REGBYTES(sp) + csrs mstatus, t0 + + LOAD x4, 4 * REGBYTES(sp) + LOAD x5, 5 * REGBYTES(sp) + LOAD x6, 6 * REGBYTES(sp) + LOAD x7, 7 * REGBYTES(sp) + LOAD x8, 8 * REGBYTES(sp) + LOAD x9, 9 * REGBYTES(sp) + LOAD x10, 10 * REGBYTES(sp) + LOAD x11, 11 * REGBYTES(sp) + LOAD x12, 12 * REGBYTES(sp) + LOAD x13, 13 * REGBYTES(sp) + LOAD x14, 14 * REGBYTES(sp) + LOAD x15, 15 * REGBYTES(sp) + LOAD x16, 16 * REGBYTES(sp) + LOAD x17, 17 * REGBYTES(sp) + LOAD x18, 18 * REGBYTES(sp) + LOAD x19, 19 * REGBYTES(sp) + LOAD x20, 20 * REGBYTES(sp) + LOAD x21, 21 * REGBYTES(sp) + LOAD x22, 22 * REGBYTES(sp) + LOAD x23, 23 * REGBYTES(sp) + LOAD x24, 24 * REGBYTES(sp) + LOAD x25, 25 * REGBYTES(sp) + LOAD x26, 26 * REGBYTES(sp) + LOAD x27, 27 * REGBYTES(sp) + LOAD x28, 28 * REGBYTES(sp) + LOAD x29, 29 * REGBYTES(sp) + LOAD x30, 30 * REGBYTES(sp) + LOAD x31, 31 * REGBYTES(sp) + + addi sp, sp, 32 * REGBYTES + mret