Add makefile based project for Nuclei ddr200T board

Setup tools for compilment and entering GCC folder under riscv_nuclei_demo_soc_gcc
Using "make all" command to compile project
Using "make clean" command to clean project
Using "make debug" command to debug project
Using "make upload" command to upload project
OS configurations is under "OS_CONFIG" folder
Most information can be found in README.md

Signed-off-by: linzewen <linzewen@nucleisys.com>
This commit is contained in:
linzewen 2021-04-06 20:16:26 -07:00
parent 6c8da43bc9
commit 746d56b7b9
55 changed files with 4555 additions and 0 deletions

View File

@ -0,0 +1,9 @@
# ignore openocd logfile and build folder
targets/*/GCC/build/
*.log
*.lst
*.bin
*.dasm
*.elf
*.hex
*.map

View File

@ -0,0 +1,222 @@
# ------------------------------------------------
# Generic Makefile (based on gcc)
#
# ChangeLog :
# 2021-04-02 - first version
# ------------------------------------------------
######################################
# target
######################################
TARGET = Nuclei-demo-soc
######################################
# building variables
######################################
# debug build?
DEBUG = 1
# optimization
OPT = -O2
#######################################
# paths
#######################################
# Build path
BUILD_DIR = build
#######################################
# Base directory
#######################################
# LiteOS top path
LITEOSTOPDIR := ../../../
######################################
# source
######################################
# C sources
C_SOURCES = \
$(wildcard ../Src/*.c) \
$(wildcard ../SoC/hbird/Common/Source/*.c) \
$(wildcard ../SoC/hbird/Common/Source/Drivers/*.c) \
$(wildcard ../SoC/hbird/Common/Source/Stubs/*.c)
# ASM sources
ASMS_SOURCES = \
$(wildcard ../SoC/hbird/Common/Source/GCC/*.S)
#######################################
# binaries
#######################################
PREFIX = riscv-nuclei-elf-
# The gcc compiler bin path can be either defined in make command via NUCLEI_TOOL_ROOT variable (> make NUCLEI_TOOL_ROOT=xxx)
# either it can be added to the PATH environment variable.
NUCLEI_RISCV_GCC_ROOT ?= $(NUCLEI_TOOL_ROOT)/gcc
NUCLEI_OPENOCD_ROOT ?= $(NUCLEI_TOOL_ROOT)/openocd
NUCLEI_TOOL_ROOT_EXIST = 0
ifneq ($(wildcard $(NUCLEI_RISCV_GCC_ROOT)),)
ifneq ($(wildcard $(NUCLEI_OPENOCD_ROOT)),)
NUCLEI_TOOL_ROOT_EXIST = 1
endif
endif
ifeq ($(NUCLEI_TOOL_ROOT_EXIST),1)
CC = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)gcc
AS = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)gcc -x assembler-with-cpp
CP = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)objcopy
DP = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)objdump
SZ = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)size
GDB = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)gdb
OPENOCD := $(NUCLEI_OPENOCD_ROOT)/bin/openocd
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
DP = $(PREFIX)objdump
SZ = $(PREFIX)size
GDB = $(PREFIX)gdb
OPENOCD := openocd
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
ECHO := echo
OPENOCD_CFG := openocd_hbird.cfg
#######################################
# CFLAGS
#######################################
#risc-v arch & abi
CORE_ARCH_ABI = -march=rv32imafc -mabi=ilp32f
#other flags
OTHER_FLAGS += -g -mcmodel=medany -fno-common
# macros for gcc
# AS defines
AS_DEFS = -DDOWNLOAD_MODE=DOWNLOAD_MODE_ILM
# C defines
C_DEFS = -DDOWNLOAD_MODE=DOWNLOAD_MODE_ILM
# AS includes
AS_INCLUDES =
# C includes
C_INCLUDES = \
-I../OS_CONFIG \
-I../Src \
-I../SoC/hbird/Board/hbird_eval/Include \
-I../SoC/hbird/Common/Include \
-I../SoC/hbird/Common/Source/Stubs
# compile gcc flags
ASFLAGS = $(AS_DEFS) $(OPT) $(CORE_ARCH_ABI) $(OTHER_FLAGS) $(AS_INCLUDES) -Wall -fdata-sections -ffunction-sections
CFLAGS = $(C_DEFS) $(C_INCLUDES) $(OPT) $(CORE_ARCH_ABI) $(OTHER_FLAGS) -Wall -fdata-sections -ffunction-sections
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
# Set your GDB port using variable GDB_PORT
GDB_PORT ?= 3333
## Makefile Variable GDBREMOTE
## You can change GDBREMOTE to other gdb remotes
## eg. if you have started openocd server with (bindto 0.0.0.0 defined in openocd.cfg)
## make sure your machine can connect to remote machine
## in remote machine(ipaddr 192.168.43.199, port 3333) which connect the hardware board,
## then you can change the GDBREMOTE to 192.168.43.199:3333
## GDBREMOTE ?= 192.168.43.199:3333
GDBREMOTE ?= | $(OPENOCD) --pipe -f $(OPENOCD_CFG)
GDB_UPLOAD_ARGS ?= --batch
GDB_UPLOAD_CMDS += -ex "monitor halt"
GDB_UPLOAD_CMDS += -ex "monitor flash protect 0 0 last off"
GDB_UPLOAD_CMDS += -ex "load"
GDB_UPLOAD_CMDS += -ex "monitor resume"
GDB_UPLOAD_CMDS += -ex "quit"
OPENOCD_PORT_ARGS = -c "gdb_port $(GDB_PORT)"
OPENOCD_ARGS += -f $(OPENOCD_CFG)
GDB_CMDS += -ex "set remotetimeout 240"
GDB_CMDS += -ex "target extended-remote localhost:$(GDB_PORT)"
#######################################
# LDFLAGS
#######################################
# link script
LDSCRIPT = gcc_hbird_ilm.ld
# libraries
LIBS = -lm
LIBDIR =
LDFLAGS = $(CORE_ARCH_ABI) $(OTHER_FLAGS) -specs=nano.specs -specs=nosys.specs -T $(LDSCRIPT) $(LIBDIR) $(LIBS) -nostartfiles -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).dasm $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
include liteos_m.mk
#######################################
# build the application
#######################################
# list of objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.S=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile $(LDSCRIPT)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
$(SZ) $@
$(BUILD_DIR)/%.dasm: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(DP) -D -S $< > $@
$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(HEX) $< $@
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(BIN) $< $@
$(BUILD_DIR):
mkdir $@
#######################################
# clean up
#######################################
clean:
-rm -fR $(BUILD_DIR)
#######################################
# upload & debug
#######################################
upload: $(BUILD_DIR)/$(TARGET).elf
@$(ECHO) "Download and run $<"
$(GDB) $< -ex "set remotetimeout 240" \
-ex "target remote $(GDBREMOTE)" \
$(GDB_UPLOAD_ARGS) $(GDB_UPLOAD_CMDS)
debug: $(BUILD_DIR)/$(TARGET).elf
@$(ECHO) "Download and debug $<"
$(GDB) $< -ex "set remotetimeout 240" \
-ex "target remote $(GDBREMOTE)"
#######################################
# dependencies
#######################################
-include $(wildcard $(BUILD_DIR)/*.d)
# *** EOF ***

View File

@ -0,0 +1,222 @@
/*
* 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_hbird_ilm.ld
* @brief GNU Linker Script for Nuclei N/NX based device in ilm Download Mode
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
ilm (rxai!w) : ORIGIN = 0x80000000, LENGTH = 64K
ram (wxa!ri) : ORIGIN = 0x90000000, LENGTH = 64K
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 10K;
__heap_size = DEFINED(__heap_size) ? __heap_size : 10K;
.init :
{
*(.vtable)
KEEP (*(SORT_NONE(.init)))
} >ilm AT>ilm
.ilalign :
{
. = ALIGN(4);
PROVIDE( _ilm_lma = . );
} >ilm AT>ilm
.ialign :
{
PROVIDE( _ilm = . );
} >ilm AT>ilm
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >ilm AT>ilm
.rodata : ALIGN(4)
{
. = ALIGN(4);
*(.rdata)
*(.rodata .rodata.*)
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
*(.gnu.linkonce.r.*)
} >ilm AT>ilm
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ilm AT>ilm
. = 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 = .);
} >ilm AT>ilm
.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 = .);
} >ilm AT>ilm
.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 = .);
} >ilm AT>ilm
.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))
} >ilm AT>ilm
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >ilm AT>ilm
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >ilm AT>ilm
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>ilm
.data :
{
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(4);
__osdriv_start = .;
KEEP (*(osdriv))
__osdriv_end = .;
} >ram AT>ilm
. = 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 = . );
.stack : ALIGN(0x10)
{
. = __stack_size;
PROVIDE( _sp = . );
} >ram AT>ram
PROVIDE( _end = . );
.heap : ALIGN(0x10)
{
. = __heap_size;
PROVIDE( _heap_end = . );
PROVIDE( __los_heap_addr_start__ = . );
. = __heap_size == 0 ? 0 : ORIGIN(ram) + LENGTH(ram);
PROVIDE( __los_heap_addr_end__ = . );
} >ram AT>ram
}

View File

@ -0,0 +1,38 @@
LITEOSTOPDIR := ../../../
LITEOSTOPDIR := $(realpath $(LITEOSTOPDIR))
# Common
C_SOURCES += $(wildcard $(LITEOSTOPDIR)/kernel/src/*.c) \
$(wildcard $(LITEOSTOPDIR)/kernel/src/mm/*.c) \
$(wildcard $(LITEOSTOPDIR)/components/cpup/*.c) \
$(wildcard $(LITEOSTOPDIR)/components/los_backtrace/*.c) \
$(wildcard $(LITEOSTOPDIR)/components/bounds_checking_function/src/*.c) \
$(wildcard $(LITEOSTOPDIR)/utils/*.c)
C_INCLUDES += -I$(LITEOSTOPDIR)/utils \
-I$(LITEOSTOPDIR)/kernel/include \
-I$(LITEOSTOPDIR)/components/cpup \
-I$(LITEOSTOPDIR)/components/los_backtrace \
-I$(LITEOSTOPDIR)/components/bounds_checking_function/include
# NMSIS related
C_INCLUDES += -I$(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/nmsis/Core/Include \
-I$(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/nmsis/DSP/Include \
-I$(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/nmsis/NN/Include
ASM_SOURCES += $(wildcard $(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/*.s)
ASMS_SOURCES += $(wildcard $(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/*.S)
C_SOURCES += $(wildcard $(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/*.c)
C_INCLUDES += -I. \
-I$(LITEOSTOPDIR)/kernel/arch/include \
-I$(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc
# list of ASM .S program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMS_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASMS_SOURCES)))
$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
$(CC) -c $(CFLAGS) $< -o $@

View File

@ -0,0 +1,54 @@
adapter_khz 1000
interface ftdi
ftdi_vid_pid 0x0403 0x6010
ftdi_oscan1_mode on
## bindto 0.0.0.0 can be used to cover all available interfaces.
## Uncomment bindto line to enable remote machine debug
# bindto 0.0.0.0
## If ftdi_device_desc not specified, the device description is ignored during device selection.
## So if you want to specify a dedicated FTDI device, you can select following device description:
## "Dual RS232-HS" is for HummingBird Debugger V1
## "USB <-> JTAG-DEBUGGER" is for HummingBird Debugger V2
## Uncomment one which match your device description
# ftdi_device_desc "Dual RS232-HS"
# ftdi_device_desc "USB <-> JTAG-DEBUGGER"
transport select jtag
ftdi_layout_init 0x0008 0x001b
ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020
ftdi_layout_signal TCK -data 0x0001
ftdi_layout_signal TDI -data 0x0002
ftdi_layout_signal TDO -input 0x0004
ftdi_layout_signal TMS -data 0x0008
ftdi_layout_signal JTAG_SEL -data 0x0100 -oe 0x0100
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME fespi 0x20000000 0 0 0 $_TARGETNAME
# Set the ILM space also as flash, to make sure it can be add breakpoint with hardware trigger
#flash bank onboard_ilm fespi 0x80000000 0 0 0 $_TARGETNAME
# Expose Nuclei self-defined CSRS
# 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 416-496,770-800,835-850,1227-1231,1483-1486,1984-2032,2064-2070,2370-2380,2490-2500,4032-4040
init
if {[ info exists pulse_srst]} {
ftdi_set_signal nSRST 0
ftdi_set_signal nSRST z
}
halt
# We must turn on this because otherwise the IDE version debug cannot download the program into flash
flash protect 0 0 last off

View File

@ -0,0 +1,118 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 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.
*/
/**@defgroup los_config System configuration items
* @ingroup kernel
*/
#ifndef _TARGET_CONFIG_H
#define _TARGET_CONFIG_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/*=============================================================================
System clock module configuration
=============================================================================*/
#define OS_SYS_CLOCK (8000000)
#define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL)
#define LOSCFG_BASE_CORE_TICK_HW_TIME 0
/*=============================================================================
Hardware interrupt module configuration
=============================================================================*/
#define LOSCFG_PLATFORM_HWI 1
#define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT 0
#define LOSCFG_PLATFORM_HWI_LIMIT 32
/*=============================================================================
Task module configuration
=============================================================================*/
#define LOSCFG_BASE_CORE_TSK_LIMIT 12
#define LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE (0x500U)
#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE (0x2E0U)
#define LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE (0x130U)
#define LOSCFG_BASE_CORE_TIMESLICE 1
#define LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT 10
/*=============================================================================
Semaphore module configuration
=============================================================================*/
#define LOSCFG_BASE_IPC_SEM 1
#define LOSCFG_BASE_IPC_SEM_LIMIT 48
/*=============================================================================
Mutex module configuration
=============================================================================*/
#define LOSCFG_BASE_IPC_MUX 1
#define LOSCFG_BASE_IPC_MUX_LIMIT 10
/*=============================================================================
Queue module configuration
=============================================================================*/
#define LOSCFG_BASE_IPC_QUEUE 1
#define LOSCFG_BASE_IPC_QUEUE_LIMIT 6
/*=============================================================================
Software timer module configuration
=============================================================================*/
#define LOSCFG_BASE_CORE_SWTMR 1
#define LOSCFG_BASE_CORE_SWTMR_ALIGN 1
#define LOSCFG_BASE_CORE_SWTMR_LIMIT 6
/*=============================================================================
Memory module configuration
=============================================================================*/
#define LOSCFG_SYS_HEAP_SIZE 0x9000UL
#define OS_SYS_MEM_SIZE 0x2000UL
#define LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK 0
#define LOSCFG_BASE_MEM_NODE_SIZE_CHECK 1
#define LOSCFG_MEM_MUL_POOL 0
#define OS_SYS_MEM_NUM 20
#define LOSCFG_KERNEL_MEM_SLAB 0
/*=============================================================================
Exception module configuration
=============================================================================*/
#define LOSCFG_PLATFORM_EXC 0
/* =============================================================================
printf module configuration
============================================================================= */
#define LOSCFG_KERNEL_PRINTF 1
/* =============================================================================
enable backtrace
============================================================================= */
#define LOSCFG_BACKTRACE_TYPE 0
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _TARGET_CONFIG_H */

