bsp: Add initial commit of nuclei rvstar board bsp

Signed-off-by: Huaqi Fang <578567190@qq.com>
This commit is contained in:
Huaqi Fang
2020-04-03 10:04:42 +08:00
parent 0f57faa591
commit 3451466e9d
170 changed files with 62399 additions and 1 deletions
+474
View File
@@ -0,0 +1,474 @@
# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)
#
# RT-Thread Kernel
#
CONFIG_RT_NAME_MAX=8
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMP is not set
CONFIG_RT_ALIGN_SIZE=4
# CONFIG_RT_THREAD_PRIORITY_8 is not set
CONFIG_RT_THREAD_PRIORITY_32=y
# CONFIG_RT_THREAD_PRIORITY_256 is not set
CONFIG_RT_THREAD_PRIORITY_MAX=32
CONFIG_RT_TICK_PER_SECOND=100
CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_USING_HOOK=y
CONFIG_RT_USING_IDLE_HOOK=y
CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
CONFIG_IDLE_THREAD_STACK_SIZE=256
CONFIG_RT_USING_TIMER_SOFT=y
CONFIG_RT_TIMER_THREAD_PRIO=4
CONFIG_RT_TIMER_THREAD_STACK_SIZE=512
CONFIG_RT_DEBUG=y
# CONFIG_RT_DEBUG_COLOR is not set
# CONFIG_RT_DEBUG_INIT_CONFIG is not set
# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
# CONFIG_RT_DEBUG_IPC_CONFIG is not set
# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
# CONFIG_RT_DEBUG_MEM_CONFIG is not set
# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
# CONFIG_RT_DEBUG_MODULE_CONFIG is not set
#
# Inter-Thread communication
#
CONFIG_RT_USING_SEMAPHORE=y
CONFIG_RT_USING_MUTEX=y
CONFIG_RT_USING_EVENT=y
CONFIG_RT_USING_MAILBOX=y
CONFIG_RT_USING_MESSAGEQUEUE=y
# CONFIG_RT_USING_SIGNALS is not set
# end of Inter-Thread communication
#
# Memory Management
#
CONFIG_RT_USING_MEMPOOL=y
# CONFIG_RT_USING_MEMHEAP is not set
# CONFIG_RT_USING_NOHEAP is not set
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
# CONFIG_RT_USING_MEMTRACE is not set
CONFIG_RT_USING_HEAP=y
# end of Memory Management
#
# Kernel Device Object
#
CONFIG_RT_USING_DEVICE=y
# CONFIG_RT_USING_DEVICE_OPS is not set
# CONFIG_RT_USING_INTERRUPT_INFO is not set
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
CONFIG_RT_CONSOLE_DEVICE_NAME="uart4"
# end of Kernel Device Object
CONFIG_RT_VER_NUM=0x40003
# end of RT-Thread Kernel
#
# RT-Thread Components
#
CONFIG_RT_USING_COMPONENTS_INIT=y
CONFIG_RT_USING_USER_MAIN=y
CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
CONFIG_RT_MAIN_THREAD_PRIORITY=10
#
# C++ features
#
# CONFIG_RT_USING_CPLUSPLUS is not set
# end of C++ features
#
# Command shell
#
CONFIG_RT_USING_FINSH=y
CONFIG_FINSH_THREAD_NAME="tshell"
CONFIG_FINSH_USING_HISTORY=y
CONFIG_FINSH_HISTORY_LINES=5
CONFIG_FINSH_USING_SYMTAB=y
CONFIG_FINSH_USING_DESCRIPTION=y
# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
CONFIG_FINSH_THREAD_PRIORITY=20
CONFIG_FINSH_THREAD_STACK_SIZE=4096
CONFIG_FINSH_CMD_SIZE=80
# CONFIG_FINSH_USING_AUTH is not set
CONFIG_FINSH_USING_MSH=y
CONFIG_FINSH_USING_MSH_DEFAULT=y
# CONFIG_FINSH_USING_MSH_ONLY is not set
CONFIG_FINSH_ARG_MAX=10
# end of Command shell
#
# Device virtual file system
#
CONFIG_RT_USING_DFS=y
CONFIG_DFS_USING_WORKDIR=y
CONFIG_DFS_FILESYSTEMS_MAX=2
CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
CONFIG_DFS_FD_MAX=16
# CONFIG_RT_USING_DFS_MNTTABLE is not set
# CONFIG_RT_USING_DFS_ELMFAT is not set
CONFIG_RT_USING_DFS_DEVFS=y
# CONFIG_RT_USING_DFS_ROMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
# CONFIG_RT_USING_DFS_UFFS is not set
# CONFIG_RT_USING_DFS_JFFS2 is not set
# end of Device virtual file system
#
# Device Drivers
#
CONFIG_RT_USING_DEVICE_IPC=y
CONFIG_RT_PIPE_BUFSZ=512
# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
CONFIG_RT_USING_SERIAL=y
# CONFIG_RT_SERIAL_USING_DMA is not set
CONFIG_RT_SERIAL_RB_BUFSZ=64
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
# CONFIG_RT_USING_PIN is not set
# CONFIG_RT_USING_ADC is not set
# CONFIG_RT_USING_PWM is not set
# CONFIG_RT_USING_MTD_NOR is not set
# CONFIG_RT_USING_MTD_NAND is not set
# CONFIG_RT_USING_PM is not set
# CONFIG_RT_USING_RTC is not set
# CONFIG_RT_USING_SDIO is not set
# CONFIG_RT_USING_SPI is not set
# CONFIG_RT_USING_WDT is not set
# CONFIG_RT_USING_AUDIO is not set
# CONFIG_RT_USING_SENSOR is not set
# CONFIG_RT_USING_TOUCH is not set
# CONFIG_RT_USING_HWCRYPTO is not set
# CONFIG_RT_USING_PULSE_ENCODER is not set
# CONFIG_RT_USING_INPUT_CAPTURE is not set
# CONFIG_RT_USING_WIFI is not set
#
# Using USB
#
# CONFIG_RT_USING_USB_HOST is not set
# CONFIG_RT_USING_USB_DEVICE is not set
# end of Using USB
# end of Device Drivers
#
# POSIX layer and C standard library
#
CONFIG_RT_USING_LIBC=y
# CONFIG_RT_USING_PTHREADS is not set
CONFIG_RT_USING_POSIX=y
# CONFIG_RT_USING_POSIX_MMAP is not set
# CONFIG_RT_USING_POSIX_TERMIOS is not set
# CONFIG_RT_USING_POSIX_AIO is not set
# CONFIG_RT_USING_MODULE is not set
# end of POSIX layer and C standard library
#
# Network
#
#
# Socket abstraction layer
#
# CONFIG_RT_USING_SAL is not set
# end of Socket abstraction layer
#
# Network interface device
#
# CONFIG_RT_USING_NETDEV is not set
# end of Network interface device
#
# light weight TCP/IP stack
#
# CONFIG_RT_USING_LWIP is not set
# end of light weight TCP/IP stack
#
# AT commands
#
# CONFIG_RT_USING_AT is not set
# end of AT commands
# end of Network
#
# VBUS(Virtual Software BUS)
#
# CONFIG_RT_USING_VBUS is not set
# end of VBUS(Virtual Software BUS)
#
# Utilities
#
# CONFIG_RT_USING_RYM is not set
# CONFIG_RT_USING_ULOG is not set
# CONFIG_RT_USING_UTEST is not set
# end of Utilities
# end of RT-Thread Components
#
# RT-Thread online packages
#
#
# IoT - internet of things
#
# CONFIG_PKG_USING_PAHOMQTT is not set
# CONFIG_PKG_USING_WEBCLIENT is not set
# CONFIG_PKG_USING_WEBNET is not set
# CONFIG_PKG_USING_MONGOOSE is not set
# CONFIG_PKG_USING_MYMQTT is not set
# CONFIG_PKG_USING_KAWAII_MQTT is not set
# CONFIG_PKG_USING_WEBTERMINAL is not set
# CONFIG_PKG_USING_CJSON is not set
# CONFIG_PKG_USING_JSMN is not set
# CONFIG_PKG_USING_LIBMODBUS is not set
# CONFIG_PKG_USING_FREEMODBUS is not set
# CONFIG_PKG_USING_LJSON is not set
# CONFIG_PKG_USING_EZXML is not set
# CONFIG_PKG_USING_NANOPB is not set
#
# Wi-Fi
#
#
# Marvell WiFi
#
# CONFIG_PKG_USING_WLANMARVELL is not set
# end of Marvell WiFi
#
# Wiced WiFi
#
# CONFIG_PKG_USING_WLAN_WICED is not set
# end of Wiced WiFi
# CONFIG_PKG_USING_RW007 is not set
# end of Wi-Fi
# CONFIG_PKG_USING_COAP is not set
# CONFIG_PKG_USING_NOPOLL is not set
# CONFIG_PKG_USING_NETUTILS is not set
# CONFIG_PKG_USING_PPP_DEVICE is not set
# CONFIG_PKG_USING_AT_DEVICE is not set
# CONFIG_PKG_USING_ATSRV_SOCKET is not set
# CONFIG_PKG_USING_WIZNET is not set
#
# IoT Cloud
#
# CONFIG_PKG_USING_ONENET is not set
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
# CONFIG_PKG_USING_ALI_IOTKIT is not set
# CONFIG_PKG_USING_AZURE is not set
# CONFIG_PKG_USING_TENCENT_IOTHUB is not set
# CONFIG_PKG_USING_JIOT-C-SDK is not set
# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
# CONFIG_PKG_USING_JOYLINK is not set
# end of IoT Cloud
# CONFIG_PKG_USING_NIMBLE is not set
# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
# CONFIG_PKG_USING_IPMSG is not set
# CONFIG_PKG_USING_LSSDP is not set
# CONFIG_PKG_USING_AIRKISS_OPEN is not set
# CONFIG_PKG_USING_LIBRWS is not set
# CONFIG_PKG_USING_TCPSERVER is not set
# CONFIG_PKG_USING_PROTOBUF_C is not set
# CONFIG_PKG_USING_ONNX_PARSER is not set
# CONFIG_PKG_USING_ONNX_BACKEND is not set
# CONFIG_PKG_USING_DLT645 is not set
# CONFIG_PKG_USING_QXWZ is not set
# CONFIG_PKG_USING_SMTP_CLIENT is not set
# CONFIG_PKG_USING_ABUP_FOTA is not set
# CONFIG_PKG_USING_LIBCURL2RTT is not set
# CONFIG_PKG_USING_CAPNP is not set
# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
# CONFIG_PKG_USING_AGILE_TELNET is not set
# end of IoT - internet of things
#
# security packages
#
# CONFIG_PKG_USING_MBEDTLS is not set
# CONFIG_PKG_USING_libsodium is not set
# CONFIG_PKG_USING_TINYCRYPT is not set
# CONFIG_PKG_USING_TFM is not set
# end of security packages
#
# language packages
#
# CONFIG_PKG_USING_LUA is not set
# CONFIG_PKG_USING_JERRYSCRIPT is not set
# CONFIG_PKG_USING_MICROPYTHON is not set
# end of language packages
#
# multimedia packages
#
# CONFIG_PKG_USING_OPENMV is not set
# CONFIG_PKG_USING_MUPDF is not set
# CONFIG_PKG_USING_STEMWIN is not set
# CONFIG_PKG_USING_WAVPLAYER is not set
# CONFIG_PKG_USING_TJPGD is not set
# end of multimedia packages
#
# tools packages
#
# CONFIG_PKG_USING_CMBACKTRACE is not set
# CONFIG_PKG_USING_EASYFLASH is not set
# CONFIG_PKG_USING_EASYLOGGER is not set
# CONFIG_PKG_USING_SYSTEMVIEW is not set
# CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_QRCODE is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
# CONFIG_PKG_USING_ADBD is not set
# CONFIG_PKG_USING_COREMARK is not set
# CONFIG_PKG_USING_DHRYSTONE is not set
# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
# CONFIG_PKG_USING_BS8116A is not set
# end of tools packages
#
# system packages
#
# CONFIG_PKG_USING_GUIENGINE is not set
# CONFIG_PKG_USING_CAIRO is not set
# CONFIG_PKG_USING_PIXMAN is not set
# CONFIG_PKG_USING_LWEXT4 is not set
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_FAL is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
# CONFIG_PKG_USING_CMSIS is not set
# CONFIG_PKG_USING_DFS_YAFFS is not set
# CONFIG_PKG_USING_LITTLEFS is not set
# CONFIG_PKG_USING_THREAD_POOL is not set
# CONFIG_PKG_USING_ROBOTS is not set
# CONFIG_PKG_USING_EV is not set
# CONFIG_PKG_USING_SYSWATCH is not set
# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
# CONFIG_PKG_USING_PLCCORE is not set
# end of system packages
#
# peripheral libraries and drivers
#
# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_SHT3X is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ICM20608 is not set
# CONFIG_PKG_USING_U8G2 is not set
# CONFIG_PKG_USING_BUTTON is not set
# CONFIG_PKG_USING_PCF8574 is not set
# CONFIG_PKG_USING_SX12XX is not set
# CONFIG_PKG_USING_SIGNAL_LED is not set
# CONFIG_PKG_USING_LEDBLINK is not set
# CONFIG_PKG_USING_LITTLED is not set
# CONFIG_PKG_USING_LKDGUI is not set
# CONFIG_PKG_USING_WM_LIBRARIES is not set
# CONFIG_PKG_USING_KENDRYTE_SDK is not set
# CONFIG_PKG_USING_INFRARED is not set
# CONFIG_PKG_USING_ROSSERIAL is not set
# CONFIG_PKG_USING_AGILE_BUTTON is not set
# CONFIG_PKG_USING_AGILE_LED is not set
# CONFIG_PKG_USING_AT24CXX is not set
# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_PCA9685 is not set
# CONFIG_PKG_USING_I2C_TOOLS is not set
# CONFIG_PKG_USING_NRF24L01 is not set
# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
# CONFIG_PKG_USING_MAX17048 is not set
# CONFIG_PKG_USING_RPLIDAR is not set
# CONFIG_PKG_USING_AS608 is not set
# CONFIG_PKG_USING_RC522 is not set
# CONFIG_PKG_USING_EMBARC_BSP is not set
# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
# CONFIG_PKG_USING_MAX7219 is not set
# CONFIG_PKG_USING_BEEP is not set
# CONFIG_PKG_USING_EASYBLINK is not set
# end of peripheral libraries and drivers
#
# miscellaneous packages
#
# CONFIG_PKG_USING_LIBCSV is not set
# CONFIG_PKG_USING_OPTPARSE is not set
# CONFIG_PKG_USING_FASTLZ is not set
# CONFIG_PKG_USING_MINILZO is not set
# CONFIG_PKG_USING_QUICKLZ is not set
# CONFIG_PKG_USING_MULTIBUTTON is not set
# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
# CONFIG_PKG_USING_CANFESTIVAL is not set
# CONFIG_PKG_USING_ZLIB is not set
# CONFIG_PKG_USING_DSTR is not set
# CONFIG_PKG_USING_TINYFRAME is not set
# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
# CONFIG_PKG_USING_DIGITALCTRL is not set
# CONFIG_PKG_USING_UPACKER is not set
# CONFIG_PKG_USING_UPARAM is not set
#
# samples: kernel and components samples
#
# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
# end of samples: kernel and components samples
# CONFIG_PKG_USING_HELLO is not set
# CONFIG_PKG_USING_VI is not set
# CONFIG_PKG_USING_NNOM is not set
# CONFIG_PKG_USING_LIBANN is not set
# CONFIG_PKG_USING_ELAPACK is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
# CONFIG_PKG_USING_VT100 is not set
# CONFIG_PKG_USING_ULAPACK is not set
# CONFIG_PKG_USING_UKAL is not set
# end of miscellaneous packages
# end of RT-Thread online packages
#
# Hardware Drivers Config
#
CONFIG_SOC_GD32VF103V=y
#
# Onboard Peripheral Drivers
#
CONFIG_BSP_USING_USART=y
# end of Onboard Peripheral Drivers
#
# On-chip Peripheral Drivers
#
CONFIG_BSP_USING_UART=y
CONFIG_BSP_USING_UART4=y
# end of On-chip Peripheral Drivers
#
# Board extended module Drivers
#
# end of Hardware Drivers Config
CONFIG_SOC_GD32VF103=y
+26
View File
@@ -0,0 +1,26 @@
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"
config SOC_GD32VF103
bool
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y
+119
View File
@@ -0,0 +1,119 @@
# GD32VF103-RVSTAR #
## 简介
gd32vf103v-rvstar 是由芯来科技公司推出的基于采用芯来科技RISC-V架构处理器芯片的GD32VF103的开发板。
### 板载资源:
| 硬件 | 描述 |
| --- | --- |
| 内核 | nuclei n205 |
| 架构 | 32-bit RV32IMAC |
| 主频 | 108 MHz |
## 编译说明
### 导入工程
打开 Eclipse 选择工作空间
![指定工作空间](figures/open_eclipse.png)
打开 Eclipse 后需要导入 RT-Thread 工程
![导入工程](figures/file.png)
选择以存在的工程,并指定工程路径
![选择存在工程](figures/exist.png)
指定工程路径
![指定工程路径](figures/finish_port.png)
### 添加环境变量
设置 Build Tools Path
![build_path](figures/build_path.png)
点击 MCU 列表中的 Build Tools Path 选项,为其选择 SDK 文件包中提供的对应工具
设置 OpenOCD Path
![open_ocd](figures/open_ocd.png)
点击 MCU 列表中的 OpenOCD Path 选项,为其选择 SDK 文件包中提供的对应工具。
设置 RISC-V Toolchains Path
![risc-v](figures/risc-v-tool.png)
点击 MCU 列表中的 RISC-V Toolchains Paths 选项,为其选择 SDK 文件包中提供的对应工具。
按照以上步骤设置好路径点击编译即可编译工程
![build](figures/build_project.png)
## 烧写及执行
### 替换驱动
1. 执行 JLink_Windows_V622c.exe (可以是任意版本)安装 JLink 驱动程序。
2. 执行 Zadig.exe,点击 Options->List All Devices。
3. 在下图 1 处选择 J-Link,2 处选择 WinUSB 之后点击 3 处 Replace Driver 进行驱动替换。
![zadig](figures/zadig.png)
安装完成之后会弹出如下窗口:
![close](figures/close.png)
### 配置 GDB 调试
在菜单栏中,点击 Run->Debug Configurations,进入 Debug 配置界面,如下图所示:
![open_debug](figures/open_debug.png)
这里使用 OpenOCD 作为 GDB Server,使用GCC工具链中的 GDB 工具作为 GDB Client。双击 GDB OpenOCD Debugging,新建一套 OpenOCD 的配置选项。
Main 选项卡
Main 选项卡配置界面
![main_select](figures/main_select.png)
选择当前工程 GD32VF103,并且选择当前型号的可执行文件,例如:GD32VF103xB\GD32VF103xB.elf。
Debugger 选项卡
Debugger 选项卡配置界面
![debug_select](figures/debug_select.png)
在 Debugger 选项卡中,确认红圈中的配置正确。
其中,“Config options” 是为 OpenOCD 选择配置文件,需要根据当前使用的下载器选择不同的 cfg 文件。
上述配置内容配置好后,点击应用调试。
### 运行结果
下载程序之后,连接串口(115200-N-8-1),可以看到 RT-Thread 的输出信息:
```
\ | /
- RT - Thread Operating System
/ | \ 4.0.2 build Jul 24 2019
2006 - 2019 Copyright by rt-thread team
msh >
```
## 驱动支持情况
| 驱动 | 支持情况 | 备注 |
| ------ | ---- | :------: |
| USART | 支持 | UART0_TX/RXGPIO 9/10 |
## 5. 联系人信息
维护人:
- [fanghuaqi](https://github.com/fanghuaqi)
+17
View File
@@ -0,0 +1,17 @@
# for module compiling
import os
Import('RTT_ROOT')
cwd = str(Dir('#'))
objs = []
list = os.listdir(cwd)
ASFLAGS = ' -I' + cwd
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')
+72
View File
@@ -0,0 +1,72 @@
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
AddOption('--run',
dest = 'run',
type='string',
nargs=1,
action = 'store',
default = "",
help = 'Upload or debug application using openocd')
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
env['ASCOM'] = env['ASPPCOM']
Export('RTT_ROOT')
Export('rtconfig')
GDB = rtconfig.GDB
nuclei_sdk_root = rtconfig.NUCLEI_SDK_ROOT
openocd_cfg = rtconfig.OPENOCD_CFG.replace('\\', '/')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT)
# include libraries
objs.extend(SConscript(os.path.join(nuclei_sdk_root, 'SConscript')))
# make a building
DoBuilding(TARGET, objs)
# Run upload or debug if --run=upload or --upload=debug
run_target = GetOption('run')
SUPPORT_RUN_TARGETS = ["upload", "debug"]
if run_target in SUPPORT_RUN_TARGETS:
if os.path.isfile(TARGET):
if run_target == "upload":
upload_cmd = '{} {} -ex "set remotetimeout 240" \
-ex "target remote | openocd --pipe -f {}" \
--batch -ex "monitor halt" -ex "monitor flash protect 0 0 last off" -ex "load" \
-ex "monitor resume" -ex "monitor shutdown" -ex "quit"'.format(GDB, TARGET, openocd_cfg)
print("Upload application {} using openocd and gdb".format(TARGET))
print(upload_cmd)
os.system(upload_cmd)
elif run_target == "debug":
debug_cmd = '{} {} -ex "set remotetimeout 240" \
-ex "target remote | openocd --pipe -f {}"'.format(GDB, TARGET, openocd_cfg)
print("Debug application {} using openocd and gdb".format(TARGET))
print(debug_cmd)
os.system(debug_cmd)
else:
print(TARGET + ' not exist, please run scons first!!')
exit(0)
@@ -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')
@@ -0,0 +1,66 @@
/*
* 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 <rtthread.h>
#include <rtdevice.h>
#define THREAD_PRIORITY 2
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
#define THREAD_NUM 20
/* Align stack when using static thread */
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t thread_stack[THREAD_NUM][THREAD_STACK_SIZE];
static struct rt_thread tid[THREAD_NUM];
/* Thread entry function */
static void thread_entry(void *parameter)
{
rt_uint32_t count = 0;
while (1) {
rt_kprintf("thread %d count: %d\n", (rt_uint32_t)parameter, count++);
rt_thread_mdelay(500);
}
}
/* Thread demo */
int create_thread_demo(void)
{
int i;
for (i = 0; i < THREAD_NUM; i ++) {
/* Create static threads */
rt_thread_init(&tid[i], "thread", thread_entry, (void *)i, thread_stack[i],
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
}
/* Startup threads */
for (i = 0; i < THREAD_NUM; i ++) {
rt_thread_startup(&tid[i]);
}
return 0;
}
int main(void)
{
rt_uint32_t count = 0;
create_thread_demo();
while (1) {
rt_kprintf("Main thread count: %d\n", count++);
rt_thread_mdelay(1000);
}
}
/******************** end of file *******************/
@@ -0,0 +1,34 @@
menu "Hardware Drivers Config"
config SOC_GD32VF103V
bool
select SOC_SERIES_GD32VF103V
default y
menu "Onboard Peripheral Drivers"
config BSP_USING_USART
bool "Enable USART (uart4)"
select BSP_USING_UART
select BSP_USING_UART4
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_UART4
bool "Enable UART4"
default y
endif
endmenu
menu "Board extended module Drivers"
endmenu
endmenu
@@ -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')
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-02 Huaqi Fang first version
*
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#ifdef RT_USING_SERIAL
#include <drv_usart.h>
#endif
extern void *_end;
extern void *_heap_end;
#define HEAP_BEGIN &_end
#define HEAP_END &_heap_end
extern void _init(void);
extern void vPortSetupTimerInterrupt(void);
void rt_hw_board_init(void)
{
/* OS Tick Configuration */
vPortSetupTimerInterrupt();
#ifdef RT_USING_HEAP
rt_system_heap_init((void *) HEAP_BEGIN, (void *) HEAP_END);
#endif
_init(); // __libc_init_array is not used
/* 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 *******************/
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-02 Huaqi Fang first version
*
*/
#ifndef __BOARD__
#define __BOARD__
#include "nuclei_sdk_hal.h"
void rt_hw_board_init(void);
#endif /* __BOARD__ */
/******************** end of file *******************/
@@ -0,0 +1,19 @@
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Split('''
drv_usart.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')
@@ -0,0 +1,251 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-07-23 tyustli first version
* 2020-04-02 fanghuaqi Modified for Nuclei
*/
#include <drv_usart.h>
#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
enum {
#ifdef BSP_USING_UART0
GDUSART0_INDEX,
#endif
#ifdef BSP_USING_UART4
GDUART4_INDEX,
#endif
};
static struct gd32_uart_config uart_config[] = {
#ifdef BSP_USING_UART0
{ "uart0",
USART0,
USART0_IRQn, },
#endif
#ifdef BSP_USING_UART4
{ "uart4",
UART4,
UART4_IRQn, },
#endif
};
static struct gd32_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
static rt_err_t gd32_configure(struct rt_serial_device *serial,
struct serial_configure *cfg) {
struct gd32_uart *usart_obj;
struct gd32_uart_config *usart;
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
usart_obj = (struct gd32_uart *) serial->parent.user_data;
usart = usart_obj->config;
RT_ASSERT(usart != RT_NULL);
usart_deinit(usart->uart_base);
usart_baudrate_set(usart->uart_base, cfg->baud_rate);
switch (cfg->data_bits) {
case DATA_BITS_8:
usart_word_length_set(usart->uart_base, USART_WL_8BIT);
break;
case DATA_BITS_9:
usart_word_length_set(usart->uart_base, USART_WL_9BIT);
break;
default:
usart_word_length_set(usart->uart_base, USART_WL_8BIT);
break;
}
switch (cfg->stop_bits) {
case STOP_BITS_1:
usart_stop_bit_set(usart->uart_base, USART_STB_1BIT);
break;
case STOP_BITS_2:
usart_stop_bit_set(usart->uart_base, USART_STB_2BIT);
break;
default:
usart_stop_bit_set(usart->uart_base, USART_STB_1BIT);
break;
}
switch (cfg->parity) {
case PARITY_NONE:
usart_parity_config(usart->uart_base, USART_PM_NONE);
break;
case PARITY_ODD:
usart_parity_config(usart->uart_base, USART_PM_ODD);
break;
case PARITY_EVEN:
usart_parity_config(usart->uart_base, USART_PM_EVEN);
break;
default:
usart_parity_config(usart->uart_base, USART_PM_NONE);
break;
}
usart_hardware_flow_rts_config(usart->uart_base, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(usart->uart_base, USART_RTS_DISABLE);
usart_receive_config(usart->uart_base, USART_RECEIVE_ENABLE);
usart_transmit_config(usart->uart_base, USART_TRANSMIT_ENABLE);
usart_enable(usart->uart_base);
return RT_EOK;
}
static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd,
void *arg) {
struct gd32_uart *usart_obj;
struct gd32_uart_config *usart;
RT_ASSERT(serial != RT_NULL);
usart_obj = (struct gd32_uart *) serial->parent.user_data;
usart = usart_obj->config;
RT_ASSERT(usart != RT_NULL);
switch (cmd) {
case RT_DEVICE_CTRL_CLR_INT:
ECLIC_DisableIRQ(usart->irqn);
usart_interrupt_disable(usart->uart_base, USART_INT_RBNE);
break;
case RT_DEVICE_CTRL_SET_INT:
ECLIC_EnableIRQ(usart->irqn);
/* enable USART0 receive interrupt */
usart_interrupt_enable(usart->uart_base, USART_INT_RBNE);
break;
}
return RT_EOK;
}
static int gd32_putc(struct rt_serial_device *serial, char ch) {
struct gd32_uart *usart_obj;
struct gd32_uart_config *usart;
RT_ASSERT(serial != RT_NULL);
usart_obj = (struct gd32_uart *) serial->parent.user_data;
usart = usart_obj->config;
RT_ASSERT(usart != RT_NULL);
usart_data_transmit(usart->uart_base, (uint8_t) ch);
while (usart_flag_get(usart->uart_base, USART_FLAG_TBE) == RESET);
return 1;
}
static int gd32_getc(struct rt_serial_device *serial) {
int ch;
struct gd32_uart *usart_obj;
struct gd32_uart_config *usart;
RT_ASSERT(serial != RT_NULL);
usart_obj = (struct gd32_uart *) serial->parent.user_data;
usart = usart_obj->config;
RT_ASSERT(usart != RT_NULL);
ch = -1;
if (RESET != usart_flag_get(usart->uart_base, USART_FLAG_RBNE)) {
ch = usart_data_receive(usart->uart_base) & 0xff;
}
return ch;
}
static const struct rt_uart_ops gd32_uart_ops = { gd32_configure, gd32_control,
gd32_putc, gd32_getc,
RT_NULL };
static void usart_isr(struct rt_serial_device *serial) {
struct gd32_uart *usart_obj;
struct gd32_uart_config *usart;
RT_ASSERT(serial != RT_NULL);
usart_obj = (struct gd32_uart *) serial->parent.user_data;
usart = usart_obj->config;
RT_ASSERT(usart != RT_NULL);
if ((usart_interrupt_flag_get(usart->uart_base, USART_INT_FLAG_RBNE)
!= RESET)
&& (RESET != usart_flag_get(usart->uart_base, USART_FLAG_RBNE))) {
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
usart_interrupt_flag_clear(usart->uart_base, USART_INT_FLAG_RBNE);
usart_flag_clear(usart->uart_base, USART_FLAG_RBNE);
} else {
if (usart_flag_get(usart->uart_base, USART_FLAG_CTSF) != RESET) {
usart_flag_clear(usart->uart_base, USART_FLAG_CTSF);
}
if (usart_flag_get(usart->uart_base, USART_FLAG_LBDF) != RESET) {
usart_flag_clear(usart->uart_base, USART_FLAG_LBDF);
}
if (usart_flag_get(usart->uart_base, USART_FLAG_TC) != RESET) {
usart_flag_clear(usart->uart_base, USART_FLAG_TC);
}
}
}
#ifdef BSP_USING_UART0
void USART0_IRQHandler(void) {
rt_interrupt_enter();
usart_isr(&uart_obj[GDUSART0_INDEX].serial);
rt_interrupt_leave();
}
#endif
#ifdef BSP_USING_UART4
void UART4_IRQHandler(void) {
rt_interrupt_enter();
usart_isr(&uart_obj[GDUART4_INDEX].serial);
rt_interrupt_leave();
}
#endif
int rt_hw_usart_init(void) {
rt_size_t obj_num;
int index;
obj_num = sizeof(uart_obj) / sizeof(struct gd32_uart);
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
rt_err_t result = 0;
for (index = 0; index < obj_num; index++) {
/* init UART object */
uart_obj[index].config = &uart_config[index];
uart_obj[index].serial.ops = &gd32_uart_ops;
uart_obj[index].serial.config = config;
/* register UART device */
result = rt_hw_serial_register(&uart_obj[index].serial,
uart_obj[index].config->name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX
| RT_DEVICE_FLAG_INT_TX, &uart_obj[index]);
RT_ASSERT(result == RT_EOK);
}
return result;
}
#endif /* RT_USING_SERIAL */
/******************** end of file *******************/
@@ -0,0 +1,27 @@
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
/* gd32 config class */
struct gd32_uart_config
{
const char *name;
uint32_t uart_base;
IRQn_Type irqn;
};
/* gd32 uart dirver class */
struct gd32_uart
{
struct gd32_uart_config *config;
struct rt_serial_device serial;
};
int rt_hw_usart_init(void);
#endif /* __DRV_USART_H__ */
/******************* end of file *******************/
+206
View File
@@ -0,0 +1,206 @@
#ifndef RT_CONFIG_H__
#define RT_CONFIG_H__
/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */
/* RT-Thread Kernel */
#define RT_NAME_MAX 8
#define RT_ALIGN_SIZE 4
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 100
#define RT_USING_OVERFLOW_CHECK
#define RT_USING_HOOK
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 256
#define RT_USING_TIMER_SOFT
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 512
#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
/* end of Inter-Thread communication */
/* Memory Management */
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_HEAP
/* end of Memory Management */
/* Kernel Device Object */
#define RT_USING_DEVICE
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uart4"
/* end of Kernel Device Object */
#define RT_VER_NUM 0x40003
/* end of RT-Thread Kernel */
/* 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 */
/* end of 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
/* end of Command shell */
/* Device virtual file system */
#define RT_USING_DFS
#define DFS_USING_WORKDIR
#define DFS_FILESYSTEMS_MAX 2
#define DFS_FILESYSTEM_TYPES_MAX 2
#define DFS_FD_MAX 16
#define RT_USING_DFS_DEVFS
/* end of 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 */
/* end of Using USB */
/* end of Device Drivers */
/* POSIX layer and C standard library */
#define RT_USING_LIBC
#define RT_USING_POSIX
/* end of POSIX layer and C standard library */
/* Network */
/* Socket abstraction layer */
/* end of Socket abstraction layer */
/* Network interface device */
/* end of Network interface device */
/* light weight TCP/IP stack */
/* end of light weight TCP/IP stack */
/* AT commands */
/* end of AT commands */
/* end of Network */
/* VBUS(Virtual Software BUS) */
/* end of VBUS(Virtual Software BUS) */
/* Utilities */
/* end of Utilities */
/* end of RT-Thread Components */
/* RT-Thread online packages */
/* IoT - internet of things */
/* Wi-Fi */
/* Marvell WiFi */
/* end of Marvell WiFi */
/* Wiced WiFi */
/* end of Wiced WiFi */
/* end of Wi-Fi */
/* IoT Cloud */
/* end of IoT Cloud */
/* end of IoT - internet of things */
/* security packages */
/* end of security packages */
/* language packages */
/* end of language packages */
/* multimedia packages */
/* end of multimedia packages */
/* tools packages */
/* end of tools packages */
/* system packages */
/* end of system packages */
/* peripheral libraries and drivers */
/* end of peripheral libraries and drivers */
/* miscellaneous packages */
/* samples: kernel and components samples */
/* end of samples: kernel and components samples */
/* end of miscellaneous packages */
/* end of RT-Thread online packages */
/* Hardware Drivers Config */
#define SOC_GD32VF103V
/* Onboard Peripheral Drivers */
#define BSP_USING_USART
/* end of Onboard Peripheral Drivers */
/* On-chip Peripheral Drivers */
#define BSP_USING_UART
#define BSP_USING_UART4
/* end of On-chip Peripheral Drivers */
/* Board extended module Drivers */
/* end of Hardware Drivers Config */
#define SOC_GD32VF103
#endif
+59
View File
@@ -0,0 +1,59 @@
import os
# toolchains options
ARCH='risc-v'
CPU='nuclei'
CROSS_TOOL='gcc'
if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = 'D:/Software/Nuclei/gcc/bin'
else:
print("CROSS_TOOL = {} not yet supported" % CROSS_TOOL)
# if os.getenv('RTT_EXEC_PATH'):
# EXEC_PATH = os.getenv('RTT_EXEC_PATH')
BUILD = 'debug'
NUCLEI_SDK_ROOT = os.path.abspath("../nuclei_sdk")
SOC_LIBRARY_ROOT = os.path.join(NUCLEI_SDK_ROOT, "SoC", "gd32vf103")
LINK_FILE = os.path.join(SOC_LIBRARY_ROOT, "Board", "gd32vf103v_rvstar", "Source", "GCC", "gcc_gd32vf103_flashxip.ld")
OPENOCD_CFG = os.path.join(SOC_LIBRARY_ROOT, "Board", "gd32vf103v_rvstar", "openocd_gd32vf103.cfg")
if PLATFORM == 'gcc':
# toolchains
PREFIX = 'riscv-nuclei-elf-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
GDB = PREFIX + 'gdb'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = '-march=rv32imac -mabi=ilp32 -mcmodel=medany '
CFLAGS = DEVICE + ' -ffunction-sections -fdata-sections -fno-common '
AFLAGS = CFLAGS
LFLAGS = DEVICE + ' --specs=nano.specs --specs=nosys.specs -nostartfiles -Wl,--gc-sections '
LFLAGS += ' -Wl,-cref,-Map=rtthread.map -u _printf_float'
LFLAGS += ' -T ' + LINK_FILE
LFLAGS += ' -u _isatty -u _write -u _sbrk -u _read -u _close -u _fstat -u _lseek '
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O2 -ggdb'
AFLAGS += ' -ggdb'
else:
CFLAGS += ' -O2 -Os'
CXXFLAGS = CFLAGS
DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n'
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
@@ -0,0 +1,224 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CORE_COMPATIABLE_H__
#define __CORE_COMPATIABLE_H__
/*!
* @file core_compatiable.h
* @brief ARM compatiable function definitions header file
*/
#ifdef __cplusplus
extern "C" {
#endif
/* ===== ARM Compatiable Functions ===== */
/**
* \defgroup NMSIS_Core_ARMCompatiable_Functions ARM Compatiable Functions
* \ingroup NMSIS_Core
* \brief A few functions that compatiable with ARM CMSIS-Core.
* \details
*
* Here we provided a few functions that compatiable with ARM CMSIS-Core,
* mostly used in the DSP and NN library.
* @{
*/
/** \brief Instruction Synchronization Barrier, compatiable with ARM */
#define __ISB() __RWMB()
/** \brief Data Synchronization Barrier, compatiable with ARM */
#define __DSB() __RWMB()
/** \brief Data Memory Barrier, compatiable with ARM */
#define __DMB() __RWMB()
/** \brief LDRT Unprivileged (8 bit), ARM Compatiable */
#define __LDRBT(ptr) __LB((ptr))
/** \brief LDRT Unprivileged (16 bit), ARM Compatiable */
#define __LDRHT(ptr) __LH((ptr))
/** \brief LDRT Unprivileged (32 bit), ARM Compatiable */
#define __LDRT(ptr) __LW((ptr))
/** \brief STRT Unprivileged (8 bit), ARM Compatiable */
#define __STRBT(ptr) __SB((ptr))
/** \brief STRT Unprivileged (16 bit), ARM Compatiable */
#define __STRHT(ptr) __SH((ptr))
/** \brief STRT Unprivileged (32 bit), ARM Compatiable */
#define __STRT(ptr) __SW((ptr))
/* ===== Saturation Operations ===== */
/**
* \brief Signed Saturate
* \details Saturates a signed value.
* \param [in] value Value to be saturated
* \param [in] sat Bit position to saturate to (1..32)
* \return Saturated value
*/
__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat)
{
if ((sat >= 1U) && (sat <= 32U)) {
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
const int32_t min = -1 - max ;
if (val > max) {
return max;
} else if (val < min) {
return min;
}
}
return val;
}
/**
* \brief Unsigned Saturate
* \details Saturates an unsigned value.
* \param [in] value Value to be saturated
* \param [in] sat Bit position to saturate to (0..31)
* \return Saturated value
*/
__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat)
{
if (sat <= 31U) {
const uint32_t max = ((1U << sat) - 1U);
if (val > (int32_t)max) {
return max;
} else if (val < 0) {
return 0U;
}
}
return (uint32_t)val;
}
/* ===== Data Processing Operations ===== */
/**
* \brief Reverse byte order (32 bit)
* \details Reverses the byte order in unsigned integer value.
* For example, 0x12345678 becomes 0x78563412.
* \param [in] value Value to reverse
* \return Reversed value
*/
__STATIC_FORCEINLINE uint32_t __REV(uint32_t value)
{
uint32_t result;
result = ((value & 0xff000000) >> 24)
| ((value & 0x00ff0000) >> 8 )
| ((value & 0x0000ff00) << 8 )
| ((value & 0x000000ff) << 24);
return result;
}
/**
* \brief Reverse byte order (16 bit)
* \details Reverses the byte order within each halfword of a word.
* For example, 0x12345678 becomes 0x34127856.
* \param [in] value Value to reverse
* \return Reversed value
*/
__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
result = ((value & 0xff000000) >> 8)
| ((value & 0x00ff00000) << 8 )
| ((value & 0x0000ff00) >> 8 )
| ((value & 0x000000ff) << 8) ;
return result;
}
/**
* \brief Reverse byte order (16 bit)
* \details Reverses the byte order in a 16-bit value
* and returns the signed 16-bit result.
* For example, 0x0080 becomes 0x8000.
* \param [in] value Value to reverse
* \return Reversed value
*/
__STATIC_FORCEINLINE int16_t __REVSH(int16_t value)
{
int16_t result;
result = ((value & 0xff00) >> 8) | ((value & 0x00ff) << 8);
return result;
}
/**
* \brief Rotate Right in unsigned value (32 bit)
* \details Rotate Right (immediate) provides the value of
* the contents of a register rotated by a variable number of bits.
* \param [in] op1 Value to rotate
* \param [in] op2 Number of Bits to rotate(0-31)
* \return Rotated value
*/
__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
op2 = op2 & 0x1F;
if (op2 == 0U) {
return op1;
}
return (op1 >> op2) | (op1 << (32U - op2));
}
/**
* \brief Reverse bit order of value
* \details Reverses the bit order of the given value.
* \param [in] value Value to reverse
* \return Reversed value
*/
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1)
#define __RBIT(value) __RV_BITREV((value), 31)
#else
__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value != 0U; value >>= 1U) {
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return result;
}
#endif /* defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) */
/**
* \brief Count leading zeros
* \details Counts the number of leading zeros of a data value.
* \param [in] data Value to count the leading zeros
* \return number of leading zeros in value
*/
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1)
#define __CLZ(data) __RV_CLZ32(data)
#else
__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t data)
{
uint8_t ret = 0;
uint32_t temp = ~data;
while (temp & 0x80000000) {
temp <<= 1;
ret++;
}
return ret;
}
#endif /* defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) */
/** @} */ /* End of Doxygen Group NMSIS_Core_ARMCompatiable_Functions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_COMPATIABLE_H__ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CORE_FEATURE_CACHE_H__
#define __CORE_FEATURE_CACHE_H__
/*!
* @file core_feature_cache.h
* @brief Cache feature API header file for Nuclei N/NX Core
*/
/*
* Cache Feature Configuration Macro:
* 1. __ICACHE_PRESENT: Define whether I-Cache Unit is present or not.
* * 0: Not present
* * 1: Present
* 1. __DCACHE_PRESENT: Define whether D-Cache Unit is present or not.
* * 0: Not present
* * 1: Present
*/
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)
/* ########################## Cache functions #################################### */
/**
* \defgroup NMSIS_Core_Cache Cache Functions
* \brief Functions that configure Instruction and Data Cache.
* @{
*/
/** @} */ /* End of Doxygen Group NMSIS_Core_Cache */
/**
* \defgroup NMSIS_Core_ICache I-Cache Functions
* \ingroup NMSIS_Core_Cache
* \brief Functions that configure Instruction Cache.
* @{
*/
/**
* \brief Enable ICache
* \details
* This function enable I-Cache
* \remarks
* - This \ref CSR_MCACHE_CTL register control I Cache enable.
* \sa
* - \ref DisableICache
*/
__STATIC_FORCEINLINE void EnableICache (void)
{
__RV_CSR_SET(CSR_MCACHE_CTL, CSR_MCACHE_CTL_IE);
}
/**
* \brief Disable ICache
* \details
* This function Disable I-Cache
* \remarks
* - This \ref CSR_MCACHE_CTL register control I Cache enable.
* \sa
* - \ref EnableICache
*/
__STATIC_FORCEINLINE void DisableICache (void)
{
__RV_CSR_CLEAR(CSR_MCACHE_CTL, CSR_MCACHE_CTL_IE);
}
/** @} */ /* End of Doxygen Group NMSIS_Core_ICache */
#endif /* defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1) */
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)
/**
* \defgroup NMSIS_Core_DCache D-Cache Functions
* \ingroup NMSIS_Core_Cache
* \brief Functions that configure Data Cache.
* @{
*/
/**
* \brief Enable DCache
* \details
* This function enable D-Cache
* \remarks
* - This \ref CSR_MCACHE_CTL register control D Cache enable.
* \sa
* - \ref DisableDCache
*/
__STATIC_FORCEINLINE void EnableDCache (void)
{
__RV_CSR_SET(CSR_MCACHE_CTL, CSR_MCACHE_CTL_DE);
}
/**
* \brief Disable DCache
* \details
* This function Disable D-Cache
* \remarks
* - This \ref CSR_MCACHE_CTL register control D Cache enable.
* \sa
* - \ref EnableDCache
*/
__STATIC_FORCEINLINE void DisableDCache (void)
{
__RV_CSR_CLEAR(CSR_MCACHE_CTL, CSR_MCACHE_CTL_DE);
}
/** @} */ /* End of Doxygen Group NMSIS_Core_DCache */
#endif /* defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1) */
#ifdef __cplusplus
}
#endif
#endif /** __CORE_FEATURE_CACHE_H__ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,304 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CORE_FEATURE_FPU_H__
#define __CORE_FEATURE_FPU_H__
/*!
* @file core_feature_fpu.h
* @brief FPU feature API header file for Nuclei N/NX Core
*/
/*
* FPU Feature Configuration Macro:
* 1. __FPU_PRESENT: Define whether Floating Point Unit(FPU) is present or not
* * 0: Not present
* * 1: Single precision FPU present, __RISCV_FLEN == 32
* * 2: Double precision FPU present, __RISCV_FLEN == 64
*/
#ifdef __cplusplus
extern "C" {
#endif
/* ===== FPU Operations ===== */
/**
* \defgroup NMSIS_Core_FPU_Functions FPU Functions
* \ingroup NMSIS_Core
* \brief Functions that related to the RISC-V FPU (F and D extension).
* \details
*
* Nuclei provided floating point unit by RISC-V F and D extension.
* * `F extension` adds single-precision floating-point computational
* instructions compliant with the IEEE 754-2008 arithmetic standard, __RISCV_FLEN = 32.
* The F extension adds 32 floating-point registers, f0-f31, each 32 bits wide,
* and a floating-point control and status register fcsr, which contains the
* operating mode and exception status of the floating-point unit.
* * `D extension` adds double-precision floating-point computational instructions
* compliant with the IEEE 754-2008 arithmetic standard.
* The D extension widens the 32 floating-point registers, f0-f31, to 64 bits, __RISCV_FLEN = 64
* @{
*/
#if defined(__FPU_PRESENT) && (__FPU_PRESENT > 0)
#if __FPU_PRESENT == 1
/** \brief Refer to the width of the floating point register in bits(either 32 or 64) */
#define __RISCV_FLEN 32
#elif __FPU_PRESENT == 2
#define __RISCV_FLEN 64
#else
#define __RISCV_FLEN __riscv_flen
#endif /* __FPU_PRESENT == 1 */
/** \brief Get FCSR CSR Register */
#define __get_FCSR() __RV_CSR_READ(CSR_FCSR)
/** \brief Set FCSR CSR Register with val */
#define __set_FCSR(val) __RV_CSR_WRITE(CSR_FCSR, (val))
/** \brief Get FRM CSR Register */
#define __get_FRM() __RV_CSR_READ(CSR_FRM)
/** \brief Set FRM CSR Register with val */
#define __set_FRM(val) __RV_CSR_WRITE(CSR_FRM, (val))
/** \brief Get FFLAGS CSR Register */
#define __get_FFLAGS() __RV_CSR_READ(CSR_FFLAGS)
/** \brief Set FFLAGS CSR Register with val */
#define __set_FFLAGS(val) __RV_CSR_WRITE(CSR_FFLAGS, (val))
/** \brief Enable FPU Unit */
#define __enable_FPU() __RV_CSR_SET(CSR_MSTATUS, MSTATUS_FS)
/**
* \brief Disable FPU Unit
* \details
* * We can save power by disable FPU Unit.
* * When FPU Unit is disabled, any access to FPU related CSR registers
* and FPU instructions will cause illegal Instuction Exception.
* */
#define __disable_FPU() __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_FS)
/**
* \brief Load a single-precision value from memory into float point register freg using flw instruction
* \details The FLW instruction loads a single-precision floating point value from memory
* address (addr + ofs) into floating point register freg(f0-f31)
* \param [in] freg The floating point register, eg. FREG(0), f0
* \param [in] addr The memory base address, 4 byte aligned required
* \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value
* \remarks
* * FLW and FSW operations need to make sure the address is 4 bytes aligned,
* otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
* * FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical
* NaNs are preserved
*
*/
#define __RV_FLW(freg, addr, ofs) \
({ \
register rv_csr_t __addr = (rv_csr_t)(addr); \
__ASM volatile("flw " STRINGIFY(freg) ", %0(%1) " \
: : "I"(ofs), "r"(__addr) \
: "memory"); \
})
/**
* \brief Store a single-precision value from float point freg into memory using fsw instruction
* \details The FSW instruction stores a single-precision value from floating point register to memory
* \param [in] freg The floating point register(f0-f31), eg. FREG(0), f0
* \param [in] addr The memory base address, 4 byte aligned required
* \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value
* \remarks
* * FLW and FSW operations need to make sure the address is 4 bytes aligned,
* otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
* * FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical
* NaNs are preserved
*
*/
#define __RV_FSW(freg, addr, ofs) \
({ \
register rv_csr_t __addr = (rv_csr_t)(addr); \
__ASM volatile("fsw " STRINGIFY(freg) ", %0(%1) " \
: : "I"(ofs), "r"(__addr) \
: "memory"); \
})
/**
* \brief Load a double-precision value from memory into float point register freg using fld instruction
* \details The FLD instruction loads a double-precision floating point value from memory
* address (addr + ofs) into floating point register freg(f0-f31)
* \param [in] freg The floating point register, eg. FREG(0), f0
* \param [in] addr The memory base address, 8 byte aligned required
* \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value
* \attention
* * Function only available for double precision floating point unit, FLEN = 64
* \remarks
* * FLD and FSD operations need to make sure the address is 8 bytes aligned,
* otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
* * FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical
* NaNs are preserved.
*/
#define __RV_FLD(freg, addr, ofs) \
({ \
register rv_csr_t __addr = (rv_csr_t)(addr); \
__ASM volatile("fld " STRINGIFY(freg) ", %0(%1) " \
: : "I"(ofs), "r"(__addr) \
: "memory"); \
})
/**
* \brief Store a double-precision value from float point freg into memory using fsd instruction
* \details The FSD instruction stores double-precision value from floating point register to memory
* \param [in] freg The floating point register(f0-f31), eg. FREG(0), f0
* \param [in] addr The memory base address, 8 byte aligned required
* \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value
* \attention
* * Function only available for double precision floating point unit, FLEN = 64
* \remarks
* * FLD and FSD operations need to make sure the address is 8 bytes aligned,
* otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
* * FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical
* NaNs are preserved.
*
*/
#define __RV_FSD(freg, addr, ofs) \
({ \
register rv_csr_t __addr = (rv_csr_t)(addr); \
__ASM volatile("fsd " STRINGIFY(freg) ", %0(%1) " \
: : "I"(ofs), "r"(__addr) \
: "memory"); \
})
/**
* \def __RV_FLOAD
* \brief Load a float point value from memory into float point register freg using flw/fld instruction
* \details
* * For Single-Precison Floating-Point Mode(__FPU_PRESENT == 1, __RISCV_FLEN == 32):
* It will call \ref __RV_FLW to load a single-precision floating point value from memory to floating point register
* * For Double-Precison Floating-Point Mode(__FPU_PRESENT == 2, __RISCV_FLEN == 64):
* It will call \ref __RV_FLD to load a double-precision floating point value from memory to floating point register
*
* \attention
* Function behaviour is different for __FPU_PRESENT = 1 or 2, please see the real function this macro represent
*/
/**
* \def __RV_FSTORE
* \brief Store a float value from float point freg into memory using fsw/fsd instruction
* \details
* * For Single-Precison Floating-Point Mode(__FPU_PRESENT == 1, __RISCV_FLEN == 32):
* It will call \ref __RV_FSW to store floating point register into memory
* * For Double-Precison Floating-Point Mode(__FPU_PRESENT == 2, __RISCV_FLEN == 64):
* It will call \ref __RV_FSD to store floating point register into memory
*
* \attention
* Function behaviour is different for __FPU_PRESENT = 1 or 2, please see the real function this macro represent
*/
#if __FPU_PRESENT == 1
#define __RV_FLOAD __RV_FLW
#define __RV_FSTORE __RV_FSW
/** \brief Type of FPU register, depends on the FLEN defined in RISC-V */
typedef uint32_t rv_fpu_t;
#elif __FPU_PRESENT == 2
#define __RV_FLOAD __RV_FLD
#define __RV_FSTORE __RV_FSD
/** \brief Type of FPU register, depends on the FLEN defined in RISC-V */
typedef uint64_t rv_fpu_t;
#endif /* __FPU_PRESENT == 2 */
/**
* \brief Save FPU context into variables for interrupt nesting
* \details
* This macro is used to declare variables which are used for saving
* FPU context, and it will store the nessary fpu registers into
* these variables, it need to be used in a interrupt when in this
* interrupt fpu registers are used.
* \remarks
* - It need to be used together with \ref RESTORE_FPU_CONTEXT
* - Don't use variable names __fpu_context in your ISR code
* - If you isr code will use fpu registers, and this interrupt is nested.
* Then you can do it like this:
* \code
* void eclic_mtip_handler(void)
* {
* // !!!Interrupt is enabled here!!!
* // !!!Higher priority interrupt could nest it!!!
*
* // Necessary only when you need to use fpu registers
* // in this isr handler functions
* SAVE_FPU_CONTEXT();
*
* // put you own interrupt handling code here
*
* // pair of SAVE_FPU_CONTEXT()
* RESTORE_FPU_CONTEXT();
* }
* \endcode
*/
#define SAVE_FPU_CONTEXT() \
rv_fpu_t __fpu_context[20]; \
__RV_FSTORE(FREG(0), __fpu_context, 0 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(1), __fpu_context, 1 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(2), __fpu_context, 2 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(3), __fpu_context, 3 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(4), __fpu_context, 4 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(5), __fpu_context, 5 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(6), __fpu_context, 6 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(7), __fpu_context, 7 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(10), __fpu_context, 8 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(11), __fpu_context, 9 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(12), __fpu_context, 10 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(13), __fpu_context, 11 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(14), __fpu_context, 12 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(15), __fpu_context, 13 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(16), __fpu_context, 14 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(17), __fpu_context, 15 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(28), __fpu_context, 16 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(29), __fpu_context, 17 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(30), __fpu_context, 18 << LOG_FPREGBYTES); \
__RV_FSTORE(FREG(31), __fpu_context, 19 << LOG_FPREGBYTES);
/**
* \brief Restore necessary fpu registers from variables for interrupt nesting
* \details
* This macro is used restore necessary fpu registers from pre-defined variables
* in \ref SAVE_FPU_CONTEXT macro.
* \remarks
* - It need to be used together with \ref SAVE_FPU_CONTEXT
*/
#define RESTORE_FPU_CONTEXT() \
__RV_FLOAD(FREG(0), __fpu_context, 0 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(1), __fpu_context, 1 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(2), __fpu_context, 2 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(3), __fpu_context, 3 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(4), __fpu_context, 4 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(5), __fpu_context, 5 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(6), __fpu_context, 6 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(7), __fpu_context, 7 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(10), __fpu_context, 8 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(11), __fpu_context, 9 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(12), __fpu_context, 10 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(13), __fpu_context, 11 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(14), __fpu_context, 12 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(15), __fpu_context, 13 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(16), __fpu_context, 14 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(17), __fpu_context, 15 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(28), __fpu_context, 16 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(29), __fpu_context, 17 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(30), __fpu_context, 18 << LOG_FPREGBYTES); \
__RV_FLOAD(FREG(31), __fpu_context, 19 << LOG_FPREGBYTES);
#else
#define SAVE_FPU_CONTEXT()
#define RESTORE_FPU_CONTEXT()
#endif /* __FPU_PRESENT > 0 */
/** @} */ /* End of Doxygen Group NMSIS_Core_FPU_Functions */
#ifdef __cplusplus
}
#endif
#endif /** __RISCV_EXT_FPU_H__ */
@@ -0,0 +1,260 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CORE_FEATURE_PMP_H__
#define __CORE_FEATURE_PMP_H__
/*!
* @file core_feature_pmp.h
* @brief PMP feature API header file for Nuclei N/NX Core
*/
/*
* PMP Feature Configuration Macro:
* 1. __PMP_PRESENT: Define whether Physical Memory Protection(PMP) is present or not
* * 0: Not present
* * 1: Present
* 2. __PMP_ENTRY_NUM: Define the number of PMP entries, only 8 or 16 is configurable.
*/
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__PMP_PRESENT) && (__PMP_PRESENT == 1)
/* ===== PMP Operations ===== */
/**
* \defgroup NMSIS_Core_PMP_Functions PMP Functions
* \ingroup NMSIS_Core
* \brief Functions that related to the RISCV Phyiscal Memory Protection.
* \details
* Optional physical memory protection (PMP) unit provides per-hart machine-mode
* control registers to allow physical memory access privileges (read, write, execute)
* to be specified for each physical memory region.
*
* The PMP can supports region access control settings as small as four bytes.
*
* @{
*/
#ifndef __PMP_ENTRY_NUM
/* numbers of PMP entries(__PMP_ENTRY_NUM) should be defined in <Device.h> */
#error "__PMP_ENTRY_NUM is not defined, please check!"
#endif
/**
* \brief Get 8bit PMPxCFG Register by PMP entry index
* \details Return the content of the PMPxCFG Register.
* \param [in] idx PMP region index(0-15)
* \return PMPxCFG Register value
*/
__STATIC_INLINE uint8_t __get_PMPxCFG(uint32_t idx)
{
rv_csr_t pmpcfg = 0;
if (idx >= __PMP_ENTRY_NUM) return 0;
#if __RISCV_XLEN == 32
if (idx < 4) {
pmpcfg = __RV_CSR_READ(CSR_PMPCFG0);
} else if ((idx >=4) && (idx < 8)) {
idx -= 4;
pmpcfg = __RV_CSR_READ(CSR_PMPCFG1);
} else if ((idx >=8) && (idx < 12)) {
idx -= 8;
pmpcfg = __RV_CSR_READ(CSR_PMPCFG2);
} else {
idx -= 12;
pmpcfg = __RV_CSR_READ(CSR_PMPCFG3);
}
idx = idx << 3;
return (uint8_t)((pmpcfg>>idx) & 0xFF);
#elif __RISCV_XLEN == 64
if (idx < 8) {
pmpcfg = __RV_CSR_READ(CSR_PMPCFG0);
} else {
idx -= 8;
pmpcfg = __RV_CSR_READ(CSR_PMPCFG2);
}
idx = idx << 3;
return (uint8_t)((pmpcfg>>idx) & 0xFF);
#else
// TODO Add RV128 Handling
return 0;
#endif
}
/**
* \brief Set 8bit PMPxCFG by pmp entry index
* \details Set the given pmpxcfg value to the PMPxCFG Register.
* \param [in] idx PMPx region index(0-15)
* \param [in] pmpxcfg PMPxCFG register value to set
*/
__STATIC_INLINE void __set_PMPxCFG(uint32_t idx, uint8_t pmpxcfg)
{
rv_csr_t pmpcfgx = 0;
if (idx >= __PMP_ENTRY_NUM) return;
#if __RISCV_XLEN == 32
if (idx < 4) {
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG0);
idx = idx << 3;
pmpcfgx = (pmpcfgx & ~(0xFFUL << idx)) | ((rv_csr_t)pmpxcfg << idx);
__RV_CSR_WRITE(CSR_PMPCFG0, pmpcfgx);
} else if ((idx >=4) && (idx < 8)) {
idx -= 4;
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG1);
idx = idx << 3;
pmpcfgx = (pmpcfgx & ~(0xFFUL << idx)) | ((rv_csr_t)pmpxcfg << idx);
__RV_CSR_WRITE(CSR_PMPCFG1, pmpcfgx);
} else if ((idx >=8) && (idx < 12)) {
idx -= 8;
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG2);
idx = idx << 3;
pmpcfgx = (pmpcfgx & ~(0xFFUL << idx)) | ((rv_csr_t)pmpxcfg << idx);
__RV_CSR_WRITE(CSR_PMPCFG2, pmpcfgx);
} else {
idx -= 12;
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG3);
idx = idx << 3;
pmpcfgx = (pmpcfgx & ~(0xFFUL << idx)) | ((rv_csr_t)pmpxcfg << idx);
__RV_CSR_WRITE(CSR_PMPCFG3, pmpcfgx);
}
#elif __RISCV_XLEN == 64
if (idx < 8) {
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG0);
idx = idx << 3;
pmpcfgx = (pmpcfgx & ~(0xFFULL << idx)) | ((rv_csr_t)pmpxcfg << idx);
__RV_CSR_WRITE(CSR_PMPCFG0, pmpcfgx);
} else {
idx -= 8;
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG2);
idx = idx << 3;
pmpcfgx = (pmpcfgx & ~(0xFFULL << idx)) | ((rv_csr_t)pmpxcfg << idx);
__RV_CSR_WRITE(CSR_PMPCFG2, pmpcfgx);
}
#else
// TODO Add RV128 Handling
#endif
}
/**
* \brief Get PMPCFGx Register by index
* \details Return the content of the PMPCFGx Register.
* \param [in] idx PMPCFG CSR index(0-3)
* \return PMPCFGx Register value
* \remark
* - For RV64, only idx = 0 and idx = 2 is allowed.
* pmpcfg0 and pmpcfg2 hold the configurations
* for the 16 PMP entries, pmpcfg1 and pmpcfg3 are illegal
* - For RV32, pmpcfg0pmpcfg3, hold the configurations
* pmp0cfgpmp15cfg for the 16 PMP entries
*/
__STATIC_INLINE rv_csr_t __get_PMPCFGx(uint32_t idx)
{
switch (idx) {
case 0: return __RV_CSR_READ(CSR_PMPCFG0);
case 1: return __RV_CSR_READ(CSR_PMPCFG1);
case 2: return __RV_CSR_READ(CSR_PMPCFG2);
case 3: return __RV_CSR_READ(CSR_PMPCFG3);
default: return 0;
}
}
/**
* \brief Set PMPCFGx by index
* \details Write the given value to the PMPCFGx Register.
* \param [in] idx PMPCFG CSR index(0-3)
* \param [in] pmpcfg PMPCFGx Register value to set
* \remark
* - For RV64, only idx = 0 and idx = 2 is allowed.
* pmpcfg0 and pmpcfg2 hold the configurations
* for the 16 PMP entries, pmpcfg1 and pmpcfg3 are illegal
* - For RV32, pmpcfg0pmpcfg3, hold the configurations
* pmp0cfgpmp15cfg for the 16 PMP entries
*/
__STATIC_INLINE void __set_PMPCFGx(uint32_t idx, rv_csr_t pmpcfg)
{
switch (idx) {
case 0: __RV_CSR_WRITE(CSR_PMPCFG0, pmpcfg); break;
case 1: __RV_CSR_WRITE(CSR_PMPCFG1, pmpcfg); break;
case 2: __RV_CSR_WRITE(CSR_PMPCFG2, pmpcfg); break;
case 3: __RV_CSR_WRITE(CSR_PMPCFG3, pmpcfg); break;
default: return;
}
}
/**
* \brief Get PMPADDRx Register by index
* \details Return the content of the PMPADDRx Register.
* \param [in] idx PMP region index(0-15)
* \return PMPADDRx Register value
*/
__STATIC_INLINE rv_csr_t __get_PMPADDRx(uint32_t idx)
{
switch (idx) {
case 0: return __RV_CSR_READ(CSR_PMPADDR0);
case 1: return __RV_CSR_READ(CSR_PMPADDR1);
case 2: return __RV_CSR_READ(CSR_PMPADDR2);
case 3: return __RV_CSR_READ(CSR_PMPADDR3);
case 4: return __RV_CSR_READ(CSR_PMPADDR4);
case 5: return __RV_CSR_READ(CSR_PMPADDR5);
case 6: return __RV_CSR_READ(CSR_PMPADDR6);
case 7: return __RV_CSR_READ(CSR_PMPADDR7);
case 8: return __RV_CSR_READ(CSR_PMPADDR8);
case 9: return __RV_CSR_READ(CSR_PMPADDR9);
case 10: return __RV_CSR_READ(CSR_PMPADDR10);
case 11: return __RV_CSR_READ(CSR_PMPADDR11);
case 12: return __RV_CSR_READ(CSR_PMPADDR12);
case 13: return __RV_CSR_READ(CSR_PMPADDR13);
case 14: return __RV_CSR_READ(CSR_PMPADDR14);
case 15: return __RV_CSR_READ(CSR_PMPADDR15);
default: return 0;
}
}
/**
* \brief Set PMPADDRx by index
* \details Write the given value to the PMPADDRx Register.
* \param [in] idx PMP region index(0-15)
* \param [in] pmpaddr PMPADDRx Register value to set
*/
__STATIC_INLINE void __set_PMPADDRx(uint32_t idx, rv_csr_t pmpaddr)
{
switch (idx) {
case 0: __RV_CSR_WRITE(CSR_PMPADDR0, pmpaddr); break;
case 1: __RV_CSR_WRITE(CSR_PMPADDR1, pmpaddr); break;
case 2: __RV_CSR_WRITE(CSR_PMPADDR2, pmpaddr); break;
case 3: __RV_CSR_WRITE(CSR_PMPADDR3, pmpaddr); break;
case 4: __RV_CSR_WRITE(CSR_PMPADDR4, pmpaddr); break;
case 5: __RV_CSR_WRITE(CSR_PMPADDR5, pmpaddr); break;
case 6: __RV_CSR_WRITE(CSR_PMPADDR6, pmpaddr); break;
case 7: __RV_CSR_WRITE(CSR_PMPADDR7, pmpaddr); break;
case 8: __RV_CSR_WRITE(CSR_PMPADDR8, pmpaddr); break;
case 9: __RV_CSR_WRITE(CSR_PMPADDR9, pmpaddr); break;
case 10: __RV_CSR_WRITE(CSR_PMPADDR10, pmpaddr); break;
case 11: __RV_CSR_WRITE(CSR_PMPADDR11, pmpaddr); break;
case 12: __RV_CSR_WRITE(CSR_PMPADDR12, pmpaddr); break;
case 13: __RV_CSR_WRITE(CSR_PMPADDR13, pmpaddr); break;
case 14: __RV_CSR_WRITE(CSR_PMPADDR14, pmpaddr); break;
case 15: __RV_CSR_WRITE(CSR_PMPADDR15, pmpaddr); break;
default: return;
}
}
/** @} */ /* End of Doxygen Group NMSIS_Core_PMP_Functions */
#endif /* defined(__PMP_PRESENT) && (__PMP_PRESENT == 1) */
#ifdef __cplusplus
}
#endif
#endif /** __CORE_FEATURE_PMP_H__ */
@@ -0,0 +1,364 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CORE_FEATURE_TIMER_H__
#define __CORE_FEATURE_TIMER_H__
/*!
* @file core_feature_timer.h
* @brief System Timer feature API header file for Nuclei N/NX Core
*/
/*
* System Timer Feature Configuration Macro:
* 1. __SYSTIMER_PRESENT: Define whether Private System Timer is present or not.
* * 0: Not present
* * 1: Present
* 2. __SYSTIMER_BASEADDR: Define the base address of the System Timer.
*/
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1)
/**
* \defgroup NMSIS_Core_SysTimer_Registers Register Define and Type Definitions Of System Timer
* \ingroup NMSIS_Core_Registers
* \brief Type definitions and defines for system timer registers.
*
* @{
*/
/**
* \brief Structure type to access the System Timer (SysTimer).
* \details
* Structure definition to access the system timer(SysTimer).
* \remarks
* - MSFTRST register is introduced in Nuclei N Core version 1.3(\ref __NUCLEI_N_REV >= 0x0103)
* - MSTOP register is renamed to MTIMECTL register in Nuclei N Core version 1.4(\ref __NUCLEI_N_REV >= 0x0104)
* - CMPCLREN and CLKSRC bit in MTIMECTL register is introduced in Nuclei N Core version 1.4(\ref __NUCLEI_N_REV >= 0x0104)
*/
typedef struct {
__IOM uint64_t MTIMER; /*!< Offset: 0x000 (R/W) System Timer current value 64bits Register */
__IOM uint64_t MTIMERCMP; /*!< Offset: 0x008 (R/W) System Timer compare Value 64bits Register */
__IOM uint32_t RESERVED0[0x3F8]; /*!< Offset: 0x010 - 0xFEC Reserved */
__IOM uint32_t MSFTRST; /*!< Offset: 0xFF0 (R/W) System Timer Software Core Reset Register */
__IOM uint32_t RESERVED1; /*!< Offset: 0xFF4 Reserved */
__IOM uint32_t MTIMECTL; /*!< Offset: 0xFF8 (R/W) System Timer Control Register, previously MSTOP register */
__IOM uint32_t MSIP; /*!< Offset: 0xFFC (R/W) System Timer SW interrupt Register */
} SysTimer_Type;
/* Timer Control / Status Register Definitions */
#define SysTimer_MTIMECTL_TIMESTOP_Pos 0U /*!< SysTick Timer MTIMECTL: TIMESTOP bit Position */
#define SysTimer_MTIMECTL_TIMESTOP_Msk (1UL << SysTimer_MTIMECTL_TIMESTOP_Pos) /*!< SysTick Timer MTIMECTL: TIMESTOP Mask */
#define SysTimer_MTIMECTL_CMPCLREN_Pos 1U /*!< SysTick Timer MTIMECTL: CMPCLREN bit Position */
#define SysTimer_MTIMECTL_CMPCLREN_Msk (1UL << SysTimer_MTIMECTL_CMPCLREN_Pos) /*!< SysTick Timer MTIMECTL: CMPCLREN Mask */
#define SysTimer_MTIMECTL_CLKSRC_Pos 2U /*!< SysTick Timer MTIMECTL: CLKSRC bit Position */
#define SysTimer_MTIMECTL_CLKSRC_Msk (1UL << SysTimer_MTIMECTL_CLKSRC_Pos) /*!< SysTick Timer MTIMECTL: CLKSRC Mask */
#define SysTimer_MSIP_MSIP_Pos 0U /*!< SysTick Timer MSIP: MSIP bit Position */
#define SysTimer_MSIP_MSIP_Msk (1UL << SysTimer_MSIP_MSIP_Pos) /*!< SysTick Timer MSIP: MSIP Mask */
#define SysTimer_MTIMER_Msk (0xFFFFFFFFFFFFFFFFULL) /*!< SysTick Timer MTIMER value Mask */
#define SysTimer_MTIMERCMP_Msk (0xFFFFFFFFFFFFFFFFULL) /*!< SysTick Timer MTIMERCMP value Mask */
#define SysTimer_MTIMECTL_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MTIMECTL/MSTOP value Mask */
#define SysTimer_MSIP_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MSIP value Mask */
#define SysTimer_MSFTRST_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MSFTRST value Mask */
#define SysTimer_MSFRST_KEY (0x80000A5FUL) /*!< SysTick Timer Software Reset Request Key */
#ifndef __SYSTIMER_BASEADDR
/* Base address of SYSTIMER(__SYSTIMER_BASEADDR) should be defined in <Device.h> */
#error "__SYSTIMER_BASEADDR is not defined, please check!"
#endif
/* System Timer Memory mapping of Device */
#define SysTimer_BASE __SYSTIMER_BASEADDR /*!< SysTick Base Address */
#define SysTimer ((SysTimer_Type *) SysTimer_BASE) /*!< SysTick configuration struct */
/** @} */ /* end of group NMSIS_Core_SysTimer_Registers */
/* ################################## SysTimer function ############################################ */
/**
* \defgroup NMSIS_Core_SysTimer SysTimer Functions
* \brief Functions that configure the Core System Timer.
* @{
*/
/**
* \brief Set system timer load value
* \details
* This function set the system timer load value in MTIMER register.
* \param [in] value value to set system timer MTIMER register.
* \remarks
* - Load value is 64bits wide.
* - \ref SysTimer_GetLoadValue
*/
__STATIC_FORCEINLINE void SysTimer_SetLoadValue(uint64_t value)
{
SysTimer->MTIMER = value;
}
/**
* \brief Get system timer load value
* \details
* This function get the system timer current value in MTIMER register.
* \return current value(64bit) of system timer MTIMER register.
* \remarks
* - Load value is 64bits wide.
* - \ref SysTimer_SetLoadValue
*/
__STATIC_FORCEINLINE uint64_t SysTimer_GetLoadValue(void)
{
return SysTimer->MTIMER;
}
/**
* \brief Set system timer compare value
* \details
* This function set the system Timer compare value in MTIMERCMP register.
* \param [in] value compare value to set system timer MTIMERCMP register.
* \remarks
* - Compare value is 64bits wide.
* - If compare value is larger than current value timer interrupt generate.
* - Modify the load value or compare value less to clear the interrupt.
* - \ref SysTimer_GetCompareValue
*/
__STATIC_FORCEINLINE void SysTimer_SetCompareValue(uint64_t value)
{
SysTimer->MTIMERCMP = value;
}
/**
* \brief Get system timer compare value
* \details
* This function get the system timer compare value in MTIMERCMP register.
* \return compare value of system timer MTIMERCMP register.
* \remarks
* - Compare value is 64bits wide.
* - \ref SysTimer_SetCompareValue
*/
__STATIC_FORCEINLINE uint64_t SysTimer_GetCompareValue(void)
{
return SysTimer->MTIMERCMP;
}
/**
* \brief Enable system timer counter running
* \details
* Enable system timer counter running by clear
* TIMESTOP bit in MTIMECTL register.
*/
__STATIC_FORCEINLINE void SysTimer_Start(void)
{
SysTimer->MTIMECTL &= ~(SysTimer_MTIMECTL_TIMESTOP_Msk);
}
/**
* \brief Stop system timer counter running
* \details
* Stop system timer counter running by set
* TIMESTOP bit in MTIMECTL register.
*/
__STATIC_FORCEINLINE void SysTimer_Stop(void)
{
SysTimer->MTIMECTL |= SysTimer_MTIMECTL_TIMESTOP_Msk;
}
/**
* \brief Set system timer control value
* \details
* This function set the system timer MTIMECTL register value.
* \param [in] mctl value to set MTIMECTL register
* \remarks
* - Bit TIMESTOP is used to start and stop timer.
* Clear TIMESTOP bit to 0 to start timer, otherwise to stop timer.
* - Bit CMPCLREN is used to enable auto MTIMER clear to zero when MTIMER >= MTIMERCMP.
* Clear CMPCLREN bit to 0 to stop auto clear MTIMER feature, otherwise to enable it.
* - Bit CLKSRC is used to select timer clock source.
* Clear CLKSRC bit to 0 to use *mtime_toggle_a*, otherwise use *core_clk_aon*
* - \ref SysTimer_GetControlValue
*/
__STATIC_FORCEINLINE void SysTimer_SetControlValue(uint32_t mctl)
{
SysTimer->MTIMECTL = (mctl & SysTimer_MTIMECTL_Msk);
}
/**
* \brief Get system timer control value
* \details
* This function get the system timer MTIMECTL register value.
* \return MTIMECTL register value
* \remarks
* - \ref SysTimer_SetControlValue
*/
__STATIC_FORCEINLINE uint32_t SysTimer_GetControlValue(void)
{
return (SysTimer->MTIMECTL & SysTimer_MTIMECTL_Msk);
}
/**
* \brief Trigger or set software interrupt via system timer
* \details
* This function set the system timer MSIP bit in MSIP register.
* \remarks
* - Set system timer MSIP bit and generate a SW interrupt.
* - \ref SysTimer_ClearSWIRQ
* - \ref SysTimer_GetMsipValue
*/
__STATIC_FORCEINLINE void SysTimer_SetSWIRQ(void)
{
SysTimer->MSIP |= SysTimer_MSIP_MSIP_Msk;
}
/**
* \brief Clear system timer software interrupt pending request
* \details
* This function clear the system timer MSIP bit in MSIP register.
* \remarks
* - Clear system timer MSIP bit in MSIP register to clear the software interrupt pending.
* - \ref SysTimer_SetSWIRQ
* - \ref SysTimer_GetMsipValue
*/
__STATIC_FORCEINLINE void SysTimer_ClearSWIRQ(void)
{
SysTimer->MSIP &= ~SysTimer_MSIP_MSIP_Msk;
}
/**
* \brief Get system timer MSIP register value
* \details
* This function get the system timer MSIP register value.
* \return Value of Timer MSIP register.
* \remarks
* - Bit0 is SW interrupt flag.
* Bit0 is 1 then SW interrupt set. Bit0 is 0 then SW interrupt clear.
* - \ref SysTimer_SetSWIRQ
* - \ref SysTimer_ClearSWIRQ
*/
__STATIC_FORCEINLINE uint32_t SysTimer_GetMsipValue(void)
{
return (uint32_t)(SysTimer->MSIP & SysTimer_MSIP_Msk);
}
/**
* \brief Set system timer MSIP register value
* \details
* This function set the system timer MSIP register value.
* \param [in] msip value to set MSIP register
*/
__STATIC_FORCEINLINE void SysTimer_SetMsipValue(uint32_t msip)
{
SysTimer->MSIP = (msip & SysTimer_MSIP_Msk);
}
/**
* \brief Do software reset request
* \details
* This function will do software reset request through MTIMER
* - Software need to write \ref SysTimer_MSFRST_KEY to generate software reset request
* - The software request flag can be cleared by reset operation to clear
* \remarks
* - The software reset is sent to SoC, SoC need to generate reset signal and send back to Core
* - This function will not return, it will do while(1) to wait the Core reset happened
*/
__STATIC_FORCEINLINE void SysTimer_SoftwareReset(void)
{
SysTimer->MSFTRST = SysTimer_MSFRST_KEY;
while(1);
}
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) && defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
/**
* \brief System Tick Configuration
* \details Initializes the System Timer and its non-vector interrupt, and starts the System Tick Timer.
*
* In our default implementation, the timer counter will be set to zero, and it will start a timer compare non-vector interrupt
* when it matchs the ticks user set, during the timer interrupt user should reload the system tick using \ref SysTick_Reload function
* or similar function written by user, so it can produce period timer interrupt.
* \param [in] ticks Number of ticks between two interrupts.
* \return 0 Function succeeded.
* \return 1 Function failed.
* \remarks
* - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced,
* but we assume that the CMPCLREN bit is set to 0, so MTIMER register will not be
* auto cleared to 0 when MTIMER >= MTIMERCMP.
* - When the variable \ref __Vendor_SysTickConfig is set to 1, then the
* function \ref SysTick_Config is not included.
* - In this case, the file <b><Device>.h</b> must contain a vendor-specific implementation
* of this function.
* - If user need this function to start a period timer interrupt, then in timer interrupt handler
* routine code, user should call \ref SysTick_Reload with ticks to reload the timer.
* - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0
* \sa
* - \ref SysTimer_SetCompareValue; SysTimer_SetLoadValue
*/
__STATIC_INLINE uint32_t SysTick_Config(uint64_t ticks)
{
SysTimer_SetLoadValue(0);
SysTimer_SetCompareValue(ticks);
ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT);
ECLIC_SetLevelIRQ(SysTimer_IRQn, 1);
ECLIC_EnableIRQ(SysTimer_IRQn);
return (0UL);
}
/**
* \brief System Tick Reload
* \details Reload the System Timer Tick when the MTIMECMP reached TIME value
*
* \param [in] ticks Number of ticks between two interrupts.
* \return 0 Function succeeded.
* \return 1 Function failed.
* \remarks
* - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced,
* but for this \ref SysTick_Config function, we assume this CMPCLREN bit is set to 0,
* so in interrupt handler function, user still need to set the MTIMERCMP or MTIMER to reload
* the system tick, if vendor want to use this timer's auto clear feature, they can define
* \ref __Vendor_SysTickConfig to 1, and implement \ref SysTick_Config and \ref SysTick_Reload functions.
* - When the variable \ref __Vendor_SysTickConfig is set to 1, then the
* function \ref SysTick_Reload is not included.
* - In this case, the file <b><Device>.h</b> must contain a vendor-specific implementation
* of this function.
* - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0
* - Since the MTIMERCMP value might overflow, if overflowed, MTIMER will be set to 0, and MTIMERCMP set to ticks
* \sa
* - \ref SysTimer_SetCompareValue
* - \ref SysTimer_SetLoadValue
*/
__STATIC_FORCEINLINE uint32_t SysTick_Reload(uint64_t ticks)
{
uint64_t cur_ticks = SysTimer->MTIMER;
uint64_t reload_ticks = ticks + cur_ticks;
if (__USUALLY(reload_ticks > cur_ticks)) {
SysTimer->MTIMERCMP = reload_ticks;
} else {
/* When added the ticks value, then the MTIMERCMP < TIMER,
* which means the MTIMERCMP is overflowed,
* so we need to reset the counter to zero */
SysTimer->MTIMER = 0;
SysTimer->MTIMERCMP = ticks;
}
return (0UL);
}
#endif /* defined(__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) */
/** @} */ /* End of Doxygen Group NMSIS_Core_SysTimer */
#endif /* defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1) */
#ifdef __cplusplus
}
#endif
#endif /** __CORE_FEATURE_TIMER_H__ */
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __NMSIS_COMPILER_H
#define __NMSIS_COMPILER_H
#include <stdint.h>
/*!
* @file nmsis_compiler.h
* @brief NMSIS compiler generic header file
*/
#if defined ( __GNUC__ )
/** GNU GCC Compiler */
#include "nmsis_gcc.h"
#else
#error Unknown compiler.
#endif
#endif /* __NMSIS_COMPILER_H */
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2009-2019 Arm Limited. All rights reserved.
* -- Adaptable modifications made for Nuclei Processors. --
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __NMSIS_CORE_H__
#define __NMSIS_CORE_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "nmsis_version.h"
/**
* \ingroup NMSIS_Core_VersionControl
* @{
*/
/* The following enum __NUCLEI_N_REV/__NUCLEI_NX_REV definition in this file
* is only used for doxygen documentation generation,
* The <device>.h is the real file to define it by vendor
*/
#if defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__)
/**
* \brief Nuclei N class core revision number
* \details
* Reversion number format: [15:8] revision number, [7:0] patch number
* \attention
* This define is exclusive with \ref __NUCLEI_NX_REV
*/
#define __NUCLEI_N_REV (0x0104)
/**
* \brief Nuclei NX class core revision number
* \details
* Reversion number format: [15:8] revision number, [7:0] patch number
* \attention
* This define is exclusive with \ref __NUCLEI_N_REV
*/
#define __NUCLEI_NX_REV (0x0100)
#endif /* __ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__ */
/** @} */ /* End of Group NMSIS_Core_VersionControl */
#include "nmsis_compiler.h" /* NMSIS compiler specific defines */
/* === Include Nuclei Core Related Headers === */
/* Include core base feature header file */
#include "core_feature_base.h"
#ifndef __NMSIS_GENERIC
/* Include core eclic feature header file */
#include "core_feature_eclic.h"
/* Include core systimer feature header file */
#include "core_feature_timer.h"
#endif
/* Include core fpu feature header file */
#include "core_feature_fpu.h"
/* Include core dsp feature header file */
#include "core_feature_dsp.h"
/* Include core pmp feature header file */
#include "core_feature_pmp.h"
/* Include core cache feature header file */
#include "core_feature_cache.h"
/* Include compatiable functions header file */
#include "core_compatiable.h"
#ifdef __cplusplus
}
#endif
#endif /* __NMSIS_CORE_H__ */
@@ -0,0 +1,265 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __NMSIS_GCC_H__
#define __NMSIS_GCC_H__
/*!
* @file nmsis_gcc.h
* @brief NMSIS compiler GCC header file
*/
#include <stdint.h>
#include "riscv_encoding.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ######################### Startup and Lowlevel Init ######################## */
/**
* \defgroup NMSIS_Core_CompilerControl Compiler Control
* \ingroup NMSIS_Core
* \brief Compiler agnostic \#define symbols for generic c/c++ source code
* \details
*
* The NMSIS-Core provides the header file <b>nmsis_compiler.h</b> with consistent \#define symbols for generate C or C++ source files that should be compiler agnostic.
* Each NMSIS compliant compiler should support the functionality described in this section.
*
* The header file <b>nmsis_compiler.h</b> is also included by each Device Header File <device.h> so that these definitions are available.
* @{
*/
/* ignore some GCC warnings */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wunused-parameter"
/* Fallback for __has_builtin */
#ifndef __has_builtin
#define __has_builtin(x) (0)
#endif
/* NMSIS compiler specific defines */
/** \brief Pass information from the compiler to the assembler. */
#ifndef __ASM
#define __ASM __asm
#endif
/** \brief Recommend that function should be inlined by the compiler. */
#ifndef __INLINE
#define __INLINE inline
#endif
/** \brief Define a static function that may be inlined by the compiler. */
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
/** \brief Define a static function that should be always inlined by the compiler. */
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
#endif
/** \brief Inform the compiler that a function does not return. */
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((__noreturn__))
#endif
/** \brief Inform that a variable shall be retained in executable image. */
#ifndef __USED
#define __USED __attribute__((used))
#endif
/** \brief restrict pointer qualifier to enable additional optimizations. */
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
/** \brief specified the vector size of the variable, measured in bytes */
#ifndef __VECTOR_SIZE
#define __VECTOR_SIZE(x) __attribute__((vector_size(x)))
#endif
/** \brief Request smallest possible alignment. */
#ifndef __PACKED
#define __PACKED __attribute__((packed, aligned(1)))
#endif
/** \brief Request smallest possible alignment for a structure. */
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
#endif
/** \brief Request smallest possible alignment for a union. */
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpacked"
#pragma GCC diagnostic ignored "-Wattributes"
/** \brief Packed struct for unaligned uint16_t write access */
__PACKED_STRUCT T_UINT16_WRITE {
uint16_t v;
};
#pragma GCC diagnostic pop
/** \brief Pointer for unaligned write of a uint16_t variable. */
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpacked"
#pragma GCC diagnostic ignored "-Wattributes"
/** \brief Packed struct for unaligned uint16_t read access */
__PACKED_STRUCT T_UINT16_READ {
uint16_t v;
};
#pragma GCC diagnostic pop
/** \brief Pointer for unaligned read of a uint16_t variable. */
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpacked"
#pragma GCC diagnostic ignored "-Wattributes"
/** \brief Packed struct for unaligned uint32_t write access */
__PACKED_STRUCT T_UINT32_WRITE {
uint32_t v;
};
#pragma GCC diagnostic pop
/** \brief Pointer for unaligned write of a uint32_t variable. */
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpacked"
#pragma GCC diagnostic ignored "-Wattributes"
/** \brief Packed struct for unaligned uint32_t read access */
__PACKED_STRUCT T_UINT32_READ {
uint32_t v;
};
#pragma GCC diagnostic pop
/** \brief Pointer for unaligned read of a uint32_t variable. */
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
/** \brief Minimum `x` bytes alignment for a variable. */
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
/** \brief restrict pointer qualifier to enable additional optimizations. */
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
/** \brief Barrier to prevent compiler from reordering instructions. */
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __ASM volatile("":::"memory")
#endif
/** \brief provide the compiler with branch prediction information, the branch is usually true */
#ifndef __USUALLY
#define __USUALLY(exp) __builtin_expect((exp), 1)
#endif
/** \brief provide the compiler with branch prediction information, the branch is rarely true */
#ifndef __RARELY
#define __RARELY(exp) __builtin_expect((exp), 0)
#endif
/** \brief Use this attribute to indicate that the specified function is an interrupt handler. */
#ifndef __INTERRUPT
#define __INTERRUPT __attribute__((interrupt))
#endif
/** @} */ /* End of Doxygen Group NMSIS_Core_CompilerControl */
/* IO definitions (access restrictions to peripheral registers) */
/**
* \defgroup NMSIS_Core_PeriphAccess Peripheral Access
* \brief Naming conventions and optional features for accessing peripherals.
*
* The section below describes the naming conventions, requirements, and optional features
* for accessing device specific peripherals.
* Most of the rules also apply to the core peripherals.
*
* The **Device Header File <device.h>** contains typically these definition
* and also includes the core specific header files.
*
* @{
*/
/** \brief Defines 'read only' permissions */
#ifdef __cplusplus
#define __I volatile
#else
#define __I volatile const
#endif
/** \brief Defines 'write only' permissions */
#define __O volatile
/** \brief Defines 'read / write' permissions */
#define __IO volatile
/* following defines should be used for structure members */
/** \brief Defines 'read only' structure member permissions */
#define __IM volatile const
/** \brief Defines 'write only' structure member permissions */
#define __OM volatile
/** \brief Defines 'read/write' structure member permissions */
#define __IOM volatile
/**
* \brief Mask and shift a bit field value for use in a register bit range.
* \details The macro \ref _VAL2FLD uses the #define's _Pos and _Msk of the related bit
* field to shift bit-field values for assigning to a register.
*
* **Example**:
* \code
* ECLIC->CFG = _VAL2FLD(CLIC_CLICCFG_NLBIT, 3);
* \endcode
* \param[in] field Name of the register bit field.
* \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
* \return Masked and shifted value.
*/
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
/**
* \brief Mask and shift a register value to extract a bit filed value.
* \details The macro \ref _FLD2VAL uses the #define's _Pos and _Msk of the related bit
* field to extract the value of a bit field from a register.
*
* **Example**:
* \code
* nlbits = _FLD2VAL(CLIC_CLICCFG_NLBIT, ECLIC->CFG);
* \endcode
* \param[in] field Name of the register bit field.
* \param[in] value Value of register. This parameter is interpreted as an uint32_t type.
* \return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
/** @} */ /* end of group NMSIS_Core_PeriphAccess */
#ifdef __cplusplus
}
#endif
#endif /* __NMSIS_GCC_H__ */
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __NMSIS_VERSION_H
#define __NMSIS_VERSION_H
/**
* \defgroup NMSIS_Core_VersionControl Version Control
* \ingroup NMSIS_Core
* \brief Version \#define symbols for NMSIS release specific C/C++ source code
* \details
*
* We followed the [semantic versioning 2.0.0](https://semver.org/) to control NMSIS version.
* The version format is **MAJOR.MINOR.PATCH**, increment the:
* 1. MAJOR version when you make incompatible API changes,
* 2. MINOR version when you add functionality in a backwards compatible manner, and
* 3. PATCH version when you make backwards compatible bug fixes.
*
* The header file `nmsis_version.h` is included by each core header so that these definitions are available.
*
* **Example Usage for NMSIS Version Check**:
* \code
* #if defined(__NMSIS_VERSION) && (__NMSIS_VERSION >= 0x00010105)
* #warning "Yes, we have NMSIS 1.1.5 or later"
* #else
* #error "We need NMSIS 1.1.5 or later!"
* #endif
* \endcode
*
* @{
*/
/*!
* \file nmsis_version.h
* \brief NMSIS Version definitions
**/
/**
* \brief Represent the NMSIS major version
* \details
* The NMSIS major version can be used to
* differentiate between NMSIS major releases.
* */
#define __NMSIS_VERSION_MAJOR (1U)
/**
* \brief Represent the NMSIS minor version
* \details
* The NMSIS minor version can be used to
* query a NMSIS release update including new features.
*
**/
#define __NMSIS_VERSION_MINOR (0U)
/**
* \brief Represent the NMSIS patch version
* \details
* The NMSIS patch version can be used to
* show bug fixes in this package.
**/
#define __NMSIS_VERSION_PATCH (0U)
/**
* \brief Represent the NMSIS Version
* \details
* NMSIS Version format: **MAJOR.MINOR.PATCH**
* * MAJOR: \ref __NMSIS_VERSION_MAJOR, stored in `bits [31:16]` of \ref __NMSIS_VERSION
* * MINOR: \ref __NMSIS_VERSION_MINOR, stored in `bits [15:8]` of \ref __NMSIS_VERSION
* * PATCH: \ref __NMSIS_VERSION_PATCH, stored in `bits [7:0]` of \ref __NMSIS_VERSION
**/
#define __NMSIS_VERSION ((__NMSIS_VERSION_MAJOR << 16U) | (__NMSIS_VERSION_MINOR << 8) | __NMSIS_VERSION_PATCH)
/** @} */ /* End of Doxygen Group NMSIS_Core_VersionControl */
#endif
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __RISCV_BITS_H__
#define __RISCV_BITS_H__
#ifdef __cplusplus
extern "C" {
#endif
#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 /* __riscv_xlen */
#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 /* __riscv_flen */
#define FPREGBYTES (1 << LOG_FPREGBYTES)
#define __rv_likely(x) __builtin_expect((x), 1)
#define __rv_unlikely(x) __builtin_expect((x), 0)
#define __RV_ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
#define __RV_ROUNDDOWN(a, b) ((a)/(b)*(b))
#define __RV_MAX(a, b) ((a) > (b) ? (a) : (b))
#define __RV_MIN(a, b) ((a) < (b) ? (a) : (b))
#define __RV_CLAMP(a, lo, hi) MIN(MAX(a, lo), hi)
#define __RV_EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
#define __RV_INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
#ifdef __ASSEMBLY__
#define _AC(X,Y) X
#define _AT(T,X) X
#else
#define __AC(X,Y) (X##Y)
#define _AC(X,Y) __AC(X,Y)
#define _AT(T,X) ((T)(X))
#endif /* __ASSEMBLY__ */
#define _UL(x) (_AC(x, UL))
#define _ULL(x) (_AC(x, ULL))
#define _BITUL(x) (_UL(1) << (x))
#define _BITULL(x) (_ULL(1) << (x))
#define UL(x) (_UL(x))
#define ULL(x) (_ULL(x))
#define STR(x) XSTR(x)
#define XSTR(x) #x
#define __STR(s) #s
#define STRINGIFY(s) __STR(s)
#ifdef __cplusplus
}
#endif
#endif /** __RISCV_BITS_H__ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,379 @@
/* ----------------------------------------------------------------------
* Project: NMSIS DSP Library
* Title: riscv_common_tables.h
* Description: Extern declaration for common tables
*
* $Date: 27. January 2017
* $Revision: V.1.5.1
*
* Target Processor: RISC-V Cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _RISCV_COMMON_TABLES_H
#define _RISCV_COMMON_TABLES_H
#include "riscv_math.h"
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_FFT_ALLOW_TABLES)
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREV_1024)
extern const uint16_t riscvBitRevTable[1024];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_16)
extern const float32_t twiddleCoef_16[32];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_32)
extern const float32_t twiddleCoef_32[64];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_64)
extern const float32_t twiddleCoef_64[128];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_128)
extern const float32_t twiddleCoef_128[256];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_256)
extern const float32_t twiddleCoef_256[512];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_512)
extern const float32_t twiddleCoef_512[1024];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_1024)
extern const float32_t twiddleCoef_1024[2048];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_2048)
extern const float32_t twiddleCoef_2048[4096];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_4096)
extern const float32_t twiddleCoef_4096[8192];
#define twiddleCoef twiddleCoef_4096
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_16)
extern const q31_t twiddleCoef_16_q31[24];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_32)
extern const q31_t twiddleCoef_32_q31[48];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_64)
extern const q31_t twiddleCoef_64_q31[96];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_128)
extern const q31_t twiddleCoef_128_q31[192];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_256)
extern const q31_t twiddleCoef_256_q31[384];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_512)
extern const q31_t twiddleCoef_512_q31[768];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_1024)
extern const q31_t twiddleCoef_1024_q31[1536];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_2048)
extern const q31_t twiddleCoef_2048_q31[3072];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_4096)
extern const q31_t twiddleCoef_4096_q31[6144];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_16)
extern const q15_t twiddleCoef_16_q15[24];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_32)
extern const q15_t twiddleCoef_32_q15[48];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_64)
extern const q15_t twiddleCoef_64_q15[96];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_128)
extern const q15_t twiddleCoef_128_q15[192];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_256)
extern const q15_t twiddleCoef_256_q15[384];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_512)
extern const q15_t twiddleCoef_512_q15[768];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_1024)
extern const q15_t twiddleCoef_1024_q15[1536];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_2048)
extern const q15_t twiddleCoef_2048_q15[3072];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_4096)
extern const q15_t twiddleCoef_4096_q15[6144];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_32)
extern const float32_t twiddleCoef_rfft_32[32];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_64)
extern const float32_t twiddleCoef_rfft_64[64];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_128)
extern const float32_t twiddleCoef_rfft_128[128];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_256)
extern const float32_t twiddleCoef_rfft_256[256];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_512)
extern const float32_t twiddleCoef_rfft_512[512];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_1024)
extern const float32_t twiddleCoef_rfft_1024[1024];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_2048)
extern const float32_t twiddleCoef_rfft_2048[2048];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_4096)
extern const float32_t twiddleCoef_rfft_4096[4096];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
/* floating-point bit reversal tables */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_16)
#define RISCVBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20)
extern const uint16_t riscvBitRevIndexTable16[RISCVBITREVINDEXTABLE_16_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_32)
#define RISCVBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48)
extern const uint16_t riscvBitRevIndexTable32[RISCVBITREVINDEXTABLE_32_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_64)
#define RISCVBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56)
extern const uint16_t riscvBitRevIndexTable64[RISCVBITREVINDEXTABLE_64_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_128)
#define RISCVBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208)
extern const uint16_t riscvBitRevIndexTable128[RISCVBITREVINDEXTABLE_128_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_256)
#define RISCVBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440)
extern const uint16_t riscvBitRevIndexTable256[RISCVBITREVINDEXTABLE_256_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_512)
#define RISCVBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448)
extern const uint16_t riscvBitRevIndexTable512[RISCVBITREVINDEXTABLE_512_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_1024)
#define RISCVBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800)
extern const uint16_t riscvBitRevIndexTable1024[RISCVBITREVINDEXTABLE_1024_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_2048)
#define RISCVBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808)
extern const uint16_t riscvBitRevIndexTable2048[RISCVBITREVINDEXTABLE_2048_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_4096)
#define RISCVBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t riscvBitRevIndexTable4096[RISCVBITREVINDEXTABLE_4096_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
/* fixed-point bit reversal tables */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_16)
#define RISCVBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12)
extern const uint16_t riscvBitRevIndexTable_fixed_16[RISCVBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_32)
#define RISCVBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24)
extern const uint16_t riscvBitRevIndexTable_fixed_32[RISCVBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_64)
#define RISCVBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56)
extern const uint16_t riscvBitRevIndexTable_fixed_64[RISCVBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_128)
#define RISCVBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112)
extern const uint16_t riscvBitRevIndexTable_fixed_128[RISCVBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_256)
#define RISCVBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240)
extern const uint16_t riscvBitRevIndexTable_fixed_256[RISCVBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_512)
#define RISCVBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480)
extern const uint16_t riscvBitRevIndexTable_fixed_512[RISCVBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_1024)
#define RISCVBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992)
extern const uint16_t riscvBitRevIndexTable_fixed_1024[RISCVBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_2048)
#define RISCVBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
extern const uint16_t riscvBitRevIndexTable_fixed_2048[RISCVBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_4096)
#define RISCVBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t riscvBitRevIndexTable_fixed_4096[RISCVBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_REALCOEF_F32)
extern const float32_t realCoefA[8192];
extern const float32_t realCoefB[8192];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_REALCOEF_Q31)
extern const q31_t realCoefAQ31[8192];
extern const q31_t realCoefBQ31[8192];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_REALCOEF_Q15)
extern const q15_t realCoefAQ15[8192];
extern const q15_t realCoefBQ15[8192];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_F32_128)
extern const float32_t Weights_128[256];
extern const float32_t cos_factors_128[128];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_F32_512)
extern const float32_t Weights_512[1024];
extern const float32_t cos_factors_512[512];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_F32_2048)
extern const float32_t Weights_2048[4096];
extern const float32_t cos_factors_2048[2048];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_F32_8192)
extern const float32_t Weights_8192[16384];
extern const float32_t cos_factors_8192[8192];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q15_128)
extern const q15_t WeightsQ15_128[256];
extern const q15_t cos_factorsQ15_128[128];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q15_512)
extern const q15_t WeightsQ15_512[1024];
extern const q15_t cos_factorsQ15_512[512];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q15_2048)
extern const q15_t WeightsQ15_2048[4096];
extern const q15_t cos_factorsQ15_2048[2048];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q15_8192)
extern const q15_t WeightsQ15_8192[16384];
extern const q15_t cos_factorsQ15_8192[8192];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q31_128)
extern const q31_t WeightsQ31_128[256];
extern const q31_t cos_factorsQ31_128[128];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q31_512)
extern const q31_t WeightsQ31_512[1024];
extern const q31_t cos_factorsQ31_512[512];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q31_2048)
extern const q31_t WeightsQ31_2048[4096];
extern const q31_t cos_factorsQ31_2048[2048];
#endif
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q31_8192)
extern const q31_t WeightsQ31_8192[16384];
extern const q31_t cos_factorsQ31_8192[8192];
#endif
#endif /* if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_FFT_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_FAST_ALLOW_TABLES)
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FAST_TABLES) || defined(RISCV_TABLE_RECIP_Q15)
extern const q15_t riscvRecipTableQ15[64];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) defined(RISCV_ALL_FAST_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FAST_TABLES) || defined(RISCV_TABLE_RECIP_Q31)
extern const q31_t riscvRecipTableQ31[64];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) defined(RISCV_ALL_FAST_TABLES) */
/* Tables for Fast Math Sine and Cosine */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FAST_TABLES) || defined(RISCV_TABLE_SIN_F32)
extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) defined(RISCV_ALL_FAST_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FAST_TABLES) || defined(RISCV_TABLE_SIN_Q31)
extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) defined(RISCV_ALL_FAST_TABLES) */
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FAST_TABLES) || defined(RISCV_TABLE_SIN_Q15)
extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) defined(RISCV_ALL_FAST_TABLES) */
#endif /* if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_FAST_TABLES) */
#endif /* RISCV_COMMON_TABLES_H */
@@ -0,0 +1,67 @@
/* ----------------------------------------------------------------------
* Project: NMSIS DSP Library
* Title: riscv_const_structs.h
* Description: Constant structs that are initialized for user convenience.
* For example, some can be given as arguments to the riscv_cfft_f32() function.
*
* $Date: 27. January 2017
* $Revision: V.1.5.1
*
* Target Processor: RISC-V Cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _RISCV_CONST_STRUCTS_H
#define _RISCV_CONST_STRUCTS_H
#include "riscv_math.h"
#include "riscv_common_tables.h"
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len16;
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len32;
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len64;
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len128;
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len256;
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len512;
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len1024;
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len2048;
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len4096;
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len16;
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len32;
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len64;
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len128;
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len256;
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len512;
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len1024;
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len2048;
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len4096;
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len16;
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len32;
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len64;
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len128;
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len256;
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len512;
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len1024;
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len2048;
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len4096;
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,57 @@
/* ----------------------------------------------------------------------
* Project: NMSIS NN Library
* Title: riscv_nn_tables.h
* Description: Extern declaration for NN tables
*
* $Date: 17. January 2018
* $Revision: V.1.0.0
*
* Target Processor: RISC-V Cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _RISCV_NN_TABLES_H
#define _RISCV_NN_TABLES_H
#include "riscv_math.h"
/**
* @brief tables for various activation functions
*
*/
extern const q15_t sigmoidTable_q15[256];
extern const q7_t sigmoidTable_q7[256];
extern const q7_t tanhTable_q7[256];
extern const q15_t tanhTable_q15[256];
/**
* @brief 2-way tables for various activation functions
*
* 2-way table, H table for value larger than 1/4
* L table for value smaller than 1/4, H table for remaining
* We have this only for the q15_t version. It does not make
* sense to have it for q7_t type
*/
extern const q15_t sigmoidHTable_q15[192];
extern const q15_t sigmoidLTable_q15[128];
#endif /* RISCV_NN_TABLES_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,366 @@
/*
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* ----------------------------------------------------------------------
* Project: NMSIS NN Library
* Title: riscv_nnsupportfunctions.h
* Description: Public header file of support functions for NMSIS NN Library
*
* $Date: July 2019
* $Revision: V.1.0.0
*
* Target Processor: RISC-V Cores
* -------------------------------------------------------------------- */
#ifndef _RISCV_NNSUPPORTFUNCTIONS_H_
#define _RISCV_NNSUPPORTFUNCTIONS_H_
#include "riscv_math.h"
#include "riscv_common_tables.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define LEFT_SHIFT(_shift) (_shift > 0 ? _shift : 0)
#define RIGHT_SHIFT(_shift) (_shift > 0 ? 0 : -_shift)
#define Q31_MIN (0x80000000L)
#define Q31_MAX (0x7FFFFFFFL)
#define MAX(A,B) (A) > (B) ? (A) : (B)
#define MIN(A,B) (A) < (B) ? (A) : (B)
/**
* @brief Union for SIMD access of q31/q15/q7 types
*/
union riscv_nnword
{
q31_t word;
/**< q31 type */
q15_t half_words[2];
/**< q15 type */
q7_t bytes[4];
/**< q7 type */
};
/**
* @brief Struct for specifying activation function types
*
*/
typedef enum
{
RISCV_SIGMOID = 0,
/**< Sigmoid activation function */
RISCV_TANH = 1,
/**< Tanh activation function */
} riscv_nn_activation_type;
/**
* @defgroup nndata_convert Neural Network Data Conversion Functions
*
* Perform data type conversion in-between neural network operations
*
*/
/**
* @brief Converts the elements of the q7 vector to q15 vector without left-shift
* @param[in] *pSrc points to the q7 input vector
* @param[out] *pDst points to the q15 output vector
* @param[in] blockSize length of the input vector
* @return none.
*
*/
void riscv_q7_to_q15_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize);
void riscv_q7_to_q7_no_shift(const q7_t * pSrc, q7_t * pDst, uint32_t blockSize);
/**
* @brief Non-saturating addition of elements of a q7 vector
* @param[in] *input Pointer to the q7 input vector
* @param[out] *output Pointer to the q31 output variable.
* @param[in] block_size length of the input vector
* @return none.
* \par Description:
*
* 2^24 samples can be added without saturating the result.
*
* The equation used for the conversion process is:
*
* <pre>
* sum = input[0] + input[1] + .. + input[block_size -1]
* </pre>
*
* */
void riscv_nn_add_q7(const q7_t *input, q31_t *output, uint32_t block_size);
/**
* @brief Converts the elements of the q7 vector to reordered q15 vector without left-shift
* @param[in] *pSrc points to the q7 input vector
* @param[out] *pDst points to the q15 output vector
* @param[in] blockSize length of the input vector
* @return none.
*
*/
void riscv_q7_to_q15_reordered_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize);
void riscv_q7_to_q7_reordered_no_shift(const q7_t * pSrc, q7_t * pDst, uint32_t blockSize);
/**
* @brief Converts the elements from a q7 vector to a q15 vector with an added offset
* @param[in] *src points to the q7 input vector
* @param[out] *dst points to the q15 output vector
* @param[in] block_size length of the input vector
* @param[in] offset q7 offset to be added to each input vector element.
* @return none.
*
* \par Description:
*
* The equation used for the conversion process is:
*
* <pre>
* dst[n] = (q15_t) src[n] + offset; 0 <= n < block_size.
* </pre>
*
*/
void riscv_q7_to_q15_with_offset(const q7_t *src, q15_t *dst, uint32_t block_size, q7_t offset);
#if defined (RISCV_MATH_DSP)
/**
* @brief read and expand one q7 word into two q15 words
*/
__STATIC_FORCEINLINE void *read_and_pad(void *source, q31_t * out1, q31_t * out2)
{
q31_t inA = *__SIMD32(source)++;
q31_t inAbuf1 = __SXTB16(__ROR(inA, 8));
q31_t inAbuf2 = __SXTB16(inA);
*out2 = __PKHTB(inAbuf1, inAbuf2, 16);
*out1 = __PKHBT(inAbuf2, inAbuf1, 16);
return source;
}
/**
* @brief read and expand one q7 word into two q15 words with reordering
*/
__STATIC_FORCEINLINE q7_t *read_and_pad_reordered(q7_t *source, q31_t * out1, q31_t * out2)
{
q31_t inA = read_q7x4_ia(&source);
*out2 = __SXTB16(__ROR(inA, 8));
*out1 = __SXTB16(inA);
return source;
}
/**
* @brief read and expand one q7 word into two q15 words with reordering and add an offset
*/
__STATIC_FORCEINLINE q7_t *read_and_pad_reordered_with_offset(q7_t *source, q31_t * out1, q31_t * out2,q31_t offset)
{
q31_t inA = read_q7x4_ia(&source);
*out2 = __SXTB16(__ROR(inA, 8));
*out1 = __SXTB16(inA);
*out1 = __QADD16(*out1,offset);
*out2 = __QADD16(*out2,offset);
return source;
}
#endif
/**
* @defgroup NNBasicMath Basic Math Functions for Neural Network Computation
*
* Basic Math Functions for Neural Network Computation
*
*/
/**
* @brief q7 vector multiplication with variable output shifts
* @param[in] *pSrcA pointer to the first input vector
* @param[in] *pSrcB pointer to the second input vector
* @param[out] *pDst pointer to the output vector
* @param[in] out_shift amount of right-shift for output
* @param[in] blockSize number of samples in each vector
* @return none.
*
* <b>Scaling and Overflow Behavior:</b>
* \par
* The function uses saturating arithmetic.
* Results outside of the allowable q15 range [0x8000 0x7FFF] will be saturated.
*/
void riscv_nn_mult_q15(
q15_t * pSrcA,
q15_t * pSrcB,
q15_t * pDst,
const uint16_t out_shift,
uint32_t blockSize);
/**
* @brief q7 vector multiplication with variable output shifts
* @param[in] *pSrcA pointer to the first input vector
* @param[in] *pSrcB pointer to the second input vector
* @param[out] *pDst pointer to the output vector
* @param[in] out_shift amount of right-shift for output
* @param[in] blockSize number of samples in each vector
* @return none.
*
* <b>Scaling and Overflow Behavior:</b>
* \par
* The function uses saturating arithmetic.
* Results outside of the allowable q7 range [0x80 0x7F] will be saturated.
*/
void riscv_nn_mult_q7(
q7_t * pSrcA,
q7_t * pSrcB,
q7_t * pDst,
const uint16_t out_shift,
uint32_t blockSize);
/**
* @brief macro for adding rounding offset
*/
#ifndef RISCV_NN_TRUNCATE
#define NN_ROUND(out_shift) ( (0x1 << out_shift) >> 1 )
#else
#define NN_ROUND(out_shift) 0
#endif
/**
* @brief Saturating doubling high multiply. Result matches
* NEON instruction VQRDMULH.
* @param[in] m1 Multiplicand
* @param[in] m2 Multiplier
* @return Result of multiplication.
*
*/
__STATIC_FORCEINLINE q31_t riscv_nn_sat_doubling_high_mult(const q31_t m1, const q31_t m2)
{
q31_t result = 0;
// Rounding offset to add for a right shift of 31
q63_t mult = 1 << 30;
if ((m1 < 0) ^ (m2 < 0))
{
mult = 1 - mult;
}
// Gets resolved as a SMLAL instruction
mult = mult + (q63_t)m1 * m2;
// Utilize all of the upper 32 bits. This is the doubling step
// as well.
result = mult / (1UL << 31);
if ((m1 == m2) && (m1 == Q31_MIN))
{
result = Q31_MAX;
}
return result;
}
/**
* @brief Rounding divide by power of two.
* @param[in] dividend - Dividend
* @param[in] exponent - Divisor = power(2, exponent)
* Range: [0, 31]
* @return Rounded result of division. Midpoint is rounded away from zero.
*
*/
__STATIC_FORCEINLINE q31_t riscv_nn_divide_by_power_of_two(const q31_t dividend, const q31_t exponent)
{
q31_t result = 0;
const q31_t remainder_mask = (1l << exponent) - 1;
int32_t remainder = remainder_mask & dividend;
// Basic division
result = dividend >> exponent;
// Adjust 'result' for rounding (mid point away from zero)
q31_t threshold = remainder_mask >> 1;
if (result < 0)
{
threshold++;
}
if (remainder > threshold)
{
result++;
}
return result;
}
/**
* @brief Requantize a given value.
* @param[in] val Value to be requantized
* @param[in] multiplier multiplier
* @param[in] shift left or right shift for 'val * multiplier'
*
* @return Returns (val * multiplier)/(2 ^ shift)
*
*/
__STATIC_FORCEINLINE q31_t riscv_nn_requantize(const q31_t val, const q31_t multiplier, const q31_t shift)
{
return riscv_nn_divide_by_power_of_two(riscv_nn_sat_doubling_high_mult(val * (1 << LEFT_SHIFT(shift)), multiplier),
RIGHT_SHIFT(shift));
}
/**
@brief Read 2 q15 elements and post increment pointer.
@param[in] in_q15 Pointer to pointer that holds address of input.
@return q31 value
*/
__STATIC_FORCEINLINE q31_t riscv_nn_read_q15x2_ia(const q15_t **in_q15)
{
q31_t val;
memcpy(&val, *in_q15, 4);
*in_q15 += 2;
return (val);
}
/**
@brief Read 4 q7 from q7 pointer and post increment pointer.
@param[in] in_q7 Pointer to pointer that holds address of input.
@return q31 value
*/
__STATIC_FORCEINLINE q31_t riscv_nn_read_q7x4_ia(const q7_t **in_q7)
{
q31_t val;
memcpy(&val, *in_q7, 4);
*in_q7 += 4;
return (val);
}
#ifdef __cplusplus
}
#endif
#endif
+31
View File
@@ -0,0 +1,31 @@
# RT-Thread building script for component
Import('rtconfig')
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
SoC_Common = 'SoC/gd32vf103/Common'
SoC_Board = 'SoC/gd32vf103/Board/gd32vf103v_rvstar'
src = Glob(SoC_Common + '/Source/*.c')
src += Glob(SoC_Common + '/Source/Drivers/*.c')
src += Glob(SoC_Common + '/Source/Drivers/Usb/*.c')
src += Glob(SoC_Common + '/Source/Stubs/*.c')
src += Glob(SoC_Common + '/Source/GCC/*.S')
src += Glob(SoC_Board + '/Source/*.c')
CPPPATH = [ cwd + '/NMSIS/Core/Include',
cwd + '/NMSIS/DSP/Include',
cwd + '/NMSIS/NN/Include',
cwd + '/', SoC_Common + '/Include',
cwd + '/', SoC_Common + '/Include/Usb',
cwd + '/', SoC_Common + '/Source/Stubs/',
cwd + '/', SoC_Board + '/Include']
CPPDEFINES = ['-DDOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP', '-DRTOS_RTTHREAD', '-DNUCLEI_BANNER=0']
group = DefineGroup('nuclei_sdk', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES=CPPDEFINES)
Return('group')
@@ -0,0 +1,168 @@
/*!
\file gd32vf103v_eval.h
\brief definitions for GD32VF103V_EVAL's leds, keys and COM ports hardware resources
\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 GD32VF103V_EVAL_H
#define GD32VF103V_EVAL_H
#ifdef cplusplus
extern "C" {
#endif
#include "nuclei_sdk_soc.h"
/* exported types */
typedef enum
{
LED1 = 0,
LED2 = 1,
LED3 = 2,
LED4 = 3
} led_typedef_enum;
typedef enum
{
KEY_A = 0,
KEY_B = 1,
KEY_C = 2,
KEY_D = 3,
KEY_CET = 4
} key_typedef_enum;
typedef enum
{
KEY_MODE_GPIO = 0,
KEY_MODE_EXTI = 1
} keymode_typedef_enum;
/* eval board low layer led */
#define LEDn 4U
#define LED1_PIN GPIO_PIN_0
#define LED1_GPIO_PORT GPIOC
#define LED1_GPIO_CLK RCU_GPIOC
#define LED2_PIN GPIO_PIN_2
#define LED2_GPIO_PORT GPIOC
#define LED2_GPIO_CLK RCU_GPIOC
#define LED3_PIN GPIO_PIN_0
#define LED3_GPIO_PORT GPIOE
#define LED3_GPIO_CLK RCU_GPIOE
#define LED4_PIN GPIO_PIN_1
#define LED4_GPIO_PORT GPIOE
#define LED4_GPIO_CLK RCU_GPIOE
#define COMn 2U
#define GD32_COM0 USART0
#define GD32_COM0_CLK RCU_USART0
#define GD32_COM0_TX_PIN GPIO_PIN_9
#define GD32_COM0_RX_PIN GPIO_PIN_10
#define GD32_COM0_GPIO_PORT GPIOA
#define GD32_COM0_GPIO_CLK RCU_GPIOA
#define GD32_COM1 USART1
#define GD32_COM1_CLK RCU_USART1
#define GD32_COM1_TX_PIN GPIO_PIN_2
#define GD32_COM1_RX_PIN GPIO_PIN_3
#define GD32_COM1_GPIO_PORT GPIOA
#define GD32_COM1_GPIO_CLK RCU_GPIOA
#define KEYn 5U
/* wakeup push-button */
#define KEY_A_PIN GPIO_PIN_0
#define KEY_A_GPIO_PORT GPIOA
#define KEY_A_GPIO_CLK RCU_GPIOA
#define KEY_A_EXTI_LINE EXTI_0
#define KEY_A_EXTI_PORT_SOURCE GPIO_PORT_SOURCE_GPIOA
#define KEY_A_EXTI_PIN_SOURCE GPIO_PIN_SOURCE_0
#define KEY_A_EXTI_IRQn EXTI0_IRQn
/* tamper push-button */
#define KEY_B_PIN GPIO_PIN_13
#define KEY_B_GPIO_PORT GPIOC
#define KEY_B_GPIO_CLK RCU_GPIOC
#define KEY_B_EXTI_LINE EXTI_13
#define KEY_B_EXTI_PORT_SOURCE GPIO_PORT_SOURCE_GPIOC
#define KEY_B_EXTI_PIN_SOURCE GPIO_PIN_SOURCE_13
#define KEY_B_EXTI_IRQn EXTI10_15_IRQn
/* user push-button */
#define KEY_C_PIN GPIO_PIN_14
#define KEY_C_GPIO_PORT GPIOB
#define KEY_C_GPIO_CLK RCU_GPIOB
#define KEY_C_EXTI_LINE EXTI_14
#define KEY_C_EXTI_PORT_SOURCE GPIO_PORT_SOURCE_GPIOB
#define KEY_C_EXTI_PIN_SOURCE GPIO_PIN_SOURCE_14
#define KEY_C_EXTI_IRQn EXTI10_15_IRQn
#define KEY_D_PIN GPIO_PIN_5
#define KEY_D_GPIO_PORT GPIOC
#define KEY_D_GPIO_CLK RCU_GPIOC
#define KEY_D_EXTI_LINE EXTI_5
#define KEY_D_EXTI_PORT_SOURCE GPIO_PORT_SOURCE_GPIOC
#define KEY_D_EXTI_PIN_SOURCE GPIO_PIN_SOURCE_5
#define KEY_D_EXTI_IRQn EXTI5_9_IRQn
#define KEY_CET_PIN GPIO_PIN_4
#define KEY_CET_GPIO_PORT GPIOC
#define KEY_CET_GPIO_CLK RCU_GPIOC
#define KEY_CET_EXTI_LINE EXTI_4
#define KEY_CET_EXTI_PORT_SOURCE GPIO_PORT_SOURCE_GPIOC
#define KEY_CET_EXTI_PIN_SOURCE GPIO_PIN_SOURCE_4
#define KEY_CET_EXTI_IRQn EXTI4_IRQn
/* function declarations */
/* configure led GPIO */
void gd_eval_led_init(led_typedef_enum lednum);
/* turn on selected led */
void gd_eval_led_on(led_typedef_enum lednum);
/* turn off selected led */
void gd_eval_led_off(led_typedef_enum lednum);
/* toggle the selected led */
void gd_eval_led_toggle(led_typedef_enum lednum);
/* configure key */
void gd_eval_key_init(key_typedef_enum keynum, keymode_typedef_enum key_mode);
/* return the selected key state */
uint8_t gd_eval_key_state_get(key_typedef_enum key);
/* configure COM port */
void gd_com_init(uint32_t com);
#ifdef cplusplus
}
#endif
#endif /* GD32VF103V_EVAL_H */
@@ -0,0 +1,16 @@
// See LICENSE for license details.
#ifndef _NUCLEI_SDK_HAL_H
#define _NUCLEI_SDK_HAL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "gd32vf103v_eval.h"
#define NUCLEI_BANNER 1
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,270 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_Device.ld
* @brief GNU Linker Script for gd32vf103 based device
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
/*********** Use Configuration Wizard in Context Menu *************************/
OUTPUT_ARCH( "riscv" )
/********************* Flash Configuration ************************************
* <h> Flash Configuration
* <o0> Flash Base Address <0x0-0xFFFFFFFF:8>
* <o1> Flash Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__ROM_BASE = 0x08000000;
__ROM_SIZE = 0x00020000;
/*--------------------- ILM RAM Configuration ---------------------------
* <h> ILM RAM Configuration
* <o0> ILM RAM Base Address <0x0-0xFFFFFFFF:8>
* <o1> ILM RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__ILM_RAM_BASE = 0x80000000;
__ILM_RAM_SIZE = 0x00010000;
/*--------------------- Embedded RAM Configuration ---------------------------
* <h> RAM Configuration
* <o0> RAM Base Address <0x0-0xFFFFFFFF:8>
* <o1> RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__RAM_BASE = 0x20000000;
__RAM_SIZE = 0x00005000;
/********************* Stack / Heap Configuration ****************************
* <h> Stack / Heap Configuration
* <o0> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
* <o1> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__STACK_SIZE = 0x00000800;
__HEAP_SIZE = 0x00000800;
/**************************** end of configuration section ********************/
/* Define base address and length of flash and ram */
MEMORY
{
flash (rxai!w) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
ram (wxa!ri) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH,ILM and RAM.
* It references following symbols, which must be defined in code:
* _Start : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* _ilm_lma
* _ilm
* __etext
* _etext
* etext
* _eilm
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* _data_lma
* _edata
* edata
* __data_end__
* __bss_start
* __fbss
* _end
* end
* __heap_end
* __StackLimit
* __StackTop
* __STACK_SIZE
*/
/* Define entry label of program */
ENTRY(_start)
SECTIONS
{
__STACK_SIZE = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2K;
.init :
{
/* vector table locate at flash */
*(.vtable)
KEEP (*(SORT_NONE(.init)))
} >flash AT>flash
.ilalign :
{
. = ALIGN(4);
/* Create a section label as _ilm_lma which located at flash */
PROVIDE( _ilm_lma = . );
} >flash AT>flash
.ialign :
{
/* Create a section label as _ilm which located at flash */
PROVIDE( _ilm = . );
} >flash AT>flash
/* Code section located at flash */
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >flash AT>flash
.rodata : ALIGN(4)
{
. = ALIGN(4);
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >flash AT>flash
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >flash AT>flash
. = ALIGN(4);
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
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
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >flash AT>flash
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>flash
/* Define data section virtual address is ram and physical address is flash */
.data :
{
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
} >ram AT>flash
. = ALIGN(4);
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.bss :
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >ram AT>ram
. = ALIGN(8);
PROVIDE( _end = . );
PROVIDE( end = . );
/* Define stack and head location at ram */
.stack ORIGIN(ram) + LENGTH(ram) - __STACK_SIZE :
{
PROVIDE( _heap_end = . );
. = __STACK_SIZE;
PROVIDE( _sp = . );
} >ram AT>ram
}
@@ -0,0 +1,252 @@
/*!
\file gd32vf103v_eval.c
\brief firmware functions to manage leds, keys, COM ports
\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.
*/
#include "nuclei_sdk_hal.h"
#include "gd32vf103_usart.h"
#include "gd32vf103_gpio.h"
#include "gd32vf103_exti.h"
/* private variables */
static uint32_t GPIO_PORT[LEDn] = {LED1_GPIO_PORT, LED2_GPIO_PORT,
LED3_GPIO_PORT, LED4_GPIO_PORT};
static uint32_t GPIO_PIN[LEDn] = {LED1_PIN, LED2_PIN, LED3_PIN, LED4_PIN};
static rcu_periph_enum COM_CLK[COMn] = {GD32_COM0_CLK, GD32_COM1_CLK};
static uint32_t COM_TX_PIN[COMn] = {GD32_COM0_TX_PIN, GD32_COM1_TX_PIN};
static uint32_t COM_RX_PIN[COMn] = {GD32_COM0_RX_PIN, GD32_COM1_RX_PIN};
static uint32_t COM_GPIO_PORT[COMn] = {GD32_COM0_GPIO_PORT, GD32_COM1_GPIO_PORT};
static rcu_periph_enum COM_GPIO_CLK[COMn] = {GD32_COM0_GPIO_CLK, GD32_COM1_GPIO_CLK};
static rcu_periph_enum GPIO_CLK[LEDn] = {LED1_GPIO_CLK, LED2_GPIO_CLK,
LED3_GPIO_CLK, LED4_GPIO_CLK};
static uint32_t KEY_PORT[KEYn] = {KEY_A_GPIO_PORT,
KEY_B_GPIO_PORT,
KEY_C_GPIO_PORT,
KEY_D_GPIO_PORT,
KEY_CET_GPIO_PORT};
static uint32_t KEY_PIN[KEYn] = {KEY_A_PIN,
KEY_B_PIN,
KEY_C_PIN,
KEY_D_PIN,
KEY_CET_PIN};
static rcu_periph_enum KEY_CLK[KEYn] = {KEY_A_GPIO_CLK,
KEY_B_GPIO_CLK,
KEY_C_GPIO_CLK,
KEY_D_GPIO_CLK,
KEY_CET_GPIO_CLK};
static exti_line_enum KEY_EXTI_LINE[KEYn] = {KEY_A_EXTI_LINE,
KEY_B_EXTI_LINE,
KEY_C_EXTI_LINE,
KEY_D_EXTI_LINE,
KEY_CET_EXTI_LINE};
static uint8_t KEY_PORT_SOURCE[KEYn] = {KEY_A_EXTI_PORT_SOURCE,
KEY_B_EXTI_PORT_SOURCE,
KEY_C_EXTI_PORT_SOURCE,
KEY_D_EXTI_PORT_SOURCE,
KEY_CET_EXTI_PORT_SOURCE};
static uint8_t KEY_PIN_SOURCE[KEYn] = {KEY_A_EXTI_PIN_SOURCE,
KEY_B_EXTI_PIN_SOURCE,
KEY_C_EXTI_PIN_SOURCE,
KEY_D_EXTI_PIN_SOURCE,
KEY_CET_EXTI_PIN_SOURCE};
static uint8_t KEY_IRQn[KEYn] = {KEY_A_EXTI_IRQn,
KEY_B_EXTI_IRQn,
KEY_C_EXTI_IRQn,
KEY_D_EXTI_IRQn,
KEY_CET_EXTI_IRQn};
/*!
\brief configure led GPIO
\param[in] lednum: specify the led to be configured
\arg LED1
\arg LED2
\arg LED3
\arg LED4
\param[out] none
\retval none
*/
void gd_eval_led_init(led_typedef_enum lednum)
{
/* enable the led clock */
rcu_periph_clock_enable(GPIO_CLK[lednum]);
/* configure led GPIO port */
gpio_init(GPIO_PORT[lednum], GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN[lednum]);
GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}
/*!
\brief turn on selected led
\param[in] lednum: specify the led to be turned on
\arg LED1
\arg LED2
\arg LED3
\arg LED4
\param[out] none
\retval none
*/
void gd_eval_led_on(led_typedef_enum lednum)
{
GPIO_BOP(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}
/*!
\brief turn off selected led
\param[in] lednum: specify the led to be turned off
\arg LED1
\arg LED2
\arg LED3
\arg LED4
\param[out] none
\retval none
*/
void gd_eval_led_off(led_typedef_enum lednum)
{
GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}
/*!
\brief toggle selected led
\param[in] lednum: specify the led to be toggled
\arg LED1
\arg LED2
\arg LED3
\arg LED4
\param[out] none
\retval none
*/
void gd_eval_led_toggle(led_typedef_enum lednum)
{
gpio_bit_write(GPIO_PORT[lednum], GPIO_PIN[lednum],
(bit_status)(1-gpio_input_bit_get(GPIO_PORT[lednum], GPIO_PIN[lednum])));
}
/*!
\brief configure key
\param[in] key_num: specify the key to be configured
\arg KEY_A: wakeup key
\arg KEY_B: tamper key
\arg KEY_C: user key
\arg KEY_D: user key
\arg KEY_CET: user key
\param[in] key_mode: specify button mode
\arg KEY_MODE_GPIO: key will be used as simple IO
\arg KEY_MODE_EXTI: key will be connected to EXTI line with interrupt
\param[out] none
\retval none
*/
void gd_eval_key_init(key_typedef_enum keynum, keymode_typedef_enum key_mode)
{
ECLIC_ClearPendingIRQ(KEY_IRQn[keynum]);
/* enable the key clock */
rcu_periph_clock_enable(KEY_CLK[keynum]);
rcu_periph_clock_enable(RCU_AF);
/* configure button pin as input */
gpio_init(KEY_PORT[keynum], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, KEY_PIN[keynum]);
if (key_mode == KEY_MODE_EXTI) {
/* enable and set key EXTI interrupt to the lowest priority */
ECLIC_EnableIRQ(KEY_IRQn[keynum]);
ECLIC_SetLevelIRQ(KEY_IRQn[keynum],1);
ECLIC_SetPriorityIRQ(KEY_IRQn[keynum],1);
/* connect key EXTI line to key GPIO pin */
gpio_exti_source_select(KEY_PORT_SOURCE[keynum], KEY_PIN_SOURCE[keynum]);
/* configure key EXTI line */
exti_init(KEY_EXTI_LINE[keynum], EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(KEY_EXTI_LINE[keynum]);
}
}
/*!
\brief return the selected key state
\param[in] key: specify the key to be checked
\arg KEY_A: wakeup key
\arg KEY_B: tamper key
\arg KEY_C: user key
\arg KEY_D: user key
\arg KEY_CET: user key
\param[out] none
\retval the key's GPIO pin value
*/
uint8_t gd_eval_key_state_get(key_typedef_enum key)
{
return gpio_input_bit_get(KEY_PORT[key], KEY_PIN[key]);
}
/*!
\brief configure COM port
\param[in] com: COM on the board
\arg GD32_COM0: COM0 on the board
\arg GD32_COM1: COM1 on the board
\param[out] none
\retval none
*/
void gd_com_init(uint32_t com)
{
uint32_t com_id = 0U;
if(GD32_COM0 == com){
com_id = 0U;
}else if(GD32_COM1 == com){
com_id = 1U;
}
/* enable GPIO clock */
rcu_periph_clock_enable(COM_GPIO_CLK[com_id]);
/* enable USART clock */
rcu_periph_clock_enable(COM_CLK[com_id]);
/* connect port to USARTx_Tx */
gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, COM_TX_PIN[com_id]);
/* connect port to USARTx_Rx */
gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, COM_RX_PIN[com_id]);
/* USART configure */
usart_deinit(com);
usart_baudrate_set(com, 115200U);
usart_word_length_set(com, USART_WL_8BIT);
usart_stop_bit_set(com, USART_STB_1BIT);
usart_parity_config(com, USART_PM_NONE);
usart_hardware_flow_rts_config(com, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(com, USART_CTS_DISABLE);
usart_receive_config(com, USART_RECEIVE_ENABLE);
usart_transmit_config(com, USART_TRANSMIT_ENABLE);
usart_enable(com);
}
@@ -0,0 +1,47 @@
adapter_khz 1000
reset_config srst_only
adapter_nsrst_assert_width 100
interface cmsis-dap
transport select jtag
autoexit true
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1e200a6d
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 20480 -work-area-backup 0
# Work-area is a space in RAM used for flash programming
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x5000
}
# Allow overriding the Flash bank size
if { [info exists FLASH_SIZE] } {
set _FLASH_SIZE $FLASH_SIZE
} else {
# autodetect size
set _FLASH_SIZE 0
}
# flash size will be probed
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME gd32vf103 0x08000000 0 0 0 $_TARGETNAME
# Expose Nuclei self-defined CSRS range 770-800,835-850,1984-2032,2064-2070
# See https://github.com/riscv/riscv-gnu-toolchain/issues/319#issuecomment-358397306
# Then user can view the csr register value in gdb using: info reg csr775 for CSR MTVT(0x307)
riscv expose_csrs 770-800,835-850,1984-2032,2064-2070
riscv set_reset_timeout_sec 1
init
halt
@@ -0,0 +1,121 @@
/*!
\file gd32vf103c_start.h
\brief definitions for GD32VF103C_START's leds, keys and COM ports hardware resources
\version 2019-06-05, 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 GD32VF103C_RVSTART_H
#define GD32VF103C_RVSTART_H
#ifdef __cplusplus
extern "C" {
#endif
#include "nuclei_sdk_soc.h"
/* exported types */
typedef enum
{
LED1 = 0,
LED2 = 1,
LED3 = 2,
}led_typedef_enum;
typedef enum
{
KEY_WAKEUP = 0,
}key_typedef_enum;
typedef enum
{
KEY_MODE_GPIO = 0,
KEY_MODE_EXTI = 1
}keymode_typedef_enum;
/* rvstar board low layer led */
#define LEDn 3U
#define LEDG_PIN GPIO_PIN_1
#define LEDG_GPIO_PORT GPIOA
#define LEDG_GPIO_CLK RCU_GPIOA
#define LEDB_PIN GPIO_PIN_3
#define LEDB_GPIO_PORT GPIOA
#define LEDB_GPIO_CLK RCU_GPIOA
#define LEDR_PIN GPIO_PIN_2
#define LEDR_GPIO_PORT GPIOA
#define LEDR_GPIO_CLK RCU_GPIOA
/* rvstar board UART com port */
#define GD32_COM0 UART4
#define GD32_COM_CLK RCU_UART4
#define GD32_COM_TX_PIN GPIO_PIN_12
#define GD32_COM_RX_PIN GPIO_PIN_2
#define GD32_COM_TX_GPIO_PORT GPIOC
#define GD32_COM_RX_GPIO_PORT GPIOD
#define GD32_COM_TX_GPIO_CLK RCU_GPIOC
#define GD32_COM_RX_GPIO_CLK RCU_GPIOD
/* rvstar board low layer button */
#define KEYn (1U)
/* wakeup push-button */
#define WAKEUP_KEY_PIN GPIO_PIN_0
#define WAKEUP_KEY_GPIO_PORT GPIOA
#define WAKEUP_KEY_GPIO_CLK RCU_GPIOA
#define WAKEUP_KEY_EXTI_LINE EXTI_0
#define WAKEUP_KEY_EXTI_PORT_SOURCE GPIO_PORT_SOURCE_GPIOA
#define WAKEUP_KEY_EXTI_PIN_SOURCE GPIO_PIN_SOURCE_0
#define WAKEUP_KEY_EXTI_IRQn EXTI0_IRQn
/* function declarations */
/* configure led GPIO */
void gd_rvstar_led_init(led_typedef_enum lednum);
/* turn on selected led */
void gd_rvstar_led_on(led_typedef_enum lednum);
/* turn off selected led */
void gd_rvstar_led_off(led_typedef_enum lednum);
/* toggle the selected led */
void gd_rvstar_led_toggle(led_typedef_enum lednum);
/* configure key */
void gd_rvstar_key_init(key_typedef_enum keynum, keymode_typedef_enum keymode);
/* return the selected key state */
uint8_t gd_rvstar_key_state_get(key_typedef_enum keynum);
/* configure COM port */
void gd_com_init(uint32_t usart_periph);
#ifdef __cplusplus
}
#endif
#endif /* GD32VF103V_RVSTART_H */
@@ -0,0 +1,18 @@
// See LICENSE for license details.
#ifndef _NUCLEI_SDK_HAL_H
#define _NUCLEI_SDK_HAL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "gd32vf103v_rvstar.h"
#ifndef NUCLEI_BANNER
#define NUCLEI_BANNER 1
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,270 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file gcc_Device.ld
* @brief GNU Linker Script for gd32vf103 based device
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
/*********** Use Configuration Wizard in Context Menu *************************/
OUTPUT_ARCH( "riscv" )
/********************* Flash Configuration ************************************
* <h> Flash Configuration
* <o0> Flash Base Address <0x0-0xFFFFFFFF:8>
* <o1> Flash Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__ROM_BASE = 0x08000000;
__ROM_SIZE = 0x00020000;
/*--------------------- ILM RAM Configuration ---------------------------
* <h> ILM RAM Configuration
* <o0> ILM RAM Base Address <0x0-0xFFFFFFFF:8>
* <o1> ILM RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__ILM_RAM_BASE = 0x80000000;
__ILM_RAM_SIZE = 0x00010000;
/*--------------------- Embedded RAM Configuration ---------------------------
* <h> RAM Configuration
* <o0> RAM Base Address <0x0-0xFFFFFFFF:8>
* <o1> RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__RAM_BASE = 0x20000000;
__RAM_SIZE = 0x00005000;
/********************* Stack / Heap Configuration ****************************
* <h> Stack / Heap Configuration
* <o0> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
* <o1> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__STACK_SIZE = 0x00000800;
__HEAP_SIZE = 0x00000800;
/**************************** end of configuration section ********************/
/* Define base address and length of flash and ram */
MEMORY
{
flash (rxai!w) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
ram (wxa!ri) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH,ILM and RAM.
* It references following symbols, which must be defined in code:
* _Start : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* _ilm_lma
* _ilm
* __etext
* _etext
* etext
* _eilm
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* _data_lma
* _edata
* edata
* __data_end__
* __bss_start
* __fbss
* _end
* end
* __heap_end
* __StackLimit
* __StackTop
* __STACK_SIZE
*/
/* Define entry label of program */
ENTRY(_start)
SECTIONS
{
__STACK_SIZE = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2K;
.init :
{
/* vector table locate at flash */
*(.vtable)
KEEP (*(SORT_NONE(.init)))
} >flash AT>flash
.ilalign :
{
. = ALIGN(4);
/* Create a section label as _ilm_lma which located at flash */
PROVIDE( _ilm_lma = . );
} >flash AT>flash
.ialign :
{
/* Create a section label as _ilm which located at flash */
PROVIDE( _ilm = . );
} >flash AT>flash
/* Code section located at flash */
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >flash AT>flash
.rodata : ALIGN(4)
{
. = ALIGN(4);
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >flash AT>flash
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >flash AT>flash
. = ALIGN(4);
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
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
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >flash AT>flash
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>flash
/* Define data section virtual address is ram and physical address is flash */
.data :
{
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
} >ram AT>flash
. = ALIGN(4);
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.bss :
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >ram AT>ram
. = ALIGN(8);
PROVIDE( _end = . );
PROVIDE( end = . );
/* Define stack and head location at ram */
.stack ORIGIN(ram) + LENGTH(ram) - __STACK_SIZE :
{
PROVIDE( _heap_end = . );
. = __STACK_SIZE;
PROVIDE( _sp = . );
} >ram AT>ram
}
@@ -0,0 +1,191 @@
/*!
* \file gd32vf103c_start.c
* \brief firmware functions to manage leds, keys, COM ports
*
* \version 2020-02-05, V1.0.0, rvstar board functions 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 "gd32vf103v_rvstar.h"
/* private variables */
static const uint32_t GPIO_PORT[LEDn] = {LEDG_GPIO_PORT,LEDB_GPIO_PORT,LEDR_GPIO_PORT};
static const uint32_t GPIO_PIN[LEDn] = {LEDG_PIN,LEDB_PIN,LEDR_PIN};
static const rcu_periph_enum GPIO_CLK[LEDn] = {LEDG_GPIO_CLK,LEDB_GPIO_CLK,LEDR_GPIO_CLK};
static const uint32_t KEY_PORT[KEYn] = {WAKEUP_KEY_GPIO_PORT};
static const uint32_t KEY_PIN[KEYn] = {WAKEUP_KEY_PIN};
static const rcu_periph_enum KEY_CLK[KEYn] = {WAKEUP_KEY_GPIO_CLK};
static const exti_line_enum KEY_EXTI_LINE[KEYn] = {WAKEUP_KEY_EXTI_LINE};
static const uint8_t KEY_PORT_SOURCE[KEYn] = {WAKEUP_KEY_EXTI_PORT_SOURCE};
static const uint8_t KEY_PIN_SOURCE[KEYn] = {WAKEUP_KEY_EXTI_PIN_SOURCE};
static const uint8_t KEY_IRQn[KEYn] = {WAKEUP_KEY_EXTI_IRQn};
/* eval board low layer private functions */
/*!
* \brief configure led GPIO
* \param[in] lednum: specify the led to be configured
* \arg LED1
* \param[out] none
* \retval none
*/
void gd_rvstar_led_init(led_typedef_enum lednum)
{
/* enable the led clock */
rcu_periph_clock_enable(GPIO_CLK[lednum]);
/* configure led GPIO port */
gpio_init(GPIO_PORT[lednum], GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN[lednum]);
GPIO_BOP(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}
/*!
* \brief turn on selected led
* \param[in] lednum: specify the led to be turned on
* \arg LED1
* \param[out] none
* \retval none
*/
void gd_rvstar_led_on(led_typedef_enum lednum)
{
GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}
/*!
* \brief turn off selected led
* \param[in] lednum: specify the led to be turned off
* \arg LED1
* \param[out] none
* \retval none
*/
void gd_rvstar_led_off(led_typedef_enum lednum)
{
GPIO_BOP(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}
/*!
* \brief toggle selected led
* \param[in] lednum: specify the led to be toggled
* \arg LED1
* \param[out] none
* \retval none
*/
void gd_rvstar_led_toggle(led_typedef_enum lednum)
{
gpio_bit_write(GPIO_PORT[lednum], GPIO_PIN[lednum],
(bit_status)(1-gpio_input_bit_get(GPIO_PORT[lednum], GPIO_PIN[lednum])));
}
/*!
* \brief configure key
* \param[in] keynum: specify the key to be configured
* \arg KEY_WAKEUP: wakeup key
* \param[in] keymode: specify button mode
* \arg KEY_MODE_GPIO: key will be used as simple IO
* \arg KEY_MODE_EXTI: key will be connected to EXTI line with interrupt
* \param[out] none
* \retval none
*/
void gd_rvstar_key_init(key_typedef_enum keynum, keymode_typedef_enum keymode)
{
/* enable the key clock */
rcu_periph_clock_enable(KEY_CLK[keynum]);
rcu_periph_clock_enable(RCU_AF);
/* configure button pin as input */
gpio_init(KEY_PORT[keynum], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, KEY_PIN[keynum]);
if (keymode == KEY_MODE_EXTI) {
/* enable and set key EXTI interrupt to the lowest priority */
ECLIC_EnableIRQ(KEY_IRQn[keynum]);
ECLIC_SetLevelIRQ(KEY_IRQn[keynum],1);
ECLIC_SetPriorityIRQ(KEY_IRQn[keynum],1);
/* connect key EXTI line to key GPIO pin */
gpio_exti_source_select(KEY_PORT_SOURCE[keynum], KEY_PIN_SOURCE[keynum]);
/* configure key EXTI line */
exti_init(KEY_EXTI_LINE[keynum], EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(KEY_EXTI_LINE[keynum]);
}
}
/*!
* \brief return the selected key state
* \param[in] keynum: specify the key to be checked
* \arg KEY_WAKEUP: wakeup key
* \param[out] none
* \retval the key's GPIO pin value
*/
uint8_t gd_rvstar_key_state_get(key_typedef_enum keynum)
{
return gpio_input_bit_get(KEY_PORT[keynum], KEY_PIN[keynum]);
}
/*!
* \brief configure COM port
* \param[in] com: COM on the board
* \arg GD32_COM0: COM0 on the board
* \param[out] none
* \retval none
*/
void gd_com_init(uint32_t usart_periph)
{
/* enable GPIO TX and RX clock */
rcu_periph_clock_enable(GD32_COM_TX_GPIO_CLK);
rcu_periph_clock_enable(GD32_COM_RX_GPIO_CLK);
/* enable USART clock */
rcu_periph_clock_enable(GD32_COM_CLK);
/* connect port to USARTx_Tx */
gpio_init(GD32_COM_TX_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GD32_COM_TX_PIN);
/* connect port to USARTx_Rx */
gpio_init(GD32_COM_RX_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GD32_COM_RX_PIN);
/* USART configure */
usart_deinit(usart_periph);
usart_baudrate_set(usart_periph, 115200U);
usart_word_length_set(usart_periph, USART_WL_8BIT);
usart_stop_bit_set(usart_periph, USART_STB_1BIT);
usart_parity_config(usart_periph, USART_PM_NONE);
usart_hardware_flow_rts_config(usart_periph, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(usart_periph, USART_CTS_DISABLE);
usart_receive_config(usart_periph, USART_RECEIVE_ENABLE);
usart_transmit_config(usart_periph, USART_TRANSMIT_ENABLE);
usart_enable(usart_periph);
}
@@ -0,0 +1,40 @@
adapter_khz 10000
reset_config srst_only
adapter_nsrst_assert_width 100
interface ftdi
ftdi_device_desc "Dual RS232-HS"
ftdi_vid_pid 0x0403 0x6010
ftdi_layout_init 0x0008 0x001b
ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020
transport select jtag
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1e200a6d
# Work-area is a space in RAM used for flash programming
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x5000
}
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME gd32vf103 0x08000000 0 0 0 $_TARGETNAME
# Expose Nuclei self-defined CSRS range 770-800,835-850,1984-2032,2064-2070
# See https://github.com/riscv/riscv-gnu-toolchain/issues/319#issuecomment-358397306
# Then user can view the csr register value in gdb using: info reg csr775 for CSR MTVT(0x307)
riscv expose_csrs 770-800,835-850,1984-2032,2064-2070
riscv set_reset_timeout_sec 1
init
halt
@@ -0,0 +1,117 @@
/*!
\file drv_usb_core.h
\brief USB core low level driver header file
\version 2019-6-5, V1.0.0, firmware for GD32 USBFS&USBHS
*/
/*
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 __DRV_USB_CORE_H
#define __DRV_USB_CORE_H
#include "drv_usb_regs.h"
#include "usb_ch9_std.h"
#define USB_FS_EP0_MAX_LEN 64U /* maximum packet size of EndPoint0 */
#define HC_MAX_PACKET_COUNT 140U /* maximum packet count */
#define EP_ID(x) ((uint8_t)((x) & 0x7FU)) /* endpoint number */
#define EP_DIR(x) ((uint8_t)((x) >> 7)) /* endpoint direction */
enum _usb_eptype {
USB_EPTYPE_CTRL = 0U, /*!< control endpoint type */
USB_EPTYPE_ISOC = 1U, /*!< isochronous endpoint type */
USB_EPTYPE_BULK = 2U, /*!< bulk endpoint type */
USB_EPTYPE_INTR = 3U, /*!< interrupt endpoint type */
USB_EPTYPE_MASK = 3U, /*!< endpoint type mask */
};
typedef enum
{
USB_OTG_OK = 0, /*!< USB OTG status OK*/
USB_OTG_FAIL /*!< USB OTG status fail*/
} usb_otg_status;
typedef enum
{
USB_OK = 0, /*!< USB status OK*/
USB_FAIL /*!< USB status fail*/
} usb_status;
typedef enum
{
USB_USE_FIFO, /*!< USB use FIFO transfer mode */
USB_USE_DMA /*!< USB use DMA transfer mode */
} usb_transfer_mode;
typedef struct
{
uint8_t core_enum; /*!< USB core type */
uint8_t core_speed; /*!< USB core speed */
uint8_t num_pipe; /*!< USB host channel numbers */
uint8_t num_ep; /*!< USB device endpoint numbers */
uint8_t transfer_mode; /*!< USB transfer mode */
uint8_t phy_itf; /*!< USB core PHY interface */
uint8_t sof_enable; /*!< USB SOF output */
uint8_t low_power; /*!< USB low power */
} usb_core_basic;
/* function declarations */
/* config core capabilities */
usb_status usb_basic_init (usb_core_basic *usb_basic,
usb_core_regs *usb_regs,
usb_core_enum usb_core);
/*initializes the USB controller registers and prepares the core device mode or host mode operation*/
usb_status usb_core_init (usb_core_basic usb_basic, usb_core_regs *usb_regs);
/* read a packet from the Rx FIFO associated with the endpoint */
void *usb_rxfifo_read (usb_core_regs *core_regs, uint8_t *dest_buf, uint16_t byte_count);
/* write a packet into the Tx FIFO associated with the endpoint */
usb_status usb_txfifo_write (usb_core_regs *usb_regs,
uint8_t *src_buf,
uint8_t fifo_num,
uint16_t byte_count);
/* flush a Tx FIFO or all Tx FIFOs */
usb_status usb_txfifo_flush (usb_core_regs *usb_regs, uint8_t fifo_num);
/* flush the entire Rx FIFO */
usb_status usb_rxfifo_flush (usb_core_regs *usb_regs);
/* get the global interrupts */
static inline uint32_t usb_coreintr_get(usb_core_regs *usb_regs)
{
return usb_regs->gr->GINTEN & usb_regs->gr->GINTF;
}
#endif /* __DRV_USB_CORE_H */
@@ -0,0 +1,217 @@
/*!
\file drv_usb_dev.h
\brief USB device low level driver header file
\version 2019-6-5, V1.0.0, firmware for GD32 USBFS&USBHS
*/
/*
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 __DRV_USB_DEV_H
#define __DRV_USB_DEV_H
#include "drv_usb_core.h"
enum usb_ctl_status {
USB_CTL_IDLE = 0U, /*!< USB control transfer idle state */
USB_CTL_DATA_IN, /*!< USB control transfer data in state */
USB_CTL_LAST_DATA_IN, /*!< USB control transfer last data in state */
USB_CTL_DATA_OUT, /*!< USB control transfer data out state */
USB_CTL_LAST_DATA_OUT, /*!< USB control transfer last data out state */
USB_CTL_STATUS_IN, /*!< USB control transfer status in state*/
USB_CTL_STATUS_OUT /*!< USB control transfer status out state */
};
#define EP_IN(x) ((uint8_t)(0x80U | (x))) /*!< device IN endpoint */
#define EP_OUT(x) ((uint8_t)(x)) /*!< device OUT endpoint */
/* USB descriptor */
typedef struct _usb_desc {
uint8_t *dev_desc; /*!< device descriptor */
uint8_t *config_desc; /*!< config descriptor */
uint8_t *bos_desc; /*!< BOS descriptor */
void* const *strings; /*!< string descriptor */
} usb_desc;
/* USB power management */
typedef struct _usb_pm {
uint8_t power_mode; /*!< power mode */
uint8_t power_low; /*!< power low */
uint8_t dev_remote_wakeup; /*!< remote wakeup */
uint8_t remote_wakeup_on; /*!< remote wakeup on */
} usb_pm;
/* USB control information */
typedef struct _usb_control {
usb_req req; /*!< USB standard device request */
uint8_t ctl_state; /*!< USB control transfer state */
uint8_t ctl_zlp; /*!< zero lenth package */
} usb_control;
typedef struct
{
struct {
uint8_t num: 4; /*!< the endpoint number.it can be from 0 to 6 */
uint8_t pad: 3; /*!< padding between number and direction */
uint8_t dir: 1; /*!< the endpoint direction */
} ep_addr;
uint8_t ep_type; /*!< USB endpoint type */
uint8_t ep_stall; /*!< USB endpoint stall status */
uint8_t frame_num; /*!< number of frame */
uint16_t max_len; /*!< Maximum packet lenth */
/* transaction level variables */
uint8_t *xfer_buf; /*!< transmit buffer */
uint32_t xfer_len; /*!< transmit buffer length */
uint32_t xfer_count; /*!< transmit buffer count */
uint32_t remain_len; /*!< remain packet lenth */
uint32_t dma_addr; /*!< DMA address */
} usb_transc;
typedef struct _usb_core_driver usb_dev;
typedef struct _usb_class_core
{
uint8_t command; /*!< device class request command */
uint8_t alter_set; /*!< alternative set */
uint8_t (*init) (usb_dev *udev, uint8_t config_index); /*!< initialize handler */
uint8_t (*deinit) (usb_dev *udev, uint8_t config_index); /*!< de-initialize handler */
uint8_t (*req_proc) (usb_dev *udev, usb_req *req); /*!< device request handler */
uint8_t (*data_in) (usb_dev *udev, uint8_t ep_num); /*!< device data in handler */
uint8_t (*data_out) (usb_dev *udev, uint8_t ep_num); /*!< device data out handler */
uint8_t (*SOF) (usb_dev *udev); /*!< Start of frame handler */
uint8_t (*incomplete_isoc_in) (usb_dev *udev); /*!< Incomplete synchronization IN transfer handler */
uint8_t (*incomplete_isoc_out) (usb_dev *udev); /*!< Incomplete synchronization OUT transfer handler */
} usb_class_core;
typedef struct _usb_perp_dev
{
uint8_t config; /*!< configuration */
uint8_t dev_addr; /*!< device address */
__IO uint8_t cur_status; /*!< current status */
__IO uint8_t backup_status; /*!< backup status */
usb_transc transc_in[USBFS_MAX_TX_FIFOS]; /*!< endpoint IN transaction */
usb_transc transc_out[USBFS_MAX_TX_FIFOS]; /*!< endpoint OUT transaction */
usb_pm pm; /*!< power management */
usb_desc desc; /*!< USB descriptors */
usb_control control; /*!< USB control information */
usb_class_core *class_core; /*!< class driver */
} usb_perp_dev;
typedef struct _usb_core_driver
{
usb_core_basic bp; /*!< USB basic parameters */
usb_core_regs regs; /*!< USB registers */
usb_perp_dev dev; /*!< USB peripheral device */
} usb_core_driver;
/* function declarations */
/* initialize USB core registers for device mode */
usb_status usb_devcore_init (usb_core_driver *udev);
/* enable the USB device mode interrupts */
usb_status usb_devint_enable (usb_core_driver *udev);
/* active the usb transaction */
usb_status usb_transc_active (usb_core_driver *udev, usb_transc *transc);
/* deactive the usb transaction */
usb_status usb_transc_deactivate (usb_core_driver *udev, usb_transc *transc);
/* configure usb transaction to start IN transfer */
usb_status usb_transc_inxfer (usb_core_driver *udev, usb_transc *transc);
/* configure usb transaction to start OUT transfer */
usb_status usb_transc_outxfer (usb_core_driver *udev, usb_transc *transc);
/* set the usb transaction STALL status */
usb_status usb_transc_stall (usb_core_driver *udev, usb_transc *transc);
/* clear the usb transaction STALL status */
usb_status usb_transc_clrstall (usb_core_driver *udev, usb_transc *transc);
/* read device all OUT endpoint interrupt register */
uint32_t usb_oepintnum_read (usb_core_driver *udev);
/* read device OUT endpoint interrupt flag register */
uint32_t usb_oepintr_read (usb_core_driver *udev, uint8_t ep_num);
/* read device all IN endpoint interrupt register */
uint32_t usb_iepintnum_read (usb_core_driver *udev);
/* read device IN endpoint interrupt flag register */
uint32_t usb_iepintr_read (usb_core_driver *udev, uint8_t ep_num);
/* config the USB device to be disconnected */
void usb_dev_disconnect (usb_core_driver *udev);
/* config the USB device to be connected */
void usb_dev_connect (usb_core_driver *udev);
/* set the USB device address */
void usb_devaddr_set (usb_core_driver *pudev, uint8_t dev_addr);
/* configures OUT endpoint 0 to receive SETUP packets */
void usb_ctlep_startout (usb_core_driver *udev);
/* active remote wakeup signalling */
void usb_rwkup_active (usb_core_driver *udev);
/* reset remote wakeup signalling */
void usb_rwkup_reset (usb_core_driver *udev);
/* set remote wakeup signalling */
void usb_rwkup_set (usb_core_driver *udev);
/* active USB core clock */
void usb_clock_active (usb_core_driver *udev);
/* usb device suspend */
void usb_dev_suspend (usb_core_driver *udev);
/* stop the device and clean up fifos */
void usb_dev_stop (usb_core_driver *udev);
#endif /* __DRV_USB_DEV_H */
@@ -0,0 +1,175 @@
/*!
\file drv_usb_host.h
\brief USB host mode low level driver header file
\version 2019-6-5, V1.0.0, firmware for GD32 USBFS&USBHS
*/
/*
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 __DRV_USB_HOST_H
#define __DRV_USB_HOST_H
#include "drv_usb_regs.h"
#include "usb_ch9_std.h"
#include "drv_usb_core.h"
typedef enum _usb_pipe_status
{
PIPE_IDLE = 0U,
PIPE_XF,
PIPE_HALTED,
PIPE_NAK,
PIPE_NYET,
PIPE_STALL,
PIPE_TRACERR,
PIPE_BBERR,
PIPE_REQOVR,
PIPE_DTGERR,
} usb_pipe_staus;
typedef enum _usb_pipe_mode
{
PIPE_PERIOD = 0U,
PIPE_NON_PERIOD = 1U
} usb_pipe_mode;
typedef enum _usb_urb_state
{
URB_IDLE = 0U,
URB_DONE,
URB_NOTREADY,
URB_ERROR,
URB_STALL
} usb_urb_state;
typedef struct _usb_pipe
{
uint8_t in_used;
uint8_t dev_addr;
uint32_t dev_speed;
struct {
uint8_t num;
uint8_t dir;
uint8_t type;
uint16_t mps;
} ep;
uint8_t ping;
uint32_t DPID;
uint8_t *xfer_buf;
uint32_t xfer_len;
uint32_t xfer_count;
uint8_t data_toggle_in;
uint8_t data_toggle_out;
__IO uint32_t err_count;
__IO usb_pipe_staus pp_status;
__IO usb_urb_state urb_state;
} usb_pipe;
typedef struct _usb_host_drv
{
uint8_t rx_buf[512U];
__IO uint32_t connect_status;
__IO uint32_t port_enabled;
__IO uint32_t backup_xfercount[USBFS_MAX_TX_FIFOS];
usb_pipe pipe[USBFS_MAX_TX_FIFOS];
} usb_host_drv;
typedef struct _usb_core_driver
{
usb_core_basic bp;
usb_core_regs regs;
usb_host_drv host;
} usb_core_driver;
/* initializes USB core for host mode */
usb_status usb_host_init (usb_core_driver *pudev);
/* initialize host pipe */
usb_status usb_pipe_init (usb_core_driver *pudev, uint8_t pipe_num);
/* prepare host pipe for transferring packets */
usb_status usb_pipe_xfer (usb_core_driver *pudev, uint8_t pipe_num);
/* halt host pipe */
usb_status usb_pipe_halt (usb_core_driver *pudev, uint8_t pipe_num);
/* configure host pipe to do ping operation */
usb_status usb_pipe_ping (usb_core_driver *pudev, uint8_t pipe_num);
/* reset host port */
uint32_t usb_port_reset (usb_core_driver *pudev);
/* control the VBUS to power */
void usb_portvbus_switch (usb_core_driver *pudev, uint8_t state);
/* stop the USB host and clean up FIFO */
void usb_host_stop (usb_core_driver *pudev);
//__STATIC_INLINE uint8_t usb_frame_even (usb_core_driver *pudev)
uint32_t usb_frame_even (usb_core_driver *pudev);
//{
// return !(pudev->regs.hr->HFINFR & 0x01U);
//}
//__STATIC_INLINE void usb_phyclock_config (usb_core_driver *pudev, uint8_t clock)
void usb_phyclock_config (usb_core_driver *pudev, uint8_t clock) ;
//{
//pudev->regs.hr->HCTL &= ~HCTL_CLKSEL;
// pudev->regs.hr->HCTL |= clock;
//}
uint32_t usb_port_read (usb_core_driver *pudev);
//inline uint32_t usb_port_read (usb_core_driver *pudev)
//{
// return *pudev->regs.HPCS & ~(HPCS_PE | HPCS_PCD | HPCS_PEDC);
//}
uint32_t usb_curspeed_get (usb_core_driver *pudev);
//inline uint32_t usb_curspeed_get (usb_core_driver *pudev)
//{
// return *pudev->regs.HPCS & HPCS_PS;
//}
//__STATIC_INLINE uint32_t usb_curframe_get (usb_core_driver *pudev)
uint32_t usb_curframe_get (usb_core_driver *pudev);
//{
// return (pudev->regs.hr->HFINFR & 0xFFFFU);
//}
#endif /* __DRV_USB_HOST_H */

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