View File

@ -0,0 +1,194 @@
# Nuclei DDR200T开发板LiteOS使用说明
## Nuclei DDR200T开发板简介
Nuclei DDR200T开发板是一款集成了FPGA和通用MCU的RISC-V评估开发板。其中FPGA子系统采用Xilinx XC7A200T-2 FPGA芯片提供板载FPGA JTAG下载器、丰富的板载存储Flash,DDR,eMMC,EEPROM)、丰富的接口资源数字、模拟以及蜂鸟调试器接口。MCU子系统采用GD32VF103 MCU芯片提供板载调试器以及JTAG调试接口。
开发板资料链接:
- [Nuclei DDR200T开发板详细介绍](https://www.nucleisys.com/upload/files/fpga/doc/Nuclei_FPGA_DebugKit_Intro_20201220.pdf)
- [Nuclei DDR200T开发板原理图](https://www.nucleisys.com/upload/files/fpga/doc/Nuclei_DDR200T.pdf)
## 文件结构
```
├── components # 可选组件
│ ├── cppsupport # C++支持
│ └── cpup # CPUP功能
├── kal # 内核抽象层
│ └── posix # posix标准接口支持
├── kernel # 内核最小功能集支持
│ ├── arch # 内核指令架构层代码
│ │ ├── risc-v # risc-v架构的代码
│ │ │ └── nuclei # nuclei内核相关代码
│ │ │ └── gcc # gcc编译器相关代码
│ │ │ ├── nmsis # nmsis内核标准
│ │ └── include # 对外接口存放目录
│ │ ├── los_arch_atomic.h # 定义通用arch的原子操作
│ │ ├── los_arch_context.h # 定义通用arch的上下文切换
│ │ ├── los_arch.h # 定义通用arch初始化
│ │ └── los_arch_interrupt.h # 定义通用arch中断
│ ├── include # 对外接口存放目录
│   │   ├── los_config.h # 功能开关和配置参数
│   │   ├── los_event.h # 事件
│   │   ├── los_liteos.h # liteos最小功能集对外提供的头文件
│   │   ├── los_memory.h # 堆内存管理
│   │   ├── los_mutex.h # 互斥锁
│   │   ├── los_queue.h # 队列
│   │   ├── los_scheduler.h # 调度算法
│   │   ├── los_sem.h # 信号量
│   │   ├── los_task.h # 任务
│   │   └── los_timer.h # 定时器
│ └── src # 内核最小功能集源码
├── targets # 板级工程目录
│ ├── riscv_nuclei_demo_soc_gcc # Nuclei DDR200T开发板相关代码
│ ├── GCC # 编译相关
│ ├── OS_CONFIG # 开发板配置功能开关和配置参数
│ ├── SoC # SOC相关代码
│ └── Src # application相关代码
├── utils # 通用公共目录
├── include
│   ├── los_compiler.h # 编译工具配置,类型定义
│   ├── los_debug.h # debugprintf相关
│   ├── los_error.h # 错误定义
│   └── los_list.h
└── src
```
## 使用说明
软件需求linux环境
硬件需求Nuclei DDR200T开发板
[环境配置](#sectionb1)
[编译源码](#sectionb2)
[下载调试、运行](#sectionb3)
本示例将新建并运行两个任务,可以在控制台查看任务执行打印信息。
### 环境配置<a name="sectionb1"></a>
- **工具链配置**
请先确认您使用的是centos系统或Ububntu 64bit。
1. 新建一个`Nuclei` 文件夹,比如`~/home/Nuclei`
2. 参考下图,从[Nuclei Download Center](https://nucleisys.com/download.php)下载工具链和OpenOCD。
- CentOS或Ubuntu系统请点击图中红框1下载RISC-V GNU工具链
- 点击图中蓝框2-1下载64bit的OpenOCD
- **确保Make工具版本不低于3.82**: ubuntu系统使用`sudo apt-get install make`指令安装`make`工具, CentOS系统使用`sudo yum install make`指令安装。
图1 Linux环境要下载的Nuclei Tools
![Nuclei Tools need to be downloaded for Linux](doc/image/nuclei_tools_download_linux.png)
3. 在之前新建的`Nuclei`文件夹中新建`gcc`文件夹和`openocd`文件夹。
- 解压缩之前下载的**gnu工具链**到任意文件夹中,复制其中`bin`文件件所在层级的所有内容到`gcc`文件夹中。
- 同样解压缩之前下载的**OpenOCD**到任意文件夹中,复制其中`bin`文件件所在层级的所有内容到`openocd`文件夹中。
> 注意:
>
> 请务必下载并解压缩Linux版本的工具不要下载windows版本工具。
- **驱动配置**
驱动配置步骤如下:
1. 连接开发板到Linux中确保USB被Linux识别出来。
2. 在控制台中使用lsusb指令查看信息参考的打印信息如下
```
Bus 001 Device 010: ID 0403:6010 Future Technology Devices International, Ltd FT2232xxxx
```
3. 将githubhttps://github.com/riscv-mcu/ses_nuclei_sdk_projects/blob/master/misc/99-openocd.rules上misc文件夹内99-openocd.rules文件复制到当前路径下控制台中输入sudo cp 99-openocd.rules /etc/udev/rules.d/99-openocd.rules指令复制文件到指定路径下。
4. 断开调试器再重新连接到Linux系统中。
5. 使用ls /dev/ttyUSB*命令查看ttyUSB信息参考输出如下
```
/dev/ttyUSB0 /dev/ttyUSB1
```
6. 使用ls -l /dev/ttyUSB1命令查看分组信息参考输出如下:
```
crw-rw-r-- 1 root plugdev 188, 1 Nov 28 12:53 /dev/ttyUSB1
```
可以看到ttyUSB1已经加入plugdev组接下来我们要将自己添加到plugdev组。使用whoami命令查看当前用户名我们将其记录为\< your_user_name >。
7. 使用sudo usermod -a -G plugdev \<your_user_name>命令将自己添加进plugdev组。
8. 再次确认当前用户名已属于plugdev组使用groups命令可以看到打印信息中有plugdev即成功将当前用户添加至plugdev组。
### 编译源码<a name="sectionb2"></a>
编译前请在当前控制台中配置`NUCLEI_TOOL_ROOT`路径,假设`Nuclei`文件夹所在路径为`/home/Nuclei`,输入`export NUCLEI_TOOL_ROOT=/home/Nuclei` 。或者使用时make选项增加`NUCLEI_TOOL_ROOT=/home/Nuclei`。
配置路径后打开至代码根目录下的/target/riscv_nuclei_demo_soc_gcc/GCC位置输入如下指令开始编译
```
make all
```
编译结束后部分参考输出如下:
```
text data bss dec hex filename
21900 112 65426 87438 1558e build/Nuclei-demo-soc.elf
```
若编译前想清理工程,请使用如下指令:
```
make clean
```
### 下载调试、运行<a name="sectionb3"></a>
调试或运行前请先是用蜂鸟调试器连接Nuclei DDR200T开发板确保已按照[环境配置](#sectionb1)中驱动配置部分配置完成。
同样配置好`NUCLEI_TOOL_ROOT`路径并打开至代码根目录下的/target/riscv_nuclei_demo_soc_gcc/GCC位置输入如下指令进入GDB调试
```
make debug
```
等待到进入GDB调试界面时输入`load`指令下载编译好的elf文件就可以开始调试。
若想直接运行,请在调试时所在位置输入如下指令:
```
make upload
```
运行时可以查看串口打印内容,使用串口查看工具,这里以`minicom`为例,若未安装此工具可自行安装或使用其他串口查看工具。打开控制台,输入`minicom -D /dev/ttyUSB1 -b 115200`指令打开串口查看工具。
运行时参考输出如下:
```
Nuclei SDK Build Time: Mar 31 2021, 03:29:57
Download Mode: ILM
CPU Frequency 7998996 Hz
entering kernel init...
TaskSampleEntry1 running...
TaskSampleEntry1 running...
TaskSampleEntry1 running...
TaskSampleEntry1 running...
TaskSampleEntry2 running...
TaskSampleEntry1 running...
TaskSampleEntry1 running...
TaskSampleEntry1 running...
TaskSampleEntry1 running...
TaskSampleEntry1 running...
TaskSampleEntry2 running...
TaskSampleEntry1 running...
```

View File

@ -0,0 +1,37 @@
// See LICENSE for license details.
#ifndef _BOARD_HBIRD_EVAL_H_
#define _BOARD_HBIRD_EVAL_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "nuclei_sdk_soc.h"
// Interrupt Numbers
#define SOC_BUTTON_1_IRQn SOC_INT49_IRQn
#define SOC_BUTTON_2_IRQn SOC_INT50_IRQn
// Interrupt Handler Definitions
#define SOC_BUTTON_1_HANDLER eclic_irq49_handler
#define SOC_BUTTON_2_HANDLER eclic_irq50_handler
// GPIO Bit Offset
#define SOC_LED_RED_GPIO_OFS 19
#define SOC_LED_GREEN_GPIO_OFS 21
#define SOC_LED_BLUE_GPIO_OFS 22
#define SOC_BUTTON_1_GPIO_OFS 30
#define SOC_BUTTON_2_GPIO_OFS 31
// GPIO Bit Mask
#define SOC_LED_RED_GPIO_MASK (1<<SOC_LED_RED_GPIO_OFS)
#define SOC_LED_GREEN_GPIO_MASK (1<<SOC_LED_GREEN_GPIO_OFS)
#define SOC_LED_BLUE_GPIO_MASK (1<<SOC_LED_BLUE_GPIO_OFS)
#define SOC_BUTTON_1_GPIO_MASK (1<<SOC_BUTTON_1_GPIO_OFS)
#define SOC_BUTTON_2_GPIO_MASK (1<<SOC_BUTTON_2_GPIO_OFS)
#define SOC_BUTTON_GPIO_MASK (SOC_BUTTON_1_GPIO_MASK | SOC_BUTTON_2_GPIO_MASK)
#define SOC_LED_GPIO_MASK (SOC_LED_RED_GPIO_MASK | SOC_LED_GREEN_GPIO_MASK | SOC_LED_BLUE_GPIO_MASK)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,20 @@
// See LICENSE for license details.
#ifndef _NUCLEI_SDK_HAL_H
#define _NUCLEI_SDK_HAL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "board_hbird_eval.h"
#define SOC_DEBUG_UART UART0
#ifndef NUCLEI_BANNER
#define NUCLEI_BANNER 1
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,211 @@
/*
* 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_hbird_ddr.ld
* @brief GNU Linker Script for Nuclei N/NX based device in ddr Download Mode
* @version V1.0.0
* @date 20. Jul 2020
******************************************************************************/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
/* Emulate ROM using DDR */
rom (rxai!w) : ORIGIN = 0xA0000000, LENGTH = 32M
/* Emulate RAM using DDR */
ram (wxa!ri) : ORIGIN = 0xA2000000, LENGTH = 32M
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
.init :
{
*(.vtable)
KEEP (*(SORT_NONE(.init)))
} >rom AT>rom
.ilalign :
{
. = ALIGN(4);
PROVIDE( _ilm_lma = . );
} >rom AT>rom
.ialign :
{
PROVIDE( _ilm = . );
} >rom AT>rom
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >rom AT>rom
.rodata : ALIGN(4)
{
. = ALIGN(4);
*(.rdata)
*(.rodata .rodata.*)
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
*(.gnu.linkonce.r.*)
} >rom AT>rom
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >rom AT>rom
. = 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 = .);
} >rom AT>rom
.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 = .);
} >rom AT>rom
.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 = .);
} >rom AT>rom
.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))
} >rom AT>rom
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >rom AT>rom
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >rom AT>rom
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>rom
.data :
{
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >ram AT>rom
. = 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 = . );
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
{
PROVIDE( _heap_end = . );
. = __stack_size;
PROVIDE( _sp = . );
} >ram AT>ram
}

View File

@ -0,0 +1,209 @@
/*
* 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_hbird_flash.ld
* @brief GNU Linker Script for Nuclei N/NX based device in Flash Download Mode
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 4M
ilm (rxai!w) : ORIGIN = 0x80000000, LENGTH = 64K
ram (wxa!ri) : ORIGIN = 0x90000000, LENGTH = 64K
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
.init :
{
KEEP (*(SORT_NONE(.init)))
} >flash AT>flash
.ilalign :
{
. = ALIGN(4);
PROVIDE( _ilm_lma = . );
} >flash AT>flash
.ialign :
{
PROVIDE( _ilm = . );
} >ilm AT>flash
.text :
{
*(.vtable_ilm)
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >ilm AT>flash
.rodata : ALIGN(4)
{
. = ALIGN(4);
} >ilm AT>flash
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ilm 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
.data :
{
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(4);
*(.rdata)
*(.rodata .rodata.*)
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
*(.gnu.linkonce.r.*)
} >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 = . );
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
{
PROVIDE( _heap_end = . );
. = __stack_size;
PROVIDE( _sp = . );
} >ram AT>ram
}

View File

@ -0,0 +1,284 @@
/*
* 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_hbird_flashxip.ld
* @brief GNU Linker Script for Nuclei N/NX based device in FlashXIP Download Mode
* @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 = 0x20000000;
__ROM_SIZE = 0x00400000;
/*--------------------- 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 = 0x90000000;
__RAM_SIZE = 0x00010000;
/********************* 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.*)
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
*(.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
}

View File

@ -0,0 +1,210 @@
/*
* 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_hbird_ilm.ld
* @brief GNU Linker Script for Nuclei N/NX based device in ilm Download Mode
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
ilm (rxai!w) : ORIGIN = 0x80000000, LENGTH = 64K
ram (wxa!ri) : ORIGIN = 0x90000000, LENGTH = 64K
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
.init :
{
*(.vtable)
KEEP (*(SORT_NONE(.init)))
} >ilm AT>ilm
.ilalign :
{
. = ALIGN(4);
PROVIDE( _ilm_lma = . );
} >ilm AT>ilm
.ialign :
{
PROVIDE( _ilm = . );
} >ilm AT>ilm
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >ilm AT>ilm
.rodata : ALIGN(4)
{
. = ALIGN(4);
*(.rdata)
*(.rodata .rodata.*)
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
*(.gnu.linkonce.r.*)
} >ilm AT>ilm
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ilm AT>ilm
. = 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 = .);
} >ilm AT>ilm
.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 = .);
} >ilm AT>ilm
.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 = .);
} >ilm AT>ilm
.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))
} >ilm AT>ilm
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >ilm AT>ilm
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >ilm AT>ilm
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>ilm
.data :
{
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >ram AT>ilm
. = 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 = . );
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
{
PROVIDE( _heap_end = . );
. = __stack_size;
PROVIDE( _sp = . );
} >ram AT>ram
}

View File

@ -0,0 +1,49 @@
adapter_khz 1000
interface ftdi
## If ftdi_device_desc not specified, the device description is ignored during device selection.
## So if you want to specify a dedicated FTDI device, you can select following device description:
## "Dual RS232-HS" is for HummingBird Debugger V1
## "USB <-> JTAG-DEBUGGER" is for HummingBird Debugger V2
## Uncomment one which match your device description
# ftdi_device_desc "Dual RS232-HS"
# ftdi_device_desc "USB <-> JTAG-DEBUGGER"
ftdi_vid_pid 0x0403 0x6010
ftdi_oscan1_mode off
transport select jtag
ftdi_layout_init 0x0008 0x001b
ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020
ftdi_layout_signal TCK -data 0x0001
ftdi_layout_signal TDI -data 0x0002
ftdi_layout_signal TDO -input 0x0004
ftdi_layout_signal TMS -data 0x0008
ftdi_layout_signal JTAG_SEL -data 0x0100 -oe 0x0100
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME fespi 0x20000000 0 0 0 $_TARGETNAME
# Set the ILM space also as flash, to make sure it can be add breakpoint with hardware trigger
#flash bank onboard_ilm fespi 0x80000000 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
init
#reset
if {[ info exists pulse_srst]} {
ftdi_set_signal nSRST 0
ftdi_set_signal nSRST z
}
halt
# We must turn on this because otherwise the IDE version debug cannot download the program into flash
flash protect 0 0 last off

View File

@ -0,0 +1,459 @@
/******************************************************************************
* @file hbird.h
* @brief NMSIS Core Peripheral Access Layer Header File for
* Nuclei HummingBird evaluation SoC which support Nuclei N/NX class cores
* @version V1.00
* @date 22. Nov 2019
******************************************************************************/
/*
* 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 __HBIRD_H__
#define __HBIRD_H__
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup Nuclei
* @{
*/
/** @addtogroup hbird
* @{
*/
/** @addtogroup Configuration_of_NMSIS
* @{
*/
/* =========================================================================================================================== */
/* ================ Interrupt Number Definition ================ */
/* =========================================================================================================================== */
typedef enum IRQn
{
/* ======================================= Nuclei Core Specific Interrupt Numbers ======================================== */
Reserved0_IRQn = 0, /*!< Internal reserved */
Reserved1_IRQn = 1, /*!< Internal reserved */
Reserved2_IRQn = 2, /*!< Internal reserved */
SysTimerSW_IRQn = 3, /*!< System Timer SW interrupt */
Reserved3_IRQn = 4, /*!< Internal reserved */
Reserved4_IRQn = 5, /*!< Internal reserved */
Reserved5_IRQn = 6, /*!< Internal reserved */
SysTimer_IRQn = 7, /*!< System Timer Interrupt */
Reserved6_IRQn = 8, /*!< Internal reserved */
Reserved7_IRQn = 9, /*!< Internal reserved */
Reserved8_IRQn = 10, /*!< Internal reserved */
Reserved9_IRQn = 11, /*!< Internal reserved */
Reserved10_IRQn = 12, /*!< Internal reserved */
Reserved11_IRQn = 13, /*!< Internal reserved */
Reserved12_IRQn = 14, /*!< Internal reserved */
Reserved13_IRQn = 15, /*!< Internal reserved */
Reserved14_IRQn = 16, /*!< Internal reserved */
Reserved15_IRQn = 17, /*!< Internal reserved */
Reserved16_IRQn = 18, /*!< Internal reserved */
/* =========================================== hbird Specific Interrupt Numbers ========================================= */
/* ToDo: add here your device specific external interrupt numbers. 19~1023 is reserved number for user. Maxmum interrupt supported
could get from clicinfo.NUM_INTERRUPT. According the interrupt handlers defined in startup_Device.s
eg.: Interrupt for Timer#1 eclic_tim1_handler -> TIM1_IRQn */
SOC_INT19_IRQn = 19, /*!< Device Interrupt */
SOC_INT20_IRQn = 20, /*!< Device Interrupt */
SOC_INT21_IRQn = 21, /*!< Device Interrupt */
SOC_INT22_IRQn = 22, /*!< Device Interrupt */
SOC_INT23_IRQn = 23, /*!< Device Interrupt */
SOC_INT24_IRQn = 24, /*!< Device Interrupt */
SOC_INT25_IRQn = 25, /*!< Device Interrupt */
SOC_INT26_IRQn = 26, /*!< Device Interrupt */
SOC_INT27_IRQn = 27, /*!< Device Interrupt */
SOC_INT28_IRQn = 28, /*!< Device Interrupt */
SOC_INT29_IRQn = 29, /*!< Device Interrupt */
SOC_INT30_IRQn = 30, /*!< Device Interrupt */
SOC_INT31_IRQn = 31, /*!< Device Interrupt */
SOC_INT32_IRQn = 32, /*!< Device Interrupt */
SOC_INT33_IRQn = 33, /*!< Device Interrupt */
SOC_INT34_IRQn = 34, /*!< Device Interrupt */
SOC_INT35_IRQn = 35, /*!< Device Interrupt */
SOC_INT36_IRQn = 36, /*!< Device Interrupt */
SOC_INT37_IRQn = 37, /*!< Device Interrupt */
SOC_INT38_IRQn = 38, /*!< Device Interrupt */
SOC_INT39_IRQn = 39, /*!< Device Interrupt */
SOC_INT40_IRQn = 40, /*!< Device Interrupt */
SOC_INT41_IRQn = 41, /*!< Device Interrupt */
SOC_INT42_IRQn = 42, /*!< Device Interrupt */
SOC_INT43_IRQn = 43, /*!< Device Interrupt */
SOC_INT44_IRQn = 44, /*!< Device Interrupt */
SOC_INT45_IRQn = 45, /*!< Device Interrupt */
SOC_INT46_IRQn = 46, /*!< Device Interrupt */
SOC_INT47_IRQn = 47, /*!< Device Interrupt */
SOC_INT48_IRQn = 48, /*!< Device Interrupt */
SOC_INT49_IRQn = 49, /*!< Device Interrupt */
SOC_INT50_IRQn = 50, /*!< Device Interrupt */
SOC_INT_MAX,
} IRQn_Type;
/* =========================================================================================================================== */
/* ================ Exception Code Definition ================ */
/* =========================================================================================================================== */
typedef enum EXCn {
/* ======================================= Nuclei N/NX Specific Exception Code ======================================== */
InsUnalign_EXCn = 0, /*!< Instruction address misaligned */
InsAccFault_EXCn = 1, /*!< Instruction access fault */
IlleIns_EXCn = 2, /*!< Illegal instruction */
Break_EXCn = 3, /*!< Beakpoint */
LdAddrUnalign_EXCn = 4, /*!< Load address misaligned */
LdFault_EXCn = 5, /*!< Load access fault */
StAddrUnalign_EXCn = 6, /*!< Store or AMO address misaligned */
StAccessFault_EXCn = 7, /*!< Store or AMO access fault */
UmodeEcall_EXCn = 8, /*!< Environment call from User mode */
MmodeEcall_EXCn = 11, /*!< Environment call from Machine mode */
NMI_EXCn = 0xfff, /*!< NMI interrupt */
} EXCn_Type;
/* =========================================================================================================================== */
/* ================ Processor and Core Peripheral Section ================ */
/* =========================================================================================================================== */
/* ToDo: set the defines according your Device */
/* ToDo: define the correct core revision */
#if __riscv_xlen == 32
#ifndef __NUCLEI_CORE_REV
#define __NUCLEI_N_REV 0x0104 /*!< Core Revision r1p4 */
#else
#define __NUCLEI_N_REV __NUCLEI_CORE_REV
#endif
#elif __riscv_xlen == 64
#ifndef __NUCLEI_CORE_REV
#define __NUCLEI_NX_REV 0x0100 /*!< Core Revision r1p0 */
#else
#define __NUCLEI_NX_REV __NUCLEI_CORE_REV
#endif
#endif /* __riscv_xlen == 64 */
/* ToDo: define the correct core features for the hbird */
#define __ECLIC_PRESENT 1 /*!< Set to 1 if ECLIC is present */
#define __ECLIC_BASEADDR 0x0C000000UL /*!< Set to ECLIC baseaddr of your device */
//#define __ECLIC_INTCTLBITS 3 /*!< Set to 1 - 8, the number of hardware bits are actually implemented in the clicintctl registers. */
#define __ECLIC_INTNUM 51 /*!< Set to 1 - 1024, total interrupt number of ECLIC Unit */
#define __SYSTIMER_PRESENT 1 /*!< Set to 1 if System Timer is present */
#define __SYSTIMER_BASEADDR 0x02000000UL /*!< Set to SysTimer baseaddr of your device */
/*!< Set to 0, 1, or 2, 0 not present, 1 single floating point unit present, 2 double floating point unit present */
#if !defined(__riscv_flen)
#define __FPU_PRESENT 0
#elif __riscv_flen == 32
#define __FPU_PRESENT 1
#else
#define __FPU_PRESENT 2
#endif
#define __DSP_PRESENT 1 /*!< Set to 1 if DSP is present */
#define __PMP_PRESENT 1 /*!< Set to 1 if PMP is present */
#define __PMP_ENTRY_NUM 16 /*!< Set to 8 or 16, the number of PMP entries */
#define __ICACHE_PRESENT 0 /*!< Set to 1 if I-Cache is present */
#define __DCACHE_PRESENT 0 /*!< Set to 1 if D-Cache is present */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
#define __Vendor_EXCEPTION 0 /*!< Set to 1 if vendor exception hander is present */
/** @} */ /* End of group Configuration_of_CMSIS */
#include <nmsis_core.h> /*!< Nuclei N/NX class processor and core peripherals */
/* ToDo: include your system_hbird.h file
replace 'Device' with your device name */
#include "system_hbird.h" /*!< hbird System */
/* ======================================== Start of section using anonymous unions ======================================== */
#if defined (__GNUC__)
/* anonymous unions are enabled by default */
#else
#warning Not supported compiler type
#endif
#define RTC_FREQ 32768
// The TIMER frequency is just the RTC frequency
#define SOC_TIMER_FREQ RTC_FREQ
/* =========================================================================================================================== */
/* ================ Device Specific Peripheral Section ================ */
/* =========================================================================================================================== */
/** @addtogroup Device_Peripheral_peripherals
* @{
*/
/****************************************************************************
* Platform definitions
*****************************************************************************/
// IOF Mappings
#define IOF0_SPI1_MASK _AC(0x000007FC,UL)
#define SPI11_NUM_SS (4)
#define IOF_SPI1_SS0 (2u)
#define IOF_SPI1_SS1 (8u)
#define IOF_SPI1_SS2 (9u)
#define IOF_SPI1_SS3 (10u)
#define IOF_SPI1_MOSI (3u)
#define IOF_SPI1_MISO (4u)
#define IOF_SPI1_SCK (5u)
#define IOF_SPI1_DQ0 (3u)
#define IOF_SPI1_DQ1 (4u)
#define IOF_SPI1_DQ2 (6u)
#define IOF_SPI1_DQ3 (7u)
#define IOF0_SPI2_MASK _AC(0xFC000000,UL)
#define SPI2_NUM_SS (1)
#define IOF_SPI2_SS0 (26u)
#define IOF_SPI2_MOSI (27u)
#define IOF_SPI2_MISO (28u)
#define IOF_SPI2_SCK (29u)
#define IOF_SPI2_DQ0 (27u)
#define IOF_SPI2_DQ1 (28u)
#define IOF_SPI2_DQ2 (30u)
#define IOF_SPI2_DQ3 (31u)
#define IOF0_UART0_MASK _AC(0x00030000, UL)
#define IOF_UART0_RX (16u)
#define IOF_UART0_TX (17u)
#define IOF0_UART1_MASK _AC(0x03000000, UL)
#define IOF_UART1_RX (24u)
#define IOF_UART1_TX (25u)
#define IOF0_I2C_MASK _AC(0x00003000, UL)
#define IOF_I2C_SDA (12u)
#define IOF_I2C_SCL (13u)
#define IOF1_PWM0_MASK _AC(0x0000000F, UL)
#define IOF1_PWM1_MASK _AC(0x00780000, UL)
#define IOF1_PWM2_MASK _AC(0x00003C00, UL)
// Interrupt Numbers
#define SOC_ECLIC_NUM_INTERRUPTS 32
#define SOC_ECLIC_INT_GPIO_BASE 19
// Interrupt Handler Definitions
#define SOC_MTIMER_HANDLER eclic_mtip_handler
#define SOC_SOFTINT_HANDLER eclic_msip_handler
#define GPIO_BIT_ALL_ZERO (0x0)
#define GPIO_BIT_ALL_ONE (0xFFFFFFFF)
/**
* @brief GPIO
*/
typedef struct { /*!< GPIO Structure */
__IOM uint32_t INPUT_VAL;
__IOM uint32_t INPUT_EN;
__IOM uint32_t OUTPUT_EN;
__IOM uint32_t OUTPUT_VAL;
__IOM uint32_t PULLUP_EN;
__IOM uint32_t DRIVE;
__IOM uint32_t RISE_IE;
__IOM uint32_t RISE_IP;
__IOM uint32_t FALL_IE;
__IOM uint32_t FALL_IP;
__IOM uint32_t HIGH_IE;
__IOM uint32_t HIGH_IP;
__IOM uint32_t LOW_IE;
__IOM uint32_t LOW_IP;
__IOM uint32_t IOF_EN;
__IOM uint32_t IOF_SEL;
__IOM uint32_t OUTPUT_XOR;
} GPIO_TypeDef;
/**
* @brief UART
*/
typedef struct {
__IOM uint32_t TXFIFO;
__IOM uint32_t RXFIFO;
__IOM uint32_t TXCTRL;
__IOM uint32_t RXCTRL;
__IOM uint32_t IE;
__IOM uint32_t IP;
__IOM uint32_t DIV;
} UART_TypeDef;
/**
* @brief PWM
*/
typedef struct {
__IOM uint32_t CFG;
uint32_t RESERVED0;
__IOM uint32_t COUNT;
uint32_t RESERVED1;
__IOM uint32_t S;
uint32_t RESERVED2[3];
__IOM uint32_t CMP0;
__IOM uint32_t CMP1;
__IOM uint32_t CMP2;
__IOM uint32_t CMP3;
} PWM_TypeDef;
/**
* @brief QSPI
*/
typedef struct {
__IOM uint32_t SCKDIV;
__IOM uint32_t SCKMODE;
__IOM uint32_t RESERVED0[2];
__IOM uint32_t CSID;
__IOM uint32_t CSDEF;
__IOM uint32_t CSMODE;
__IOM uint32_t RESERVED1[3];
__IOM uint32_t DELAY0;
__IOM uint32_t DELAY1;
__IOM uint32_t RESERVED2[4];
__IOM uint32_t FMT;
__IOM uint32_t RESERVED3;
__IOM uint32_t TXDATA;
__IOM uint32_t RXDATA;
__IOM uint32_t TXMARK;
__IOM uint32_t RXMARK;
__IOM uint32_t RESERVED4[2];
__IOM uint32_t FCTRL;
__IOM uint32_t FFMT;
__IOM uint32_t RESERVED5[2];
__IOM uint32_t IE;
__IOM uint32_t IP;
} QSPI_TypeDef;
/**
* @brief I2C
*/
typedef struct {
__IOM uint8_t PRERlo;
__IOM uint8_t PRERhi;
__IOM uint8_t CTR;
__IOM uint8_t TXRXR; /* TXR and RXR in same address */
__IOM uint8_t CSR; /* CR and SR in same address */
} I2C_TypeDef;
/*@}*/ /* end of group hbird_Peripherals */
/* ========================================= End of section using anonymous unions ========================================= */
#if defined (__GNUC__)
/* anonymous unions are enabled by default */
#else
#warning Not supported compiler type
#endif
/* =========================================================================================================================== */
/* ================ Device Specific Peripheral Address Map ================ */
/* =========================================================================================================================== */
/* ToDo: add here your device peripherals base addresses
following is an example for timer */
/** @addtogroup Device_Peripheral_peripheralAddr
* @{
*/
/* Peripheral and SRAM base address */
#define QSPI_FLASH_BASE (0x20000000UL) /*!< (FLASH ) Base Address */
#define ONCHIP_ROM_BASE (0x00001000UL) /*!< (ROM ) Base Address */
#define ONCHIP_ILM_BASE (0x80000000UL) /*!< (ILM ) Base Address */
#define ONCHIP_DLM_BASE (0x90000000UL) /*!< (DLM ) Base Address */
#define HBIRD_PERIPH_BASE (0x10000000UL) /*!< (Peripheral) Base Address */
/* Peripheral memory map */
/* Fast-IO Interfaced IP */
#define GPIO_BASE (HBIRD_PERIPH_BASE + 0x12000) /*!< (GPIO) Base Address */
/* PPI Interfaced IP */
#define UART0_BASE (HBIRD_PERIPH_BASE + 0x13000) /*!< (UART0) Base Address */
#define QSPI0_BASE (HBIRD_PERIPH_BASE + 0x14000) /*!< (QSPI0) Base Address */
#define PWM0_BASE (HBIRD_PERIPH_BASE + 0x15000) /*!< (PWM0) Base Address */
#define UART1_BASE (HBIRD_PERIPH_BASE + 0x23000) /*!< (UART1) Base Address */
#define QSPI1_BASE (HBIRD_PERIPH_BASE + 0x24000) /*!< (QSPI1) Base Address */
#define PWM1_BASE (HBIRD_PERIPH_BASE + 0x25000) /*!< (PWM1) Base Address */
#define QSPI2_BASE (HBIRD_PERIPH_BASE + 0x34000) /*!< (QSPI2) Base Address */
#define PWM2_BASE (HBIRD_PERIPH_BASE + 0x35000) /*!< (PWM2) Base Address */
#define I2C_BASE (HBIRD_PERIPH_BASE + 0x42000) /*!< (I2C Master) Base Address */
/** @} */ /* End of group Device_Peripheral_peripheralAddr */
/* =========================================================================================================================== */
/* ================ Peripheral declaration ================ */
/* =========================================================================================================================== */
/* ToDo: add here your device peripherals pointer definitions
following is an example for timer */
/** @addtogroup Device_Peripheral_declaration
* @{
*/
#define GPIO ((GPIO_TypeDef *) GPIO_BASE)
#define UART0 ((UART_TypeDef *) UART0_BASE)
#define QSPI0 ((QSPI_TypeDef *) QSPI0_BASE)
#define PWM0 ((PWM_TypeDef *) PWM0_BASE)
#define UART1 ((UART_TypeDef *) UART1_BASE)
#define QSPI1 ((QSPI_TypeDef *) QSPI1_BASE)
#define PWM1 ((PWM_TypeDef *) PWM1_BASE)
#define QSPI2 ((QSPI_TypeDef *) QSPI2_BASE)
#define PWM2 ((PWM_TypeDef *) PWM2_BASE)
#define I2C ((I2C_TypeDef *) I2C_BASE)
// Helper functions
#define _REG8(p, i) (*(volatile uint8_t *) ((p) + (i)))
#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i)))
#define GPIO_REG(offset) _REG32(GPIO_BASE, offset)
#define PWM0_REG(offset) _REG32(PWM0_BASE, offset)
#define PWM1_REG(offset) _REG32(PWM1_BASE, offset)
#define PWM2_REG(offset) _REG32(PWM2_BASE, offset)
#define SPI0_REG(offset) _REG32(QSPI0_BASE, offset)
#define SPI1_REG(offset) _REG32(QSPI1_BASE, offset)
#define SPI2_REG(offset) _REG32(QSPI2_BASE, offset)
#define UART0_REG(offset) _REG32(UART0_BASE, offset)
#define UART1_REG(offset) _REG32(UART1_BASE, offset)
#define I2C_REG(offset) _REG8(I2C_BASE, offset)
// Misc
#define NUM_GPIO 32
uint32_t get_cpu_freq();
void delay_1ms(uint32_t count);
/** @} */ /* End of group hbird */
/** @} */ /* End of group Nuclei */
#ifdef __cplusplus
}
#endif
#endif /* __HBIRD_H__ */

View File

@ -0,0 +1,56 @@
// See LICENSE for license details.
#ifndef _HBIRD_GPIO_H
#define _HBIRD_GPIO_H
#ifdef __cplusplus
extern "C" {
#endif
#define GPIO_INPUT_VAL (0x00)
#define GPIO_INPUT_EN (0x04)
#define GPIO_OUTPUT_EN (0x08)
#define GPIO_OUTPUT_VAL (0x0C)
#define GPIO_PULLUP_EN (0x10)
#define GPIO_DRIVE (0x14)
#define GPIO_RISE_IE (0x18)
#define GPIO_RISE_IP (0x1C)
#define GPIO_FALL_IE (0x20)
#define GPIO_FALL_IP (0x24)
#define GPIO_HIGH_IE (0x28)
#define GPIO_HIGH_IP (0x2C)
#define GPIO_LOW_IE (0x30)
#define GPIO_LOW_IP (0x34)
#define GPIO_IOF_EN (0x38)
#define GPIO_IOF_SEL (0x3C)
#define GPIO_OUTPUT_XOR (0x40)
typedef enum iof_func {
IOF_SEL_GPIO = 0,
IOF_SEL_0 = 1,
IOF_SEL_1 = 2
} IOF_FUNC;
typedef enum gpio_int_type {
GPIO_INT_RISE = 0,
GPIO_INT_FALL = 1,
GPIO_INT_HIGH = 2,
GPIO_INT_LOW = 3
} GPIO_INT_TYPE;
int32_t gpio_iof_config(GPIO_TypeDef *gpio, uint32_t mask, IOF_FUNC func);
int32_t gpio_enable_output(GPIO_TypeDef *gpio, uint32_t mask);
int32_t gpio_enable_input(GPIO_TypeDef *gpio, uint32_t mask);
int32_t gpio_write(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value);
int32_t gpio_toggle(GPIO_TypeDef *gpio, uint32_t mask);
int32_t gpio_read(GPIO_TypeDef *gpio, uint32_t mask);
int32_t gpio_set_pue(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value);
int32_t gpio_set_ds(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value);
int32_t gpio_set_outxor(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value);
int32_t gpio_enable_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type);
int32_t gpio_disable_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type);
int32_t gpio_clear_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type);
#ifdef __cplusplus
}
#endif
#endif /* _HBIRD_GPIO_H */

View File

@ -0,0 +1,56 @@
//See LICENSE for license details
#ifndef _HBIRD_I2C_H
#define _HBIRD_I2C_H
#ifdef __cplusplus
extern "C" {
#endif
/* register offsets */
//all registers are 8 bits width
#define I2C_REG_PRERlo 0x00
#define I2C_REG_PRERhi 0x01
#define I2C_REG_CTR 0X02
#define I2C_REG_TXR 0x03
#define I2C_REG_RXR 0X03
#define I2C_REG_CR 0X04
#define I2C_REG_SR 0X04
#define I2C_CTR_EN (1 << 7)
#define I2C_CTR_IE (1 << 6)
#define I2C_CR_STA (1 << 7)
#define I2C_CR_STO (1 << 6)
#define I2C_CR_RD (1 << 5)
#define I2C_CR_WR (1 << 4)
#define I2C_CR_ACK (1 << 3)
#define I2C_CR_IACK (1 << 0)
#define I2C_TXR_WRRD (1 << 0)//0:write to slave; 1:read from slave;
#define I2C_SR_RXACK (1 << 7)//0:received; 1:no ack resceived
#define I2C_SR_BUSY (1 << 6)//0:after 'STOP' detected; 1:after 'START' detected
#define I2C_SR_AL (1 << 5)
#define I2C_SR_TIP (1 << 1)//0:transfer complete; 1:transfering
#define I2C_SR_IF (1 << 0)
#if 0
/*fileds*/
#define I2C_CTR_ENABLE 1
#define I2C_CTR_DISABLE 0
#define I2C_CTR_INTEN 1
#define I2C_CTR_INTDIS 0
#define I2C_TXR_RFS 1 //read from slave
#define I2C_TXR_WTS 0 //write to slave
#define I2C
#endif
#ifdef __cplusplus
}
#endif
#endif /* _HBIRD_I2C_H */

View File

@ -0,0 +1,44 @@
// See LICENSE for license details.
#ifndef _HBIRD_PWM_H
#define _HBIRD_PWM_H
#ifdef __cplusplus
extern "C" {
#endif
/* Register offsets */
#define PWM_CFG 0x00
#define PWM_COUNT 0x08
#define PWM_S 0x10
#define PWM_CMP0 0x20
#define PWM_CMP1 0x24
#define PWM_CMP2 0x28
#define PWM_CMP3 0x2C
/* Constants */
#define PWM_CFG_SCALE 0x0000000F
#define PWM_CFG_STICKY 0x00000100
#define PWM_CFG_ZEROCMP 0x00000200
#define PWM_CFG_DEGLITCH 0x00000400
#define PWM_CFG_ENALWAYS 0x00001000
#define PWM_CFG_ONESHOT 0x00002000
#define PWM_CFG_CMP0CENTER 0x00010000
#define PWM_CFG_CMP1CENTER 0x00020000
#define PWM_CFG_CMP2CENTER 0x00040000
#define PWM_CFG_CMP3CENTER 0x00080000
#define PWM_CFG_CMP0GANG 0x01000000
#define PWM_CFG_CMP1GANG 0x02000000
#define PWM_CFG_CMP2GANG 0x04000000
#define PWM_CFG_CMP3GANG 0x08000000
#define PWM_CFG_CMP0IP 0x10000000
#define PWM_CFG_CMP1IP 0x20000000
#define PWM_CFG_CMP2IP 0x40000000
#define PWM_CFG_CMP3IP 0x80000000
#ifdef __cplusplus
}
#endif
#endif /* _HBIRD_PWM_H */

View File

@ -0,0 +1,86 @@
// See LICENSE for license details.
#ifndef _HBIRD_SPI_H
#define _HBIRD_SPI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Register offsets */
#define SPI_REG_SCKDIV 0x00
#define SPI_REG_SCKMODE 0x04
#define SPI_REG_CSID 0x10
#define SPI_REG_CSDEF 0x14
#define SPI_REG_CSMODE 0x18
#define SPI_REG_DCSSCK 0x28
#define SPI_REG_DSCKCS 0x2a
#define SPI_REG_DINTERCS 0x2c
#define SPI_REG_DINTERXFR 0x2e
#define SPI_REG_FMT 0x40
#define SPI_REG_TXFIFO 0x48
#define SPI_REG_RXFIFO 0x4c
#define SPI_REG_TXCTRL 0x50
#define SPI_REG_RXCTRL 0x54
#define SPI_REG_FCTRL 0x60
#define SPI_REG_FFMT 0x64
#define SPI_REG_IE 0x70
#define SPI_REG_IP 0x74
/* Fields */
#define SPI_SCK_POL 0x1
#define SPI_SCK_PHA 0x2
#define SPI_FMT_PROTO(x) ((x) & 0x3)
#define SPI_FMT_ENDIAN(x) (((x) & 0x1) << 2)
#define SPI_FMT_DIR(x) (((x) & 0x1) << 3)
#define SPI_FMT_LEN(x) (((x) & 0xf) << 16)
/* TXCTRL register */
#define SPI_TXWM(x) ((x) & 0xffff)
/* RXCTRL register */
#define SPI_RXWM(x) ((x) & 0xffff)
#define SPI_IP_TXWM 0x1
#define SPI_IP_RXWM 0x2
#define SPI_FCTRL_EN 0x1
#define SPI_INSN_CMD_EN 0x1
#define SPI_INSN_ADDR_LEN(x) (((x) & 0x7) << 1)
#define SPI_INSN_PAD_CNT(x) (((x) & 0xf) << 4)
#define SPI_INSN_CMD_PROTO(x) (((x) & 0x3) << 8)
#define SPI_INSN_ADDR_PROTO(x) (((x) & 0x3) << 10)
#define SPI_INSN_DATA_PROTO(x) (((x) & 0x3) << 12)
#define SPI_INSN_CMD_CODE(x) (((x) & 0xff) << 16)
#define SPI_INSN_PAD_CODE(x) (((x) & 0xff) << 24)
#define SPI_TXFIFO_FULL (1 << 31)
#define SPI_RXFIFO_EMPTY (1 << 31)
/* Values */
#define SPI_CSMODE_AUTO 0
#define SPI_CSMODE_HOLD 2
#define SPI_CSMODE_OFF 3
#define SPI_DIR_RX 0
#define SPI_DIR_TX 1
#define SPI_PROTO_S 0
#define SPI_PROTO_D 1
#define SPI_PROTO_Q 2
#define SPI_ENDIAN_MSB 0
#define SPI_ENDIAN_LSB 1
#ifdef __cplusplus
}
#endif
#endif /* _HBIRD_SPI_H */

View File

@ -0,0 +1,75 @@
// See LICENSE for license details.
#ifndef _HBIRD_UART_H
#define _HBIRD_UART_H
#ifdef __cplusplus
extern "C" {
#endif
/* Register offsets */
#define UART_REG_TXFIFO 0x00
#define UART_REG_RXFIFO 0x04
#define UART_REG_TXCTRL 0x08
#define UART_REG_RXCTRL 0x0c
#define UART_REG_IE 0x10
#define UART_REG_IP 0x14
#define UART_REG_DIV 0x18
/* TXCTRL register */
#define UART_TXEN 0x1
#define UART_TXWM(x) (((x) & 0xffff) << 16)
/* RXCTRL register */
#define UART_RXEN 0x1
#define UART_RXWM(x) (((x) & 0xffff) << 16)
/* IP register */
#define UART_IP_TXWM 0x1
#define UART_IP_RXWM 0x2
#define UART_TXFIFO_FULL (1<<31)
#define UART_RXFIFO_EMPTY (1<<31)
#define UART_TXCTRL_TXCNT_OFS (16)
#define UART_TXCTRL_TXCNT_MASK (0x7 << UART_TXCTRL_TXCNT_OFS)
#define UART_TXCTRL_TXEN_OFS (0)
#define UART_TXCTRL_TXEN_MASK (0x1 << UART_TXCTRL_TXEN_OFS)
#define UART_TXCTRL_NSTOP_OFS (1)
#define UART_TXCTRL_NSTOP_MASK (0x1 << UART_TXCTRL_TXEN_OFS)
#define UART_RXCTRL_RXCNT_OFS (16)
#define UART_RXCTRL_RXCNT_MASK (0x7 << UART_RXCTRL_RXCNT_OFS)
#define UART_RXCTRL_RXEN_OFS (0)
#define UART_RXCTRL_RXEN_MASK (0x1 << UART_RXCTRL_RXEN_OFS)
#define UART_IE_TXIE_OFS (0)
#define UART_IE_TXIE_MASK (0x1 << UART_IE_TXIE_OFS)
#define UART_IE_RXIE_OFS (1)
#define UART_IE_RXIE_MASK (0x1 << UART_IE_RXIE_OFS)
#define UART_IP_TXIP_OFS (0)
#define UART_IP_TXIP_MASK (0x1 << UART_IP_TXIP_OFS)
#define UART_IP_RXIP_OFS (1)
#define UART_IP_RXIP_MASK (0x1 << UART_IP_RXIP_OFS)
typedef enum uart_stop_bit {
UART_STOP_BIT_1 = 0,
UART_STOP_BIT_2 = 1
} UART_STOP_BIT;
int32_t uart_init(UART_TypeDef *uart, uint32_t baudrate);
int32_t uart_config_stopbit(UART_TypeDef *uart, UART_STOP_BIT stopbit);
int32_t uart_write(UART_TypeDef *uart, uint8_t val);
uint8_t uart_read(UART_TypeDef *uart);
int32_t uart_set_tx_watermark(UART_TypeDef *uart, uint32_t watermark);
int32_t uart_enable_txint(UART_TypeDef *uart);
int32_t uart_disable_txint(UART_TypeDef *uart);
int32_t uart_set_rx_watermark(UART_TypeDef *uart, uint32_t watermark);
int32_t uart_enable_rxint(UART_TypeDef *uart);
int32_t uart_disable_rxint(UART_TypeDef *uart);
#ifdef __cplusplus
}
#endif
#endif /* _HBIRD_UART_H */

View File

@ -0,0 +1,19 @@
// See LICENSE for license details.
#ifndef _NUCLEI_SDK_SOC_H
#define _NUCLEI_SDK_SOC_H
#ifdef __cplusplus
extern "C" {
#endif
#include "hbird.h"
#include "hbird_uart.h"
#include "hbird_gpio.h"
#include "hbird_i2c.h"
#include "hbird_spi.h"
#include "hbird_pwm.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2009-2018 Arm Limited. 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.
*/
/*******************************************************************************
* @file system_hbird.h
* @brief NMSIS Nuclei N/NX Device Peripheral Access Layer Header File for
* Device <Device>
* @version V1.00
* @date 17. Dec 2019
******************************************************************************/
#ifndef __SYSTEM_HBIRD_H__ /* ToDo: replace '<Device>' with your device name */
#define __SYSTEM_HBIRD_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* \brief Setup the microcontroller system.
* \details
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* \brief Update SystemCoreClock variable.
* \details
* Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
/**
* \brief Register an exception handler for exception code EXCn
*/
extern void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler);
/**
* \brief Get current exception handler for exception code EXCn
*/
extern unsigned long Exception_Get_EXC(uint32_t EXCn);
/**
* \brief Initialize eclic config
*/
extern void ECLIC_Init(void);
/**
* \brief Initialize a specific IRQ and register the handler
* \details
* This function set vector mode, trigger mode and polarity, interrupt level and priority,
* assign handler for specific IRQn.
*/
extern int32_t ECLIC_Register_IRQ(IRQn_Type IRQn, uint8_t shv, ECLIC_TRIGGER_Type trig_mode, uint8_t lvl, uint8_t priority, void *handler);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_HBIRD_H__ */

View File

@ -0,0 +1,177 @@
#include "hbird.h"
#include "hbird_gpio.h"
int32_t gpio_iof_config(GPIO_TypeDef *gpio, uint32_t mask, IOF_FUNC func)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
switch (func) {
case IOF_SEL_GPIO:
gpio->IOF_EN &= ~mask;
break;
case IOF_SEL_0:
gpio->IOF_SEL &= ~mask;
gpio->IOF_EN |= mask;
break;
case IOF_SEL_1:
gpio->IOF_SEL |= mask;
gpio->IOF_EN |= mask;
break;
default:
break;
}
return 0;
}
int32_t gpio_enable_output(GPIO_TypeDef *gpio, uint32_t mask)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
gpio->OUTPUT_EN |= mask;
gpio->INPUT_EN &= ~mask;
return 0;
}
int32_t gpio_enable_input(GPIO_TypeDef *gpio, uint32_t mask)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
gpio->INPUT_EN |= mask;
gpio->OUTPUT_EN &= ~mask;
return 0;
}
int32_t gpio_write(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
// If value != 0, mean set gpio pin high, otherwise set pin low
if (value) {
gpio->OUTPUT_VAL |= (mask);
} else {
gpio->OUTPUT_VAL &= ~(mask);
}
return 0;
}
int32_t gpio_toggle(GPIO_TypeDef *gpio, uint32_t mask)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
gpio->OUTPUT_VAL = (mask ^ gpio->OUTPUT_VAL);
return 0;
}
int32_t gpio_read(GPIO_TypeDef *gpio, uint32_t mask)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
return gpio->INPUT_VAL & mask;
}
int32_t gpio_set_pue(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
gpio->PULLUP_EN |= (mask & value);
return 0;
}
int32_t gpio_set_ds(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
gpio->DRIVE |= (mask & value);
return 0;
}
int32_t gpio_set_outxor(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
gpio->OUTPUT_XOR |= (mask & value);
return 0;
}
int32_t gpio_enable_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
switch (type) {
case GPIO_INT_RISE:
gpio->RISE_IE |= mask;
break;
case GPIO_INT_FALL:
gpio->FALL_IE |= mask;
break;
case GPIO_INT_HIGH:
gpio->HIGH_IE |= mask;
break;
case GPIO_INT_LOW:
gpio->LOW_IE |= mask;
break;
default:
break;
}
return 0;
}
int32_t gpio_disable_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
switch (type) {
case GPIO_INT_RISE:
gpio->RISE_IE &= ~mask;
break;
case GPIO_INT_FALL:
gpio->FALL_IE &= ~mask;
break;
case GPIO_INT_HIGH:
gpio->HIGH_IE &= ~mask;
break;
case GPIO_INT_LOW:
gpio->LOW_IE &= ~mask;
break;
default:
break;
}
return 0;
}
int32_t gpio_clear_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type)
{
if (__RARELY(gpio == NULL)) {
return -1;
}
switch (type) {
case GPIO_INT_RISE:
gpio->RISE_IP |= mask;
break;
case GPIO_INT_FALL:
gpio->FALL_IP |= mask;
break;
case GPIO_INT_HIGH:
gpio->HIGH_IP |= mask;
break;
case GPIO_INT_LOW:
gpio->LOW_IP |= mask;
break;
default:
break;
}
return 0;
}

View File

@ -0,0 +1,105 @@
#include "hbird.h"
#include "hbird_uart.h"
int32_t uart_init(UART_TypeDef *uart, uint32_t baudrate)
{
if (__RARELY(uart == NULL)) {
return -1;
}
uart->DIV = SystemCoreClock / baudrate - 1;
uart->TXCTRL |= UART_TXEN;
uart->RXCTRL |= UART_RXEN;
return 0;
}
int32_t uart_config_stopbit(UART_TypeDef *uart, UART_STOP_BIT stopbit)
{
if (__RARELY(uart == NULL)) {
return -1;
}
uint32_t stopval = stopbit;
stopval = (stopbit << UART_TXCTRL_NSTOP_OFS) & UART_TXCTRL_TXCNT_MASK;
uart->TXCTRL &= stopval | (~UART_TXCTRL_TXCNT_MASK);
return 0;
}
int32_t uart_write(UART_TypeDef *uart, uint8_t val)
{
if (__RARELY(uart == NULL)) {
return -1;
}
#ifndef SIMULATION_XLSPIKE
while (uart->TXFIFO & UART_TXFIFO_FULL);
#endif
uart->TXFIFO = val;
return 0;
}
uint8_t uart_read(UART_TypeDef *uart)
{
uint32_t reg;
if (__RARELY(uart == NULL)) {
return -1;
}
do {
reg = uart->RXFIFO;
}
while (reg & UART_RXFIFO_EMPTY);
return (uint8_t)(reg & 0xFF);
}
int32_t uart_set_tx_watermark(UART_TypeDef *uart, uint32_t watermark)
{
if (__RARELY(uart == NULL)) {
return -1;
}
watermark = (watermark << UART_TXCTRL_TXCNT_OFS) & UART_TXCTRL_TXCNT_MASK;
uart->TXCTRL &= watermark | (~UART_TXCTRL_TXCNT_MASK);
return 0;
}
int32_t uart_enable_txint(UART_TypeDef *uart)
{
if (__RARELY(uart == NULL)) {
return -1;
}
uart->IE |= UART_IE_TXIE_MASK;
return 0;
}
int32_t uart_disable_txint(UART_TypeDef *uart)
{
if (__RARELY(uart == NULL)) {
return -1;
}
uart->IE &= ~UART_IE_TXIE_MASK;
return 0;
}
int32_t uart_set_rx_watermark(UART_TypeDef *uart, uint32_t watermark)
{
if (__RARELY(uart == NULL)) {
return -1;
}
watermark = (watermark << UART_RXCTRL_RXCNT_OFS) & UART_RXCTRL_RXCNT_MASK;
uart->RXCTRL &= watermark | (~UART_RXCTRL_RXCNT_MASK);
return 0;
}
int32_t uart_enable_rxint(UART_TypeDef *uart)
{
if (__RARELY(uart == NULL)) {
return -1;
}
uart->IE |= UART_IE_RXIE_MASK;
return 0;
}
int32_t uart_disable_rxint(UART_TypeDef *uart)
{
if (__RARELY(uart == NULL)) {
return -1;
}
uart->IE &= ~UART_IE_RXIE_MASK;
return 0;
}

View File

@ -0,0 +1,231 @@
/*
* 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 intexc_hbird.S
* \brief NMSIS Interrupt and Exception Handling Template File
* for Nuclei HummingBird evaluation SoC which support Nuclei N/NX class cores
* \version V1.00
* \date 17 Dec 2019
*
******************************************************************************/
#include "riscv_encoding.h"
/**
* \brief Global interrupt disabled
* \details
* This function disable global interrupt.
* \remarks
* - All the interrupt requests will be ignored by CPU.
*/
.macro DISABLE_MIE
csrc CSR_MSTATUS, MSTATUS_MIE
.endm
/**
* \brief Macro for context save
* \details
* This macro save ABI defined caller saved registers in the stack.
* \remarks
* - This Macro could use to save context when you enter to interrupt
* or exception
*/
/* Save caller registers */
.macro SAVE_CONTEXT
/* Allocate stack space for context saving */
#ifndef __riscv_32e
addi sp, sp, -20*REGBYTES
#else
addi sp, sp, -14*REGBYTES
#endif /* __riscv_32e */
STORE x1, 0*REGBYTES(sp)
STORE x4, 1*REGBYTES(sp)
STORE x5, 2*REGBYTES(sp)
STORE x6, 3*REGBYTES(sp)
STORE x7, 4*REGBYTES(sp)
STORE x10, 5*REGBYTES(sp)
STORE x11, 6*REGBYTES(sp)
STORE x12, 7*REGBYTES(sp)
STORE x13, 8*REGBYTES(sp)
STORE x14, 9*REGBYTES(sp)
STORE x15, 10*REGBYTES(sp)
#ifndef __riscv_32e
STORE x16, 14*REGBYTES(sp)
STORE x17, 15*REGBYTES(sp)
STORE x28, 16*REGBYTES(sp)
STORE x29, 17*REGBYTES(sp)
STORE x30, 18*REGBYTES(sp)
STORE x31, 19*REGBYTES(sp)
#endif /* __riscv_32e */
.endm
/**
* \brief Macro for restore caller registers
* \details
* This macro restore ABI defined caller saved registers from stack.
* \remarks
* - You could use this macro to restore context before you want return
* from interrupt or exeception
*/
/* Restore caller registers */
.macro RESTORE_CONTEXT
LOAD x1, 0*REGBYTES(sp)
LOAD x4, 1*REGBYTES(sp)
LOAD x5, 2*REGBYTES(sp)
LOAD x6, 3*REGBYTES(sp)
LOAD x7, 4*REGBYTES(sp)
LOAD x10, 5*REGBYTES(sp)
LOAD x11, 6*REGBYTES(sp)
LOAD x12, 7*REGBYTES(sp)
LOAD x13, 8*REGBYTES(sp)
LOAD x14, 9*REGBYTES(sp)
LOAD x15, 10*REGBYTES(sp)
#ifndef __riscv_32e
LOAD x16, 14*REGBYTES(sp)
LOAD x17, 15*REGBYTES(sp)
LOAD x28, 16*REGBYTES(sp)
LOAD x29, 17*REGBYTES(sp)
LOAD x30, 18*REGBYTES(sp)
LOAD x31, 19*REGBYTES(sp)
/* De-allocate the stack space */
addi sp, sp, 20*REGBYTES
#else
/* De-allocate the stack space */
addi sp, sp, 14*REGBYTES
#endif /* __riscv_32e */
.endm
/**
* \brief Macro for save necessary CSRs to stack
* \details
* This macro store MCAUSE, MEPC, MSUBM to stack.
*/
.macro SAVE_CSR_CONTEXT
/* Store CSR mcause to stack using pushmcause */
csrrwi x0, CSR_PUSHMCAUSE, 11
/* Store CSR mepc to stack using pushmepc */
csrrwi x0, CSR_PUSHMEPC, 12
/* Store CSR msub to stack using pushmsub */
csrrwi x0, CSR_PUSHMSUBM, 13
.endm
/**
* \brief Macro for restore necessary CSRs from stack
* \details
* This macro restore MSUBM, MEPC, MCAUSE from stack.
*/
.macro RESTORE_CSR_CONTEXT
LOAD x5, 13*REGBYTES(sp)
csrw CSR_MSUBM, x5
LOAD x5, 12*REGBYTES(sp)
csrw CSR_MEPC, x5
LOAD x5, 11*REGBYTES(sp)
csrw CSR_MCAUSE, x5
.endm
/**
* \brief Exception/NMI Entry
* \details
* This function provide common entry functions for exception/nmi.
* \remarks
* This function provide a default exception/nmi entry.
* ABI defined caller save register and some CSR registers
* to be saved before enter interrupt handler and be restored before return.
*/
.section .text.trap
/* In CLIC mode, the exeception entry must be 64bytes aligned */
.align 6
.global exc_entry
.weak exc_entry
exc_entry:
/* Save the caller saving registers (context) */
SAVE_CONTEXT
/* Save the necessary CSR registers */
SAVE_CSR_CONTEXT
/*
* Set the exception handler function arguments
* argument 1: mcause value
* argument 2: current stack point(SP) value
*/
csrr a0, mcause
mv a1, sp
/*
* TODO: Call the exception handler function
* By default, the function template is provided in
* system_Device.c, you can adjust it as you want
*/
call core_exception_handler
/* Restore the necessary CSR registers */
RESTORE_CSR_CONTEXT
/* Restore the caller saving registers (context) */
RESTORE_CONTEXT
/* Return to regular code */
mret
/**
* \brief Non-Vector Interrupt Entry
* \details
* This function provide common entry functions for handling
* non-vector interrupts
* \remarks
* This function provide a default non-vector interrupt entry.
* ABI defined caller save register and some CSR registers need
* to be saved before enter interrupt handler and be restored before return.
*/
.section .text.irq
/* In CLIC mode, the interrupt entry must be 4bytes aligned */
.align 2
.global irq_entry
.weak irq_entry
/* This label will be set to MTVT2 register */
irq_entry:
/* Save the caller saving registers (context) */
SAVE_CONTEXT
/* Save the necessary CSR registers */
SAVE_CSR_CONTEXT
/* This special CSR read/write operation, which is actually
* claim the CLIC to find its pending highest ID, if the ID
* is not 0, then automatically enable the mstatus.MIE, and
* jump to its vector-entry-label, and update the link register
*/
csrrw ra, CSR_JALMNXTI, ra
/* Critical section with interrupts disabled */
DISABLE_MIE
/* Restore the necessary CSR registers */
RESTORE_CSR_CONTEXT
/* Restore the caller saving registers (context) */
RESTORE_CONTEXT
/* Return to regular code */
mret
/* Default Handler for Exceptions / Interrupts */
.global default_intexc_handler
.weak default_intexc_handler
Undef_Handler:
default_intexc_handler:
1:
j 1b

View File

@ -0,0 +1,306 @@
/*
* 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 startup_hbird.S
* \brief NMSIS Nuclei N/NX Class Core based Core Device Startup File for
* Nuclei HummingBird evaluation SoC which support Nuclei N/NX class cores
* \version V1.00
* \date 17. Dec 2019
*
******************************************************************************/
#include "riscv_encoding.h"
.macro DECLARE_INT_HANDLER INT_HDL_NAME
#if defined(__riscv_xlen) && (__riscv_xlen == 32)
.word \INT_HDL_NAME
#else
.dword \INT_HDL_NAME
#endif
.endm
/*
* === Different Download and Running Mode ===
* flashxip: Program will to be download into flash and run directly in Flash
* flash: Program will be download into flash, when running, program will be copied to ilm/ram and run in ilm/ram
* ilm: Program will be download into ilm/ram and run directly in ilm/ram, program lost when poweroff
*/
/*** Vector Table Code Section ***/
/*
* Put the interrupt vectors in this section according to the run mode:
* FlashXIP: .vtable
* ILM: .vtable
* Flash: .vtable_ilm
*/
#if defined(DOWNLOAD_MODE) && (DOWNLOAD_MODE == DOWNLOAD_MODE_FLASH)
.section .vtable_ilm
#else
.section .vtable
#endif
.weak eclic_msip_handler
.weak eclic_mtip_handler
.weak eclic_irq19_handler
.weak eclic_irq20_handler
.weak eclic_irq21_handler
.weak eclic_irq22_handler
.weak eclic_irq23_handler
.weak eclic_irq24_handler
.weak eclic_irq25_handler
.weak eclic_irq26_handler
.weak eclic_irq27_handler
.weak eclic_irq28_handler
.weak eclic_irq29_handler
.weak eclic_irq30_handler
.weak eclic_irq31_handler
.weak eclic_irq32_handler
.weak eclic_irq33_handler
.weak eclic_irq34_handler
.weak eclic_irq35_handler
.weak eclic_irq36_handler
.weak eclic_irq37_handler
.weak eclic_irq38_handler
.weak eclic_irq39_handler
.weak eclic_irq40_handler
.weak eclic_irq41_handler
.weak eclic_irq42_handler
.weak eclic_irq43_handler
.weak eclic_irq44_handler
.weak eclic_irq45_handler
.weak eclic_irq46_handler
.weak eclic_irq47_handler
.weak eclic_irq48_handler
.weak eclic_irq49_handler
.weak eclic_irq50_handler
.globl vector_base
vector_base:
#if defined(DOWNLOAD_MODE) && (DOWNLOAD_MODE != DOWNLOAD_MODE_FLASH)
j _start /* 0: Reserved, Jump to _start when reset for ILM/FlashXIP mode.*/
.align LOG_REGBYTES /* Need to align 4 byte for RV32, 8 Byte for RV64 */
#else
DECLARE_INT_HANDLER default_intexc_handler /* 0: Reserved, default handler for Flash download mode */
#endif
DECLARE_INT_HANDLER default_intexc_handler /* 1: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 2: Reserved */
DECLARE_INT_HANDLER eclic_msip_handler /* 3: Machine software interrupt */
DECLARE_INT_HANDLER default_intexc_handler /* 4: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 5: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 6: Reserved */
DECLARE_INT_HANDLER eclic_mtip_handler /* 7: Machine timer interrupt */
DECLARE_INT_HANDLER default_intexc_handler /* 8: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 9: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 10: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 11: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 12: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 13: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 14: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 15: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 16: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 17: Reserved */
DECLARE_INT_HANDLER default_intexc_handler /* 18: Reserved */
DECLARE_INT_HANDLER eclic_irq19_handler /* 19: Interrupt 19 */
DECLARE_INT_HANDLER eclic_irq20_handler /* 20: Interrupt 20 */
DECLARE_INT_HANDLER eclic_irq21_handler /* 21: Interrupt 21 */
DECLARE_INT_HANDLER eclic_irq22_handler /* 22: Interrupt 22 */
DECLARE_INT_HANDLER eclic_irq23_handler /* 23: Interrupt 23 */
DECLARE_INT_HANDLER eclic_irq24_handler /* 24: Interrupt 24 */
DECLARE_INT_HANDLER eclic_irq25_handler /* 25: Interrupt 25 */
DECLARE_INT_HANDLER eclic_irq26_handler /* 26: Interrupt 26 */
DECLARE_INT_HANDLER eclic_irq27_handler /* 27: Interrupt 27 */
DECLARE_INT_HANDLER eclic_irq28_handler /* 28: Interrupt 28 */
DECLARE_INT_HANDLER eclic_irq29_handler /* 29: Interrupt 29 */
DECLARE_INT_HANDLER eclic_irq30_handler /* 30: Interrupt 30 */
DECLARE_INT_HANDLER eclic_irq31_handler /* 31: Interrupt 31 */
DECLARE_INT_HANDLER eclic_irq32_handler /* 32: Interrupt 32 */
DECLARE_INT_HANDLER eclic_irq33_handler /* 33: Interrupt 33 */
DECLARE_INT_HANDLER eclic_irq34_handler /* 34: Interrupt 34 */
DECLARE_INT_HANDLER eclic_irq35_handler /* 35: Interrupt 35 */
DECLARE_INT_HANDLER eclic_irq36_handler /* 36: Interrupt 36 */
DECLARE_INT_HANDLER eclic_irq37_handler /* 37: Interrupt 37 */
DECLARE_INT_HANDLER eclic_irq38_handler /* 38: Interrupt 38 */
DECLARE_INT_HANDLER eclic_irq39_handler /* 39: Interrupt 39 */
DECLARE_INT_HANDLER eclic_irq40_handler /* 40: Interrupt 40 */
DECLARE_INT_HANDLER eclic_irq41_handler /* 41: Interrupt 41 */
DECLARE_INT_HANDLER eclic_irq42_handler /* 42: Interrupt 42 */
DECLARE_INT_HANDLER eclic_irq43_handler /* 43: Interrupt 43 */
DECLARE_INT_HANDLER eclic_irq44_handler /* 44: Interrupt 44 */
DECLARE_INT_HANDLER eclic_irq45_handler /* 45: Interrupt 45 */
DECLARE_INT_HANDLER eclic_irq46_handler /* 46: Interrupt 46 */
DECLARE_INT_HANDLER eclic_irq47_handler /* 47: Interrupt 47 */
DECLARE_INT_HANDLER eclic_irq48_handler /* 48: Interrupt 48 */
DECLARE_INT_HANDLER eclic_irq49_handler /* 49: Interrupt 49 */
DECLARE_INT_HANDLER eclic_irq50_handler /* 50: Interrupt 50 */
.section .init
.globl _start
.type _start,@function
/**
* Reset Handler called on controller reset
*/
_start:
/* ===== Startup Stage 1 ===== */
/* Disable Global Interrupt */
csrc CSR_MSTATUS, MSTATUS_MIE
/* Initialize GP and Stack Pointer SP */
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _sp
/*
* Set the the NMI base mnvec to share
* with mtvec by setting CSR_MMISC_CTL
* bit 9 NMI_CAUSE_FFF to 1
*/
li t0, MMISC_CTL_NMI_CAUSE_FFF
csrs CSR_MMISC_CTL, t0
/*
* Intialize ECLIC vector interrupt
* base address mtvt to vector_base
*/
la t0, vector_base
csrw CSR_MTVT, t0
/*
* Set ECLIC non-vector entry to be controlled
* by mtvt2 CSR register.
* Intialize ECLIC non-vector interrupt
* base address mtvt2 to irq_entry.
*/
la t0, irq_entry
csrw CSR_MTVT2, t0
csrs CSR_MTVT2, 0x1
/*
* Set Exception Entry MTVEC to exc_entry
* Due to settings above, Exception and NMI
* will share common entry.
*/
la t0, exc_entry
// la t0, HalTrapEntry
csrw CSR_MTVEC, t0
/* Set the interrupt processing mode to ECLIC mode */
li t0, 0x3f
csrc CSR_MTVEC, t0
csrs CSR_MTVEC, 0x3
/* ===== Startup Stage 2 ===== */
#ifdef __riscv_flen
/* Enable FPU */
li t0, MSTATUS_FS
csrs mstatus, t0
csrw fcsr, x0
#endif
/* Enable mcycle and minstret counter */
csrci CSR_MCOUNTINHIBIT, 0x5
/* ===== Startup Stage 3 ===== */
/*
* Load code section from FLASH to ILM
* when code LMA is different with VMA
*/
la a0, _ilm_lma
la a1, _ilm
/* If the ILM phy-address same as the logic-address, then quit */
beq a0, a1, 2f
la a2, _eilm
bgeu a1, a2, 2f
1:
/* Load code section if necessary */
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/* Load data section */
la a0, _data_lma
la a1, _data
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/* Clear bss section */
la a0, __bss_start
la a1, _end
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
/*
* Call vendor defined SystemInit to
* initialize the micro-controller system
*/
call SystemInit
/* Call global constructors */
la a0, __libc_fini_array
call atexit
/* Call C/C++ constructor start up code */
call __libc_init_array
/* do pre-init steps before main */
call _premain_init
/* ===== Call Main Function ===== */
/* argc = argv = 0 */
li a0, 0
li a1, 0
#ifdef RTOS_RTTHREAD
// Call entry function when using RT-Thread
call entry
#else
call main
#endif
/* do post-main steps after main */
call _postmain_fini
1:
j 1b

View File

@ -0,0 +1,14 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#include <time.h>
#include <stdint.h>
/* Get resolution of clock. */
__WEAK int clock_getres(clockid_t clock_id, struct timespec *res)
{
res->tv_sec = 0;
res->tv_nsec = 1000000000 / SystemCoreClock;
return 0;
}

View File

@ -0,0 +1,21 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#include <time.h>
#include <sys/time.h>
extern int _gettimeofday(struct timeval *tp, void *tzp);
/* Get current value of CLOCK and store it in tp. */
__WEAK int clock_gettime(clockid_t clock_id, struct timespec *tp)
{
struct timeval tv;
int retval = -1;
retval = _gettimeofday(&tv, NULL);
if (retval == 0) {
TIMEVAL_TO_TIMESPEC(&tv, tp);
}
return retval;
}

View File

@ -0,0 +1,10 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#include <time.h>
/* Set CLOCK to value TP. */
__WEAK int clock_settime(clockid_t clock_id, const struct timespec *tp)
{
return -1;
}

View File

@ -0,0 +1,12 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#undef errno
extern int errno;
__WEAK int _close(int fd)
{
errno = EBADF;
return -1;
}

View File

@ -0,0 +1,12 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#undef errno
extern int errno;
__WEAK int _execve(char *name, char **argv, char **env)
{
errno = ENOMEM;
return -1;
}

View File

@ -0,0 +1,9 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
__WEAK void _exit(int fd)
{
while(1) {
__WFI();
}
}

View File

@ -0,0 +1,12 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#undef errno
extern int errno;
__WEAK int _fork(void)
{
errno = EAGAIN;
return -1;
}

View File

@ -0,0 +1,19 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#undef errno
extern int errno;
__WEAK int _fstat(int file, struct stat *st)
{
if ((STDOUT_FILENO == file) || (STDERR_FILENO == file)) {
st->st_mode = S_IFCHR;
return 0;
} else {
errno = EBADF;
return -1;
}
}

View File

@ -0,0 +1,8 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
__WEAK int _getpid(void)
{
return 1;
}

View File

@ -0,0 +1,15 @@
/* See LICENSE of license details. */
#include <errno.h>
#include <sys/time.h>
#include "nuclei_sdk_soc.h"
__WEAK int _gettimeofday(struct timeval *tp, void *tzp)
{
uint64_t cycles;
cycles = __get_rv_cycle();
tp->tv_sec = cycles / SystemCoreClock;
tp->tv_usec = (cycles % SystemCoreClock) * 1000000 / SystemCoreClock;
return 0;
}

View File

@ -0,0 +1,8 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <unistd.h>
__WEAK int _isatty(int fd)
{
return 1;
}

View File

@ -0,0 +1,11 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#undef errno
extern int errno;
__WEAK int _kill(int pid, int sig)
{
errno = EINVAL;
return -1;
}

View File

@ -0,0 +1,12 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#undef errno
extern int errno;
int _link(char *old, char *new)
{
errno = EMLINK;
return -1;
}

View File

@ -0,0 +1,11 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#undef errno
extern int errno;
__WEAK int _lseek(int file, int offset, int whence)
{
return 0;
}

View File

@ -0,0 +1,12 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <errno.h>
#undef errno
extern int errno;
__WEAK int _open(const char *name, int flags, int mode)
{
errno = ENOSYS;
return -1;
}

View File

@ -0,0 +1,22 @@
/* See LICENSE of license details. */
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include "nuclei_sdk_hal.h"
// #define UART_AUTO_ECHO
__WEAK ssize_t _read(int fd, void* ptr, size_t len)
{
if (fd != STDIN_FILENO) {
return -1;
}
uint8_t *readbuf = (uint8_t *)ptr;
readbuf[0] = uart_read(SOC_DEBUG_UART);
#ifdef UART_AUTO_ECHO
uart_write(SOC_DEBUG_UART, readbuf[0]);
#endif
return 1;
}

View File

@ -0,0 +1,19 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <stdint.h>
#include <stddef.h>
#include <unistd.h>
__WEAK void *_sbrk(ptrdiff_t incr)
{
extern char _end[];
extern char _heap_end[];
static char *curbrk = _end;
if ((curbrk + incr < _end) || (curbrk + incr > _heap_end)) {
return (void *)(-1);
}
curbrk += incr;
return (void *)(curbrk - incr);
}

View File

@ -0,0 +1,9 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <sys/stat.h>
__WEAK int _stat(char *file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}

View File

@ -0,0 +1,5 @@
static inline int _stub(int err)
{
return -1;
}

View File

@ -0,0 +1,27 @@
/* See LICENSE of license details. */
#include <sys/times.h>
#include <sys/time.h>
#include <time.h>
#include "nuclei_sdk_soc.h"
extern int _gettimeofday(struct timeval *, void *);
__WEAK clock_t _times(struct tms *buf)
{
static struct timeval t0;
struct timeval t;
long long utime;
/* When called for the first time, initialize t0. */
if (t0.tv_sec == 0 && t0.tv_usec == 0) {
_gettimeofday(&t0, 0);
}
_gettimeofday(&t, 0);
utime = (t.tv_sec - t0.tv_sec) * 1000000 + (t.tv_usec - t0.tv_usec);
buf->tms_utime = utime * CLOCKS_PER_SEC / 1000000;
buf->tms_stime = buf->tms_cstime = buf->tms_cutime = 0;
return buf->tms_utime;
}

View File

@ -0,0 +1,12 @@
/* See LICENSE of license details. */
#include <errno.h>
#include "nuclei_sdk_hal.h"
#undef errno
extern int errno;
__WEAK int _unlink(const char *name)
{
return -1;
}

View File

@ -0,0 +1,13 @@
/* See LICENSE of license details. */
#include "nuclei_sdk_soc.h"
#include <sys/stat.h>
#include <errno.h>
#undef errno
extern int errno;
__WEAK int _wait(int *status)
{
errno = ECHILD;
return -1;
}

View File

@ -0,0 +1,22 @@
/* See LICENSE of license details. */
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include "nuclei_sdk_hal.h"
__WEAK ssize_t _write(int fd, const void* ptr, size_t len)
{
if (!isatty(fd)) {
return -1;
}
const uint8_t *writebuf = (const uint8_t *)ptr;
for (size_t i = 0; i < len; i++) {
if (writebuf[i] == '\n') {
uart_write(SOC_DEBUG_UART, '\r');
}
uart_write(SOC_DEBUG_UART, writebuf[i]);
}
return len;
}

View File

@ -0,0 +1,69 @@
#include "nuclei_sdk_soc.h"
static uint32_t get_timer_freq()
{
return SOC_TIMER_FREQ;
}
uint32_t measure_cpu_freq(uint32_t n)
{
uint32_t start_mcycle, delta_mcycle;
uint32_t start_mtime, delta_mtime;
uint32_t mtime_freq = get_timer_freq();
// Don't start measuruing until we see an mtime tick
uint32_t tmp = (uint32_t)SysTimer_GetLoadValue();
do {
start_mtime = (uint32_t)SysTimer_GetLoadValue();
start_mcycle = __RV_CSR_READ(CSR_MCYCLE);
} while (start_mtime == tmp);
do {
delta_mtime = (uint32_t)SysTimer_GetLoadValue() - start_mtime;
delta_mcycle = __RV_CSR_READ(CSR_MCYCLE) - start_mcycle;
} while (delta_mtime < n);
return (delta_mcycle / delta_mtime) * mtime_freq
+ ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime;
}
uint32_t get_cpu_freq()
{
uint32_t cpu_freq;
// warm up
measure_cpu_freq(1);
// measure for real
cpu_freq = measure_cpu_freq(100);
return cpu_freq;
}
/**
* \brief delay a time in milliseconds
* \details
* provide API for delay
* \param[in] count: count in milliseconds
* \remarks
*/
void delay_1ms(uint32_t count)
{
uint64_t start_mtime, delta_mtime;
uint64_t delay_ticks = (SOC_TIMER_FREQ * (uint64_t)count) / 1000;
start_mtime = SysTimer_GetLoadValue();
do {
delta_mtime = SysTimer_GetLoadValue() - start_mtime;
} while (delta_mtime < delay_ticks);
}
#ifdef SIMULATION_XLSPIKE
// never return for xlspike
void xlspike_exit(int status)
{
// pass exit status via rxfifo register
UART0->RXFIFO = status;
uart_write(UART0, 4);
}
#endif

View File

@ -0,0 +1,405 @@
/*
* Copyright (c) 2009-2018 Arm Limited. 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.
*/
/******************************************************************************
* @file system_hbird.c
* @brief NMSIS Nuclei Core Device Peripheral Access Layer Source File for
* Nuclei HummingBird evaluation SoC which support Nuclei N/NX class cores
* @version V1.00
* @date 22. Nov 2019
******************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include "nuclei_sdk_hal.h"
#include "los_arch_interrupt.h"
#include "los_debug.h"
/*----------------------------------------------------------------------------
Define clocks
*----------------------------------------------------------------------------*/
/* ToDo: add here your necessary defines for device initialization
following is an example for different system frequencies */
#ifndef SYSTEM_CLOCK
#define SYSTEM_CLOCK (80000000UL)
#endif
/**
* \defgroup NMSIS_Core_SystemConfig System Device Configuration
* \brief Functions for system and clock setup available in system_<device>.c.
* \details
* Nuclei provides a template file **system_Device.c** that must be adapted by
* the silicon vendor to match their actual device. As a <b>minimum requirement</b>,
* this file must provide:
* - A device-specific system configuration function, \ref SystemInit.
* - A global variable that contains the system frequency, \ref SystemCoreClock.
* - A global eclic configuration initialization, \ref ECLIC_Init.
* - Global c library \ref _init and \ref _fini functions called right before calling main function.
* - Vendor customized interrupt, exception and nmi handling code, see \ref NMSIS_Core_IntExcNMI_Handling
*
* The file configures the device and, typically, initializes the oscillator (PLL) that is part
* of the microcontroller device. This file might export other functions or variables that provide
* a more flexible configuration of the microcontroller system.
*
* And this file also provided common interrupt, exception and NMI exception handling framework template,
* Silicon vendor can customize these template code as they want.
*
* \note Please pay special attention to the static variable \c SystemCoreClock. This variable might be
* used throughout the whole system initialization and runtime to calculate frequency/time related values.
* Thus one must assure that the variable always reflects the actual system clock speed.
*
* \attention
* Be aware that a value stored to \c SystemCoreClock during low level initializaton (i.e. \c SystemInit()) might get
* overwritten by C libray startup code and/or .bss section initialization.
* Thus its highly recommended to call \ref SystemCoreClockUpdate at the beginning of the user \c main() routine.
*
* @{
*/
/*----------------------------------------------------------------------------
System Core Clock Variable
*----------------------------------------------------------------------------*/
/* ToDo: initialize SystemCoreClock with the system core clock frequency value
achieved after system intitialization.
This means system core clock frequency after call to SystemInit() */
/**
* \brief Variable to hold the system core clock value
* \details
* Holds the system core clock, which is the system clock frequency supplied to the SysTick
* timer and the processor core clock. This variable can be used by debuggers to query the
* frequency of the debug timer or to configure the trace clock speed.
*
* \attention
* Compilers must be configured to avoid removing this variable in case the application
* program is not using it. Debugging systems require the variable to be physically
* present in memory so that it can be examined to configure the debugger.
*/
uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Clock Frequency (Core Clock) */
/*----------------------------------------------------------------------------
Clock functions
*----------------------------------------------------------------------------*/
/**
* \brief Function to update the variable \ref SystemCoreClock
* \details
* Updates the variable \ref SystemCoreClock and must be called whenever the core clock is changed
* during program execution. The function evaluates the clock register settings and calculates
* the current core clock.
*/
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
{
/* ToDo: add code to calculate the system frequency based upon the current
* register settings.
* Note: This function can be used to retrieve the system core clock frequeny
* after user changed register settings.
*/
SystemCoreClock = SYSTEM_CLOCK;
}
/**
* \brief Function to Initialize the system.
* \details
* Initializes the microcontroller system. Typically, this function configures the
* oscillator (PLL) that is part of the microcontroller device. For systems
* with a variable clock speed, it updates the variable \ref SystemCoreClock.
* SystemInit is called from the file <b>startup<i>_device</i></b>.
*/
void SystemInit (void)
{
/* ToDo: add code to initialize the system
* Warn: do not use global variables because this function is called before
* reaching pre-main. RW section maybe overwritten afterwards.
*/
SystemCoreClock = SYSTEM_CLOCK;
}
/**
* \defgroup NMSIS_Core_IntExcNMI_Handling Interrupt and Exception and NMI Handling
* \brief Functions for interrupt, exception and nmi handle available in system_<device>.c.
* \details
* Nuclei provide a template for interrupt, exception and NMI handling. Silicon Vendor could adapat according
* to their requirement. Silicon vendor could implement interface for different exception code and
* replace current implementation.
*
* @{
*/
/** \brief Max exception handler number, don't include the NMI(0xFFF) one */
#define MAX_SYSTEM_EXCEPTION_NUM 12
/**
* \brief Store the exception handlers for each exception ID
* \note
* - This SystemExceptionHandlers are used to store all the handlers for all
* the exception codes Nuclei N/NX core provided.
* - Exception code 0 - 11, totally 12 exceptions are mapped to SystemExceptionHandlers[0:11]
* - Exception for NMI is also re-routed to exception handling(exception code 0xFFF) in startup code configuration, the handler itself is mapped to SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM]
*/
static unsigned long SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM+1];
/**
* \brief Exception Handler Function Typedef
* \note
* This typedef is only used internal in this system_<Device>.c file.
* It is used to do type conversion for registered exception handler before calling it.
*/
typedef void (*EXC_HANDLER) (unsigned long mcause, unsigned long sp);
/**
* \brief System Default Exception Handler
* \details
* This function provided a default exception and NMI handling code for all exception ids.
* By default, It will just print some information for debug, Vendor can customize it according to its requirements.
*/
static void system_default_exception_handler(unsigned long mcause, unsigned long sp)
{
/* TODO: Uncomment this if you have implement printf function */
printf("MCAUSE: 0x%lx\r\n", mcause);
printf("MEPC : 0x%lx\r\n", __RV_CSR_READ(CSR_MEPC));
printf("MTVAL : 0x%lx\r\n", __RV_CSR_READ(CSR_MBADADDR));
while(1);
}
/**
* \brief Initialize all the default core exception handlers
* \details
* The core exception handler for each exception id will be initialized to \ref system_default_exception_handler.
* \note
* Called in \ref _init function, used to initialize default exception handlers for all exception IDs
*/
static void Exception_Init(void)
{
for (int i = 0; i < MAX_SYSTEM_EXCEPTION_NUM+1; i++) {
SystemExceptionHandlers[i] = (unsigned long)system_default_exception_handler;
}
}
/**
* \brief Register an exception handler for exception code EXCn
* \details
* * For EXCn < \ref MAX_SYSTEM_EXCEPTION_NUM, it will be registered into SystemExceptionHandlers[EXCn-1].
* * For EXCn == NMI_EXCn, it will be registered into SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM].
* \param EXCn See \ref EXCn_Type
* \param exc_handler The exception handler for this exception code EXCn
*/
void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler)
{
if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn >= 0)) {
SystemExceptionHandlers[EXCn] = exc_handler;
} else if (EXCn == NMI_EXCn) {
SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM] = exc_handler;
}
}
/**
* \brief Get current exception handler for exception code EXCn
* \details
* * For EXCn < \ref MAX_SYSTEM_EXCEPTION_NUM, it will return SystemExceptionHandlers[EXCn-1].
* * For EXCn == NMI_EXCn, it will return SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM].
* \param EXCn See \ref EXCn_Type
* \return Current exception handler for exception code EXCn, if not found, return 0.
*/
unsigned long Exception_Get_EXC(uint32_t EXCn)
{
if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn >= 0)) {
return SystemExceptionHandlers[EXCn];
} else if (EXCn == NMI_EXCn) {
return SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM];
} else {
return 0;
}
}
/**
* \brief Common NMI and Exception handler entry
* \details
* This function provided a command entry for NMI and exception. Silicon Vendor could modify
* this template implementation according to requirement.
* \remarks
* - RISCV provided common entry for all types of exception. This is proposed code template
* for exception entry function, Silicon Vendor could modify the implementation.
* - For the core_exception_handler template, we provided exception register function \ref Exception_Register_EXC
* which can help developer to register your exception handler for specific exception number.
*/
uint32_t core_exception_handler(unsigned long mcause, unsigned long sp)
{
uint32_t EXCn = (uint32_t)(mcause & 0X00000fff);
EXC_HANDLER exc_handler;
PRINTK("----------------All Task infomation ------------\r\n");
HalDisplayTaskInfo();
PRINTK("---------------exc handler infomation -----------\r\n");
if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn >= 0)) {
exc_handler = (EXC_HANDLER)SystemExceptionHandlers[EXCn];
} else if (EXCn == NMI_EXCn) {
exc_handler = (EXC_HANDLER)SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM];
} else {
exc_handler = (EXC_HANDLER)system_default_exception_handler;
}
if (exc_handler != NULL) {
exc_handler(mcause, sp);
}
return 0;
}
/** @} */ /* End of Doxygen Group NMSIS_Core_ExceptionAndNMI */
/** Banner Print for Nuclei SDK */
void SystemBannerPrint(void)
{
#if defined(NUCLEI_BANNER) && (NUCLEI_BANNER == 1)
#ifndef DOWNLOAD_MODE
#error DOWNLOAD_MODE is not defined via build system, please check!
#endif
const char* download_modes[] = {"FLASHXIP", "FLASH", "ILM", "DDR"};
printf("Nuclei SDK Build Time: %s, %s\r\n", __DATE__, __TIME__);
printf("Download Mode: %s\r\n", download_modes[DOWNLOAD_MODE]);
printf("CPU Frequency %lu Hz\r\n", SystemCoreClock);
#endif
}
/**
* \brief initialize eclic config
* \details
* ECLIC needs be initialized after boot up,
* Vendor could also change the initialization
* configuration.
*/
void ECLIC_Init(void)
{
/* Global Configuration about MTH and NLBits.
* TODO: Please adapt it according to your system requirement.
* This function is called in _init function */
ECLIC_SetMth(0);
ECLIC_SetCfgNlbits(__ECLIC_INTCTLBITS);
}
/**
* \brief Initialize a specific IRQ and register the handler
* \details
* This function set vector mode, trigger mode and polarity, interrupt level and priority,
* assign handler for specific IRQn.
* \param [in] IRQn NMI interrupt handler address
* \param [in] shv \ref ECLIC_NON_VECTOR_INTERRUPT means non-vector mode, and \ref ECLIC_VECTOR_INTERRUPT is vector mode
* \param [in] trig_mode see \ref ECLIC_TRIGGER_Type
* \param [in] lvl interupt level
* \param [in] priority interrupt priority
* \param [in] handler interrupt handler, if NULL, handler will not be installed
* \return -1 means invalid input parameter. 0 means successful.
* \remarks
* - This function use to configure specific eclic interrupt and register its interrupt handler and enable its interrupt.
* - If the vector table is placed in read-only section(FLASHXIP mode), handler could not be installed
*/
int32_t ECLIC_Register_IRQ(IRQn_Type IRQn, uint8_t shv, ECLIC_TRIGGER_Type trig_mode, uint8_t lvl, uint8_t priority, void *handler)
{
if ((IRQn > SOC_INT_MAX) || (shv > ECLIC_VECTOR_INTERRUPT) \
|| (trig_mode > ECLIC_NEGTIVE_EDGE_TRIGGER )) {
return -1;
}
/* set interrupt vector mode */
ECLIC_SetShvIRQ(IRQn, shv);
/* set interrupt trigger mode and polarity */
ECLIC_SetTrigIRQ(IRQn, trig_mode);
/* set interrupt level */
ECLIC_SetLevelIRQ(IRQn, lvl);
/* set interrupt priority */
ECLIC_SetPriorityIRQ(IRQn, priority);
if (handler != NULL) {
/* set interrupt handler entry to vector table */
ECLIC_SetVector(IRQn, (rv_csr_t)handler);
}
/* enable interrupt */
ECLIC_EnableIRQ(IRQn);
return 0;
}
/** @} */ /* End of Doxygen Group NMSIS_Core_ExceptionAndNMI */
/**
* \brief early init function before main
* \details
* This function is executed right before main function.
* For RISC-V gnu toolchain, _init function might not be called
* by __libc_init_array function, so we defined a new function
* to do initialization
*/
void _premain_init(void)
{
/* TODO: Add your own initialization code here, called before main */
/* __ICACHE_PRESENT and __DCACHE_PRESENT are defined in hbird.h */
#if defined(__ICACHE_PRESENT) && __ICACHE_PRESENT == 1
EnableICache();
#endif
#if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT == 1
EnableDCache();
#endif
SystemCoreClock = get_cpu_freq();
gpio_iof_config(GPIO, IOF0_UART0_MASK, IOF_SEL_0);
uart_init(SOC_DEBUG_UART, 115200);
/* Display banner after UART initialized */
SystemBannerPrint();
/* Initialize exception default handlers */
Exception_Init();
/* ECLIC initilization, mainly MTH and NLBIT */
ECLIC_Init();
}
/**
* \brief finish function after main
* \param [in] status status code return from main
* \details
* This function is executed right after main function.
* For RISC-V gnu toolchain, _fini function might not be called
* by __libc_fini_array function, so we defined a new function
* to do initialization
*/
void _postmain_fini(int status)
{
/* TODO: Add your own finishing code here, called after main */
#ifdef SIMULATION_XLSPIKE
extern void xlspike_exit(int status);
xlspike_exit(status);
#endif
}
/**
* \brief _init function called in __libc_init_array()
* \details
* This `__libc_init_array()` function is called during startup code,
* user need to implement this function, otherwise when link it will
* error init.c:(.text.__libc_init_array+0x26): undefined reference to `_init'
* \note
* Please use \ref _premain_init function now
*/
void _init(void)
{
/* Don't put any code here, please use _premain_init now */
}
/**
* \brief _fini function called in __libc_fini_array()
* \details
* This `__libc_fini_array()` function is called when exit main.
* user need to implement this function, otherwise when link it will
* error fini.c:(.text.__libc_fini_array+0x28): undefined reference to `_fini'
* \note
* Please use \ref _postmain_fini function now
*/
void _fini(void)
{
/* Don't put any code here, please use _postmain_fini now */
}
/** @} */ /* End of Doxygen Group NMSIS_Core_SystemAndClock */

View File

@ -0,0 +1,35 @@
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include "nuclei_sdk_hal.h"
#include "task_sample.h"
#include "target_config.h"
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN Init */
RunTaskSample();
while (1)
{
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 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.
*
* Description: Provide a task example.
*/
#include "task_sample.h"
#include "los_config.h"
#include "los_debug.h"
#include "los_interrupt.h"
#include "los_task.h"
#include "los_tick.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cpluscplus */
#endif /* __cpluscplus */
UINT8 __attribute__ ((aligned (8))) g_memStart[OS_SYS_MEM_SIZE];
VOID TaskSampleEntry2(VOID)
{
while (1) {
LOS_TaskDelay(10000); /* 10 Seconds */
printf("TaskSampleEntry2 running...\n");
}
}
VOID TaskSampleEntry1(VOID)
{
while (1) {
LOS_TaskDelay(2000); /* 2 Seconds */
printf("TaskSampleEntry1 running...\n");
}
}
VOID TaskSample(VOID)
{
UINT32 uwRet;
UINT32 taskID1;
UINT32 taskID2;
TSK_INIT_PARAM_S stTask = {0};
stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry1;
stTask.uwStackSize = 0x1000;
stTask.pcName = "TaskSampleEntry1";
stTask.usTaskPrio = 6; /* Os task priority is 6 */
uwRet = LOS_TaskCreate(&taskID1, &stTask);
if (uwRet != LOS_OK) {
printf("Task1 create failed\n");
}
stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry2;
stTask.uwStackSize = 0x1000;
stTask.pcName = "TaskSampleEntry2";
stTask.usTaskPrio = 7; /* Os task priority is 7 */
uwRet = LOS_TaskCreate(&taskID2, &stTask);
if (uwRet != LOS_OK) {
printf("Task2 create failed\n");
}
}
VOID RunTaskSample(VOID)
{
UINT32 ret;
ret = LOS_KernelInit();
if (ret == LOS_OK) {
TaskSample();
LOS_Start();
}
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cpluscplus */
#endif /* __cpluscplus */

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 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
*
* Description: Provide a task example.
*/
#ifndef _TASKSAMPLE_H
#define _TASKSAMPLE_H
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cpluscplus */
#endif /* __cpluscplus */
VOID RunTaskSample(VOID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cpluscplus */
#endif /* __cpluscplus */
#endif /* _TASKSAMPLE_H */

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB