add t-head smart-evb bsp, and risc-v cpu e906

This commit is contained in:
chenzx 2020-09-11 10:11:25 +08:00
parent 5a6a7e391e
commit 60287b69fd
46 changed files with 10424 additions and 3 deletions

417
bsp/thead-smart/.config Normal file
View File

@ -0,0 +1,417 @@
#
# Automatically generated file; DO NOT EDIT.
# RT-Thread Configuration
#
#
# RT-Thread Kernel
#
CONFIG_RT_NAME_MAX=8
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMP is not set
CONFIG_RT_ALIGN_SIZE=4
# CONFIG_RT_THREAD_PRIORITY_8 is not set
CONFIG_RT_THREAD_PRIORITY_32=y
# CONFIG_RT_THREAD_PRIORITY_256 is not set
CONFIG_RT_THREAD_PRIORITY_MAX=32
CONFIG_RT_TICK_PER_SECOND=100
CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_USING_HOOK=y
CONFIG_RT_USING_IDLE_HOOK=y
CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
CONFIG_IDLE_THREAD_STACK_SIZE=512
# CONFIG_RT_USING_TIMER_SOFT is not set
# CONFIG_RT_DEBUG is not set
#
# Inter-Thread communication
#
CONFIG_RT_USING_SEMAPHORE=y
CONFIG_RT_USING_MUTEX=y
CONFIG_RT_USING_EVENT=y
CONFIG_RT_USING_MAILBOX=y
CONFIG_RT_USING_MESSAGEQUEUE=y
# CONFIG_RT_USING_SIGNALS is not set
#
# Memory Management
#
CONFIG_RT_USING_MEMPOOL=y
# CONFIG_RT_USING_MEMHEAP is not set
# CONFIG_RT_USING_NOHEAP is not set
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
# CONFIG_RT_USING_MEMTRACE is not set
CONFIG_RT_USING_HEAP=y
#
# Kernel Device Object
#
CONFIG_RT_USING_DEVICE=y
# CONFIG_RT_USING_DEVICE_OPS is not set
# CONFIG_RT_USING_INTERRUPT_INFO is not set
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
CONFIG_RT_VER_NUM=0x40003
#
# RT-Thread CPU arch and features
#
# CONFIG_ARCH_CSKY is not set
#
# risc-v arch
#
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_RISCV_32=y
# CONFIG_ARCH_RISCV_64 is not set
CONFIG_ARCH_RISCV_FPU=y
CONFIG_ARCH_RISCV_FPU_S=y
# CONFIG_ARCH_RISCV_FPU_D is not set
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
#
# RT-Thread Components
#
CONFIG_RT_USING_COMPONENTS_INIT=y
CONFIG_RT_USING_USER_MAIN=y
CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
CONFIG_RT_MAIN_THREAD_PRIORITY=10
#
# C++ features
#
# CONFIG_RT_USING_CPLUSPLUS is not set
#
# Command shell
#
CONFIG_RT_USING_FINSH=y
CONFIG_FINSH_THREAD_NAME="tshell"
CONFIG_FINSH_USING_HISTORY=y
CONFIG_FINSH_HISTORY_LINES=1
CONFIG_FINSH_USING_SYMTAB=y
CONFIG_FINSH_USING_DESCRIPTION=y
# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
CONFIG_FINSH_THREAD_PRIORITY=20
CONFIG_FINSH_THREAD_STACK_SIZE=2048
CONFIG_FINSH_CMD_SIZE=80
# CONFIG_FINSH_USING_AUTH is not set
CONFIG_FINSH_USING_MSH=y
CONFIG_FINSH_USING_MSH_DEFAULT=y
CONFIG_FINSH_USING_MSH_ONLY=y
CONFIG_FINSH_ARG_MAX=10
#
# Device virtual file system
#
# CONFIG_RT_USING_DFS is not set
#
# Device Drivers
#
CONFIG_RT_USING_DEVICE_IPC=y
CONFIG_RT_PIPE_BUFSZ=512
# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
CONFIG_RT_USING_SERIAL=y
CONFIG_RT_SERIAL_USING_DMA=y
CONFIG_RT_SERIAL_RB_BUFSZ=64
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_ADC is not set
# CONFIG_RT_USING_DAC is not set
# CONFIG_RT_USING_PWM is not set
# CONFIG_RT_USING_MTD_NOR is not set
# CONFIG_RT_USING_MTD_NAND is not set
# CONFIG_RT_USING_PM is not set
# CONFIG_RT_USING_RTC is not set
# CONFIG_RT_USING_SDIO is not set
# CONFIG_RT_USING_SPI is not set
# CONFIG_RT_USING_WDT is not set
# CONFIG_RT_USING_AUDIO is not set
# CONFIG_RT_USING_SENSOR is not set
# CONFIG_RT_USING_TOUCH is not set
# CONFIG_RT_USING_HWCRYPTO is not set
# CONFIG_RT_USING_PULSE_ENCODER is not set
# CONFIG_RT_USING_INPUT_CAPTURE is not set
# CONFIG_RT_USING_WIFI is not set
#
# Using USB
#
# CONFIG_RT_USING_USB_HOST is not set
# CONFIG_RT_USING_USB_DEVICE is not set
#
# POSIX layer and C standard library
#
# CONFIG_RT_USING_LIBC is not set
# CONFIG_RT_USING_PTHREADS is not set
# CONFIG_RT_LIBC_USING_TIME is not set
#
# Network
#
#
# Socket abstraction layer
#
# CONFIG_RT_USING_SAL is not set
#
# Network interface device
#
# CONFIG_RT_USING_NETDEV is not set
#
# light weight TCP/IP stack
#
# CONFIG_RT_USING_LWIP is not set
#
# AT commands
#
# CONFIG_RT_USING_AT is not set
#
# VBUS(Virtual Software BUS)
#
# CONFIG_RT_USING_VBUS is not set
#
# Utilities
#
# CONFIG_RT_USING_RYM is not set
# CONFIG_RT_USING_ULOG is not set
# CONFIG_RT_USING_UTEST is not set
#
# RT-Thread online packages
#
#
# IoT - internet of things
#
# CONFIG_PKG_USING_PAHOMQTT is not set
# CONFIG_PKG_USING_UMQTT is not set
# CONFIG_PKG_USING_WEBCLIENT is not set
# CONFIG_PKG_USING_WEBNET is not set
# CONFIG_PKG_USING_MONGOOSE is not set
# CONFIG_PKG_USING_MYMQTT is not set
# CONFIG_PKG_USING_KAWAII_MQTT is not set
# CONFIG_PKG_USING_BC28_MQTT is not set
# CONFIG_PKG_USING_WEBTERMINAL is not set
# CONFIG_PKG_USING_CJSON is not set
# CONFIG_PKG_USING_JSMN is not set
# CONFIG_PKG_USING_LIBMODBUS is not set
# CONFIG_PKG_USING_FREEMODBUS is not set
# CONFIG_PKG_USING_LJSON is not set
# CONFIG_PKG_USING_EZXML is not set
# CONFIG_PKG_USING_NANOPB is not set
#
# Wi-Fi
#
#
# Marvell WiFi
#
# CONFIG_PKG_USING_WLANMARVELL is not set
#
# Wiced WiFi
#
# CONFIG_PKG_USING_WLAN_WICED is not set
# CONFIG_PKG_USING_RW007 is not set
# CONFIG_PKG_USING_COAP is not set
# CONFIG_PKG_USING_NOPOLL is not set
# CONFIG_PKG_USING_NETUTILS is not set
# CONFIG_PKG_USING_CMUX is not set
# CONFIG_PKG_USING_PPP_DEVICE is not set
# CONFIG_PKG_USING_AT_DEVICE is not set
# CONFIG_PKG_USING_ATSRV_SOCKET is not set
# CONFIG_PKG_USING_WIZNET is not set
#
# IoT Cloud
#
# CONFIG_PKG_USING_ONENET is not set
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
# CONFIG_PKG_USING_ALI_IOTKIT is not set
# CONFIG_PKG_USING_AZURE is not set
# CONFIG_PKG_USING_TENCENT_IOTHUB is not set
# CONFIG_PKG_USING_JIOT-C-SDK is not set
# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
# CONFIG_PKG_USING_JOYLINK is not set
# CONFIG_PKG_USING_NIMBLE is not set
# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
# CONFIG_PKG_USING_IPMSG is not set
# CONFIG_PKG_USING_LSSDP is not set
# CONFIG_PKG_USING_AIRKISS_OPEN is not set
# CONFIG_PKG_USING_LIBRWS is not set
# CONFIG_PKG_USING_TCPSERVER is not set
# CONFIG_PKG_USING_PROTOBUF_C is not set
# CONFIG_PKG_USING_ONNX_PARSER is not set
# CONFIG_PKG_USING_ONNX_BACKEND is not set
# CONFIG_PKG_USING_DLT645 is not set
# CONFIG_PKG_USING_QXWZ is not set
# CONFIG_PKG_USING_SMTP_CLIENT is not set
# CONFIG_PKG_USING_ABUP_FOTA is not set
# CONFIG_PKG_USING_LIBCURL2RTT is not set
# CONFIG_PKG_USING_CAPNP is not set
# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
# CONFIG_PKG_USING_AGILE_TELNET is not set
#
# security packages
#
# CONFIG_PKG_USING_MBEDTLS is not set
# CONFIG_PKG_USING_libsodium is not set
# CONFIG_PKG_USING_TINYCRYPT is not set
# CONFIG_PKG_USING_TFM is not set
#
# language packages
#
# CONFIG_PKG_USING_LUA is not set
# CONFIG_PKG_USING_JERRYSCRIPT is not set
# CONFIG_PKG_USING_MICROPYTHON is not set
#
# multimedia packages
#
# CONFIG_PKG_USING_OPENMV is not set
# CONFIG_PKG_USING_MUPDF is not set
# CONFIG_PKG_USING_STEMWIN is not set
# CONFIG_PKG_USING_WAVPLAYER is not set
# CONFIG_PKG_USING_TJPGD is not set
#
# tools packages
#
# CONFIG_PKG_USING_CMBACKTRACE is not set
# CONFIG_PKG_USING_EASYFLASH is not set
# CONFIG_PKG_USING_EASYLOGGER is not set
# CONFIG_PKG_USING_SYSTEMVIEW is not set
# CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_QRCODE is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
# CONFIG_PKG_USING_ADBD is not set
# CONFIG_PKG_USING_COREMARK is not set
# CONFIG_PKG_USING_DHRYSTONE is not set
# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
# CONFIG_PKG_USING_BS8116A is not set
# CONFIG_PKG_USING_URLENCODE is not set
#
# system packages
#
# CONFIG_PKG_USING_GUIENGINE is not set
# CONFIG_PKG_USING_CAIRO is not set
# CONFIG_PKG_USING_PIXMAN is not set
# CONFIG_PKG_USING_LWEXT4 is not set
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_FAL is not set
# CONFIG_PKG_USING_FLASHDB is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
# CONFIG_PKG_USING_CMSIS is not set
# CONFIG_PKG_USING_DFS_YAFFS is not set
# CONFIG_PKG_USING_LITTLEFS is not set
# CONFIG_PKG_USING_THREAD_POOL is not set
# CONFIG_PKG_USING_ROBOTS is not set
# CONFIG_PKG_USING_EV is not set
# CONFIG_PKG_USING_SYSWATCH is not set
# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
# CONFIG_PKG_USING_PLCCORE is not set
#
# peripheral libraries and drivers
#
# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_SHT3X is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ICM20608 is not set
# CONFIG_PKG_USING_U8G2 is not set
# CONFIG_PKG_USING_BUTTON is not set
# CONFIG_PKG_USING_PCF8574 is not set
# CONFIG_PKG_USING_SX12XX is not set
# CONFIG_PKG_USING_SIGNAL_LED is not set
# CONFIG_PKG_USING_LEDBLINK is not set
# CONFIG_PKG_USING_LITTLED is not set
# CONFIG_PKG_USING_LKDGUI is not set
# CONFIG_PKG_USING_NRF5X_SDK is not set
# CONFIG_PKG_USING_NRFX is not set
# CONFIG_PKG_USING_WM_LIBRARIES is not set
# CONFIG_PKG_USING_KENDRYTE_SDK is not set
# CONFIG_PKG_USING_INFRARED is not set
# CONFIG_PKG_USING_ROSSERIAL is not set
# CONFIG_PKG_USING_AGILE_BUTTON is not set
# CONFIG_PKG_USING_AGILE_LED is not set
# CONFIG_PKG_USING_AT24CXX is not set
# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_PCA9685 is not set
# CONFIG_PKG_USING_I2C_TOOLS is not set
# CONFIG_PKG_USING_NRF24L01 is not set
# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
# CONFIG_PKG_USING_MAX17048 is not set
# CONFIG_PKG_USING_RPLIDAR is not set
# CONFIG_PKG_USING_AS608 is not set
# CONFIG_PKG_USING_RC522 is not set
# CONFIG_PKG_USING_EMBARC_BSP is not set
# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
# CONFIG_PKG_USING_MULTI_RTIMER is not set
# CONFIG_PKG_USING_MAX7219 is not set
# CONFIG_PKG_USING_BEEP is not set
# CONFIG_PKG_USING_EASYBLINK is not set
# CONFIG_PKG_USING_PMS_SERIES is not set
# CONFIG_PKG_USING_NUCLEI_SDK is not set
# CONFIG_PKG_USING_CAN_YMODEM is not set
#
# miscellaneous packages
#
# CONFIG_PKG_USING_LIBCSV is not set
# CONFIG_PKG_USING_OPTPARSE is not set
# CONFIG_PKG_USING_FASTLZ is not set
# CONFIG_PKG_USING_MINILZO is not set
# CONFIG_PKG_USING_QUICKLZ is not set
# CONFIG_PKG_USING_MULTIBUTTON is not set
# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
# CONFIG_PKG_USING_CANFESTIVAL is not set
# CONFIG_PKG_USING_ZLIB is not set
# CONFIG_PKG_USING_DSTR is not set
# CONFIG_PKG_USING_TINYFRAME is not set
# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
# CONFIG_PKG_USING_DIGITALCTRL is not set
# CONFIG_PKG_USING_UPACKER is not set
# CONFIG_PKG_USING_UPARAM is not set
#
# samples: kernel and components samples
#
# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
# CONFIG_PKG_USING_HELLO is not set
# CONFIG_PKG_USING_VI is not set
# CONFIG_PKG_USING_NNOM is not set
# CONFIG_PKG_USING_LIBANN is not set
# CONFIG_PKG_USING_ELAPACK is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
# CONFIG_PKG_USING_VT100 is not set
# CONFIG_PKG_USING_ULAPACK is not set
# CONFIG_PKG_USING_UKAL is not set
CONFIG_SOC_THEAD_SMART=y
CONFIG_RT_USING_UART1=y

36
bsp/thead-smart/Kconfig Normal file
View File

@ -0,0 +1,36 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config RTT_DIR
string
option env="RTT_ROOT"
default "../.."
# you can change the RTT_ROOT default "../.." to your rtthread_root,
# example : default "F:/git_repositories/rt-thread"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
config SOC_THEAD_SMART
bool
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y
if RT_USING_SERIAL
config RT_USING_UART1
bool "Using uart1"
default y
endif

45
bsp/thead-smart/README.md Normal file
View File

@ -0,0 +1,45 @@
# T-HEAD SMART-EVB Introduction
SMART-EVB is a development board provided by T-HEAD, based on FPGA to provide implementation, integrating T-HEAD's RISC-V CPU (eg. E902/E906/C906) and C-SKY CPU (eg. E805/E804/E803/E802 ), integrates basic peripheral resources such as GPIO/TIMER/UART/RAM.
##The main resources on board are as follows:
1. SMART-EVB for E906/E906F/E906FD
| res | description |
| -- | -- |
|ISA | RISCV |
|CPU | E906 |
|FREQ| 20MHz |
|SRAM| 768KB |
2. SMART-EVB for E804/E804F/E804D
| res | description |
| -- | -- |
|ISA | C-SKY |
|CPU | E804 |
|FREQ| 20MHz |
|SRAM| 768KB |
# Compile T-HEAD BSP
SMART-EVB BSP supports GCC compiler, the version information is:
1. SMART-EVB for E906/E906F/E906FD
| IDE/Compiler| version|
| - | - |
| GCC | gcc version 8.4.0 (C-SKY RISCV Tools V1.9.6 B20200616) |
# run smart-evb bsp
1. Connect JTAG
2. Connect the serial port
3. riscv64-unknown-elf-gdb rtthread-e906f.elf
run log as follows:
```
\ | /
- RT - Thread Operating System
/ | \ 4.0.3 build Sep 2 2020
2006 - 2020 Copyright by rt-thread team
msh >
```

View File

@ -0,0 +1,14 @@
# for module compiling
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

View File

@ -0,0 +1,33 @@
import os
import sys
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = 'rtthread-' + rtconfig.CPU + '.' + rtconfig.TARGET_EXT
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
# add --start-group and --end-group for GNU GCC
env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS -Wl,--start-group $_LIBFLAGS -Wl,--end-group'
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
# make a building
DoBuilding(TARGET, objs)

View File

@ -0,0 +1,13 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = GetCurrentDir()
CCFLAGS = ' -c -ffunction-sections'
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH, CCFLAGS=CCFLAGS)
Return('group')

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen first version
*/
#include <rtthread.h>
int main(void)
{
return 0;
}
/*@}*/

View File

@ -0,0 +1,13 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = GetCurrentDir()
# add the general drivers.
src = Glob("*.c") + Glob("*.cpp") + Glob("*.S")
CPPPATH = [cwd]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen add T-HEAD header file csi_core.h
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "csi_core.h"
#include "drv_usart.h"
extern int __bss_end__;
#define SYS_HEAP_BEGIN (&__bss_end__)
#include "core_rv32.h"
extern usart_handle_t console_handle;
extern void ioreuse_initial(void);
/**
* This function will initial smartl-evb(e906) board.
*/
void rt_hw_board_init(void)
{
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
/* initialize hardware usart */
rt_hw_usart_init();
#ifdef RT_USING_CONSOLE
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#ifdef RT_USING_HEAP
rt_system_heap_init((void *)SYS_HEAP_BEGIN, (void *)E906FD_IRAM_END);
#endif
}
/*@}*/

View File

@ -0,0 +1,18 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen add E906 ram size
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#define APB_DEFAULT_FREQ 20000000 /* Hz */
#define E906FD_IRAM_SIZE 128
#define E906FD_IRAM_END (0x20000000 + E906FD_IRAM_SIZE * 1024)
#endif /* __BOARD_H__ */

View File

@ -0,0 +1,207 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen first implementation
*/
#include <rtthread.h>
#ifdef RT_USING_CONSOLE
#include <rthw.h>
#include <rtdevice.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "board.h"
#include "soc.h"
#include "ck_usart.h"
#include "drv_usart.h"
#include "pin_name.h"
__attribute__((isr)) void ck_usart0_irqhandler(void);
struct
{
uint32_t base;
uint32_t irq;
void *handler;
}
const sg_usart_config[CONFIG_USART_NUM] =
{
{CSKY_UART_BASE, UART_IRQn, ck_usart0_irqhandler},
};
int32_t target_usart_init(int32_t idx, uint32_t *base, uint32_t *irq, void **handler)
{
if (idx >= CONFIG_USART_NUM)
{
return -1;
}
if (base != NULL)
{
*base = sg_usart_config[idx].base;
}
if (irq != NULL)
{
*irq = sg_usart_config[idx].irq;
}
if (handler != NULL)
{
*handler = sg_usart_config[idx].handler;
}
return idx;
}
#ifdef RT_USING_UART1
#define UART_TXD1 PA10_TXD1_PWM1_XX_SIROUT1
#define UART_RXD1 PA11_RXD1_PWM2_XX_SIRIN1
static usart_handle_t uart1_handle;
static struct rt_serial_device serial1;
__attribute__((isr)) void ck_usart0_irqhandler(void)
{
rt_hw_serial_isr(&serial1,RT_SERIAL_EVENT_RX_IND);
}
#endif
/*
* UART interface
*/
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
int ret;
usart_handle_t uart;
uint32_t bauds;
usart_mode_e mode;
usart_parity_e parity;
usart_stop_bits_e stopbits;
usart_data_bits_e databits;
RT_ASSERT(serial != RT_NULL);
uart = (usart_handle_t)serial->parent.user_data;
RT_ASSERT(uart != RT_NULL);
/* set baudrate parity...*/
bauds = cfg->baud_rate;
mode = USART_MODE_ASYNCHRONOUS;
if (cfg->parity == PARITY_EVEN)
parity = USART_PARITY_EVEN;
else if (cfg->parity == PARITY_ODD)
parity = USART_PARITY_ODD;
else
parity = USART_PARITY_NONE;
stopbits = USART_STOP_BITS_1 ;
databits = USART_DATA_BITS_8;
ret = csi_usart_config(uart, bauds, USART_MODE_ASYNCHRONOUS, parity, stopbits, databits);
if (ret < 0)
{
return -RT_ERROR;
}
return RT_EOK;
}
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
usart_handle_t uart;
RT_ASSERT(serial != RT_NULL);
uart = (usart_handle_t)serial->parent.user_data;
RT_ASSERT(uart != RT_NULL);
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
/* Disable the UART Interrupt */
ck_usart_clr_int_flag(uart,IER_RDA_INT_ENABLE);
break;
case RT_DEVICE_CTRL_SET_INT:
/* Enable the UART Interrupt */
ck_usart_set_int_flag(uart,IER_RDA_INT_ENABLE);
break;
}
return (RT_EOK);
}
static int uart_putc(struct rt_serial_device *serial, char c)
{
usart_handle_t uart;
RT_ASSERT(serial != RT_NULL);
uart = (usart_handle_t)serial->parent.user_data;
RT_ASSERT(uart != RT_NULL);
csi_usart_putchar(uart,c);
return (1);
}
static int uart_getc(struct rt_serial_device *serial)
{
int ch;
usart_handle_t uart;
RT_ASSERT(serial != RT_NULL);
uart = (usart_handle_t)serial->parent.user_data;
RT_ASSERT(uart != RT_NULL);
ch = csi_uart_getchar(uart);
return ch;
}
const struct rt_uart_ops _uart_ops =
{
uart_configure,
uart_control,
uart_putc,
uart_getc,
};
int rt_hw_usart_init(void)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
#ifdef RT_USING_UART1
serial1.ops = & _uart_ops;
serial1.config = config;
serial1.config.bufsz = 2048;
serial1.config.baud_rate = 115200;
uart1_handle = csi_usart_initialize(0, NULL);
rt_hw_serial_register(&serial1,
"uart1",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
uart1_handle);
#endif
return 0;
}
INIT_BOARD_EXPORT(rt_hw_usart_init);
#endif

View File

@ -0,0 +1,88 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen CSI Source File for IRQ Driver
*/
#include <stdint.h>
#include <soc.h>
#include <csi_core.h>
#include <csi_config.h>
extern void Default_Handler(void);
extern void (*g_irqvector[])(void);
extern void (*g_nmivector)(void);
/**
\brief enable irq.
\param[in] irq_num Number of IRQ.
\return None.
*/
void drv_irq_enable(uint32_t irq_num)
{
if (NMI_EXPn != irq_num)
{
#ifdef CONFIG_SYSTEM_SECURE
csi_vic_enable_sirq(irq_num);
#else
csi_vic_enable_irq(irq_num);
#endif
}
}
/**
\brief disable irq.
\param[in] irq_num Number of IRQ.
\return None.
*/
void drv_irq_disable(uint32_t irq_num)
{
if (NMI_EXPn != irq_num)
{
#ifdef CONFIG_SYSTEM_SECURE
csi_vic_disable_sirq(irq_num);
#else
csi_vic_disable_irq(irq_num);
#endif
}
}
/**
\brief register irq handler.
\param[in] irq_num Number of IRQ.
\param[in] irq_handler IRQ Handler.
\return None.
*/
void drv_irq_register(uint32_t irq_num, void *irq_handler)
{
if (NMI_EXPn != irq_num)
{
g_irqvector[irq_num] = irq_handler;
}
else
{
g_nmivector = irq_handler;
}
}
/**
\brief unregister irq handler.
\param[in] irq_num Number of IRQ.
\return None.
*/
void drv_irq_unregister(uint32_t irq_num)
{
if (NMI_EXPn != irq_num)
{
g_irqvector[irq_num] = (void *)Default_Handler;
}
else
{
g_nmivector = (void *)Default_Handler;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen header file for usart driver
*/
#ifndef __CK_USART_H
#define __CK_USART_H
#include <stdio.h>
#include "errno.h"
#include "soc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BAUDRATE_DEFAULT 19200
#define UART_BUSY_TIMEOUT 1000000
#define UART_RECEIVE_TIMEOUT 1000
#define UART_TRANSMIT_TIMEOUT 1000
#define UART_MAX_FIFO 0x10
/* UART register bit definitions */
#define USR_UART_BUSY 0x01
#define USR_UART_TFE 0x04
#define USR_UART_RFNE 0x08
#define LSR_DATA_READY 0x01
#define LSR_THR_EMPTY 0x20
#define IER_RDA_INT_ENABLE 0x01
#define IER_THRE_INT_ENABLE 0x02
#define IIR_RECV_LINE_ENABLE 0x04
#define IIR_NO_ISQ_PEND 0x01
#define LCR_SET_DLAB 0x80 /* enable r/w DLR to set the baud rate */
#define LCR_PARITY_ENABLE 0x08 /* parity enabled */
#define LCR_PARITY_EVEN 0x10 /* Even parity enabled */
#define LCR_PARITY_ODD 0xef /* Odd parity enabled */
#define LCR_WORD_SIZE_5 0xfc /* the data length is 5 bits */
#define LCR_WORD_SIZE_6 0x01 /* the data length is 6 bits */
#define LCR_WORD_SIZE_7 0x02 /* the data length is 7 bits */
#define LCR_WORD_SIZE_8 0x03 /* the data length is 8 bits */
#define LCR_STOP_BIT1 0xfb /* 1 stop bit */
#define LCR_STOP_BIT2 0x04 /* 1.5 stop bit */
#define DW_LSR_PFE 0x80
#define DW_LSR_TEMT 0x40
#define DW_LSR_THRE 0x40
#define DW_LSR_BI 0x10
#define DW_LSR_FE 0x08
#define DW_LSR_PE 0x04
#define DW_LSR_OE 0x02
#define DW_LSR_DR 0x01
#define DW_LSR_TRANS_EMPTY 0x20
#define DW_IIR_THR_EMPTY 0x02 /* threshold empty */
#define DW_IIR_RECV_DATA 0x04 /* received data available */
#define DW_IIR_RECV_LINE 0x06 /* receiver line status */
#define DW_IIR_CHAR_TIMEOUT 0x0c /* character timeout */
typedef struct
{
union
{
__IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */
__OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */
__IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */
};
union
{
__IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */
__IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */
};
__IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */
__IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */
uint32_t RESERVED0;
__IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */
__IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */
uint32_t RESERVED1[24];
__IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */
} ck_usart_reg_t;
#ifdef __cplusplus
}
#endif
#endif /* __CK_USART_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen config file
*/
/* csi_config.h -- Autogenerated! Do not edit. */
#ifndef __CSI_CONFIG_H
#define __CSI_CONFIG_H
#define CONFIG_ARCH_RV32 1
#define CONFIG_CPU_E906FD 1
#define CONFIG_RV32_CORETIM 1
#define CONFIG_CHIP_SMARTL_RV32 1
#define CONFIG_BOARD_SMARTL_E906_EVB 1
#define CONFIG_BOARD_NAME_STR "smartl_e906_evb"
#define CONFIG_SUPPORT_TSPEND 1
#define CONFIG_ARCH_INTERRUPTSTACK 4096
#define CONFIG_NEWLIB_WRAP 1
#define CONFIG_USER_DEFINED_LD_DIR_STR ""
#define CONFIG_KERNEL_RTTHREAD 1
#endif /* __CONFIG_H */

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen CSI Core Layer Header File
*/
#ifndef _CORE_H_
#define _CORE_H_
#include <stdint.h>
#if defined(__CK801__) || defined(__E801__)
#include <core_801.h>
#elif defined(__CK802__) || defined(__E802__) || defined(__E802T__) || defined(__S802__) || defined(__S802T__)
#include <core_802.h>
#elif defined(__CK804__) || defined(__E804D__) || defined(__E804DT__) || defined(__E804F__) || defined(__E804FT__) || defined (__E804DF__) || defined(__E804DFT__)
#include <core_804.h>
#elif defined(__CK803__) || defined(__E803__) || defined(__E803T__) || defined(__S803__) || defined(__S803T__)
#include <core_803.h>
#elif defined(__CK805__) || defined(__I805__) || defined(__I805F__)
#include <core_805.h>
#elif defined(__CK610__)
#include <core_ck610.h>
#elif defined(__CK810__) || defined(__C810__) || defined(__C810T__) || defined(__C810V__) || defined(__C810VT__)
#include <core_810.h>
#elif defined(__CK807__) || defined(__C807__) || defined(__C807F__) || defined(__C807FV__) || defined(__R807__)
#include <core_807.h>
#elif defined(__riscv) && defined(CONFIG_CSKY_CORETIM)
#include <core_rv32_old.h>
#elif defined(__riscv)
#include <core_rv32.h>
#endif
#ifdef __riscv
#include <csi_rv32_gcc.h>
#else
#include <csi_gcc.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* _CORE_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen Header File for Common Driver
*/
#ifndef _DRV_COMMON_H_
#define _DRV_COMMON_H_
#include <stdint.h>
#include <drv_errno.h>
#ifdef __cplusplus
extern "C" {
#endif
/// \details driver handle
typedef void *drv_handle_t;
#ifndef CONFIG_PARAM_NOT_CHECK
#define HANDLE_PARAM_CHK(para, err) \
do { \
if ((int32_t)para == (int32_t)NULL) { \
return (err); \
} \
} while (0)
#define HANDLE_PARAM_CHK_NORETVAL(para, err) \
do { \
if ((int32_t)para == (int32_t)NULL) { \
return; \
} \
} while (0)
#else
#define HANDLE_PARAM_CHK(para, err)
#define HANDLE_PARAM_CHK_NORETVAL(para, err)
#endif
/**
\brief General power states
*/
typedef enum
{
DRV_POWER_OFF, ///< Power off: no operation possible
DRV_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events
DRV_POWER_FULL, ///< Power on: full operation at maximum performance
DRV_POWER_SUSPEND, ///< Power suspend: power saving operation
} csi_power_stat_e;
#ifdef __cplusplus
}
#endif
#endif /* _DRV_COMMON_H */

View File

@ -0,0 +1,96 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen header file for error num
*/
#ifndef _DRV_ERRNO_H_
#define _DRV_ERRNO_H_
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ERRNO_DRV_START 0X80
/* driver General error codes */
typedef enum
{
DRV_ERROR = ERRNO_DRV_START, ///< Unspecified error
DRV_ERROR_BUSY, ///< Driver is busy
DRV_ERROR_TIMEOUT, ///< Timeout occurred
DRV_ERROR_UNSUPPORTED, ///< Operation not supported
DRV_ERROR_PARAMETER, ///< Parameter error
DRV_ERROR_SPECIFIC ///< Start of driver specific errors
} drv_err_e;
/** Get error type */
#define GET_ERROR_TYPE(errno) \
(error & 0xFF000000 >> 24)
/** Get error module */
#define GET_ERROR_MODULE(error) \
(error & 0x00FF0000 >> 16)
/** Get error API */
#define GET_ERROR_API(error) \
(error & 0x0000FF00 >> 8)
/** Get errno */
#define GET_ERROR_NUM(error) \
(error & 0x000000FF)
#ifndef CSI_DRV_ERRNO_BASE
#define CSI_DRV_ERRNO_BASE 0x81000000
#endif
/** driver module id definition*/
#define CSI_DRV_ERRNO_GPIO_BASE 0x81010000
#define CSI_DRV_ERRNO_USART_BASE 0x81020000
#define CSI_DRV_ERRNO_SPI_BASE 0x81030000
#define CSI_DRV_ERRNO_IIC_BASE 0x81040000
#define CSI_DRV_ERRNO_PWM_BASE 0x81050000
#define CSI_DRV_ERRNO_RTC_BASE 0x81060000
#define CSI_DRV_ERRNO_TIMER_BASE 0x81070000
#define CSI_DRV_ERRNO_WDT_BASE 0x81080000
#define CSI_DRV_ERRNO_AES_BASE 0x81090000
#define CSI_DRV_ERRNO_CRC_BASE 0x810A0000
#define CSI_DRV_ERRNO_RSA_BASE 0x810B0000
#define CSI_DRV_ERRNO_SHA_BASE 0x810C0000
#define CSI_DRV_ERRNO_TRNG_BASE 0x810D0000
#define CSI_DRV_ERRNO_EFLASH_BASE 0x810E0000
#define CSI_DRV_ERRNO_DMA_BASE 0x810F0000
#define CSI_DRV_ERRNO_NORFLASH_BASE 0x81100000
#define CSI_DRV_ERRNO_INTC_BASE 0x81110000
#define CSI_DRV_ERRNO_SPU_BASE 0x81120000
#define CSI_DRV_ERRNO_ADC_BASE 0x81130000
#define CSI_DRV_ERRNO_PMU_BASE 0x81140000
#define CSI_DRV_ERRNO_BMU_BASE 0x81150000
#define CSI_DRV_ERRNO_ETB_BASE 0x81160000
#define CSI_DRV_ERRNO_I2S_BASE 0x81170000
#define CSI_DRV_ERRNO_USI_BASE 0x81180000
#define CSI_DRV_ERRNO_SPIFLASH_BASE 0x81190000
#define CSI_DRV_ERRNO_ACMP_BASE 0x811A0000
#define CSI_DRV_ERRNO_MAILBOX_BASE 0x811B0000
#define CSI_DRV_ERRNO_EFUSEC_BASE 0x811C0000
#define CSI_DRV_ERRNO_CODEC_BASE 0x811D0000
#define CSI_DRV_ERRNO_DPU_BASE 0x811E0000
#define CSI_DRV_ERRNO_VPU_BASE 0x811F0000
#define CSI_DRV_ERRNO_CAMERA_BASE 0x81200000
#define CSI_DRV_ERRNO_MIPI_CSI_BASE 0x81210000
#define CSI_DRV_ERRNO_MIPI_CSI_READER_BASE 0x81220000
#define CSI_DRV_ERRNO_GMAC_BASE 0x81230000
#define CSI_DRV_ERRNO_ETHPHY_BASE 0x81240000
#define CSI_DRV_ERRNO_QW_EFUSE_BASE 0x81250000
#define CSI_DRV_ERRNO_RESET_BASE 0x81260000
#ifdef __cplusplus
}
#endif
#endif /* CSI_DRV_ERRNO_H */

View File

@ -0,0 +1,144 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen header file for gpio driver
*/
#ifndef _CSI_GPIO_H_
#define _CSI_GPIO_H_
#include <stdint.h>
#include <stdbool.h>
#include <drv_common.h>
#ifdef __cplusplus
extern "C" {
#endif
/// definition for gpio pin handle.
typedef void *gpio_pin_handle_t;
/****** GPIO specific error codes *****/
typedef enum
{
GPIO_ERROR_MODE = (DRV_ERROR_SPECIFIC + 1), ///< Specified Mode not supported
GPIO_ERROR_DIRECTION, ///< Specified direction not supported
GPIO_ERROR_IRQ_MODE, ///< Specified irq mode not supported
} gpio_error_e;
/*----- GPIO Control Codes: Mode -----*/
typedef enum
{
GPIO_MODE_PULLNONE = 0, ///< pull none for input
GPIO_MODE_PULLUP, ///< pull up for input
GPIO_MODE_PULLDOWN, ///< pull down for input
GPIO_MODE_OPEN_DRAIN, ///< open drain mode for output
GPIO_MODE_PUSH_PULL, ///< push-pull mode for output
} gpio_mode_e;
/*----- GPIO Control Codes: Mode Parameters: Data Bits -----*/
typedef enum
{
GPIO_DIRECTION_INPUT = 0, ///< gpio as input
GPIO_DIRECTION_OUTPUT, ///< gpio as output
} gpio_direction_e;
/*----- GPIO Control Codes: Mode Parameters: Parity -----*/
typedef enum
{
GPIO_IRQ_MODE_RISING_EDGE = 0, ///< interrupt mode for rising edge
GPIO_IRQ_MODE_FALLING_EDGE, ///< interrupt mode for falling edge
GPIO_IRQ_MODE_DOUBLE_EDGE, ///< interrupt mode for double edge
GPIO_IRQ_MODE_LOW_LEVEL, ///< interrupt mode for low level
GPIO_IRQ_MODE_HIGH_LEVEL, ///< interrupt mode for high level
} gpio_irq_mode_e;
typedef void (*gpio_event_cb_t)(int32_t idx); ///< gpio Event call back.
/**
\brief Initialize GPIO handle.
\param[in] gpio_pin gpio pin idx.
\param[in] cb_event event callback function \ref gpio_event_cb_t
\return gpio_pin_handle
*/
gpio_pin_handle_t csi_gpio_pin_initialize(int32_t gpio_pin, gpio_event_cb_t cb_event);
/**
\brief De-initialize GPIO pin handle.stops operation and releases the software resources used by the handle.
\param[in] handle gpio pin handle to operate.
\return error code
*/
int32_t csi_gpio_pin_uninitialize(gpio_pin_handle_t handle);
/**
\brief control gpio power.
\param[in] handle gpio handle to operate.
\param[in] state power state.\ref csi_power_stat_e.
\return error code
*/
int32_t csi_gpio_power_control(gpio_pin_handle_t handle, csi_power_stat_e state);
/**
\brief config pin mode
\param[in] pin gpio pin handle to operate.
\param[in] mode \ref gpio_mode_e
\return error code
*/
int32_t csi_gpio_pin_config_mode(gpio_pin_handle_t handle,
gpio_mode_e mode);
/**
\brief config pin direction
\param[in] pin gpio pin handle to operate.
\param[in] dir \ref gpio_direction_e
\return error code
*/
int32_t csi_gpio_pin_config_direction(gpio_pin_handle_t handle,
gpio_direction_e dir);
/**
\brief config pin
\param[in] pin gpio pin handle to operate.
\param[in] mode \ref gpio_mode_e
\param[in] dir \ref gpio_direction_e
\return error code
*/
int32_t csi_gpio_pin_config(gpio_pin_handle_t handle,
gpio_mode_e mode,
gpio_direction_e dir);
/**
\brief Set one or zero to the selected GPIO pin.
\param[in] pin gpio pin handle to operate.
\param[in] value value to be set
\return error code
*/
int32_t csi_gpio_pin_write(gpio_pin_handle_t handle, bool value);
/**
\brief Get the value of selected GPIO pin.
\param[in] pin gpio pin handle to operate.
\param[out] value buffer to store the pin value
\return error code
*/
int32_t csi_gpio_pin_read(gpio_pin_handle_t handle, bool *value);
/**
\brief set GPIO interrupt mode.
\param[in] pin gpio pin handle to operate.
\param[in] mode irq mode to be set
\param[in] enable enable flag
\return error code
*/
int32_t csi_gpio_pin_set_irq(gpio_pin_handle_t handle, gpio_irq_mode_e mode, bool enable);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_GPIO_H_ */

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen header File for IRQ Driver
*/
#include <stdint.h>
/**
\brief enable irq.
\param[in] irq_num Number of IRQ.
\return None.
*/
void drv_irq_enable(uint32_t irq_num);
/**
\brief disable irq.
\param[in] irq_num Number of IRQ.
\return None.
*/
void drv_irq_disable(uint32_t irq_num);
/**
\brief register irq handler.
\param[in] irq_num Number of IRQ.
\param[in] irq_handler IRQ Handler.
\return None.
*/
void drv_irq_register(uint32_t irq_num, void *irq_handler);
/**
\brief unregister irq handler.
\param[in] irq_num Number of IRQ.
\param[in] irq_handler IRQ Handler.
\return None.
*/
void drv_irq_unregister(uint32_t irq_num);

View File

@ -0,0 +1,154 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen timer driver header file
*/
/******************************************************************************
* @file drv_timer.h
* @brief header file for timer driver
* @version V1.0
* @date 02. June 2017
* @model timer
******************************************************************************/
#ifndef _CSI_TIMER_H_
#define _CSI_TIMER_H_
#include <stdint.h>
#include <drv_common.h>
#ifdef __cplusplus
extern "C" {
#endif
/// definition for timer handle.
typedef void *timer_handle_t;
/*----- TIMER Control Codes: Mode -----*/
typedef enum
{
TIMER_MODE_FREE_RUNNING = 0, ///< free running mode
TIMER_MODE_RELOAD ///< reload mode
} timer_mode_e;
/**
\brief TIMER Status
*/
typedef struct
{
uint32_t active : 1; ///< timer active flag
uint32_t timeout : 1; ///< timeout flag
} timer_status_t;
/**
\brief TIMER Event
*/
typedef enum
{
TIMER_EVENT_TIMEOUT = 0 ///< time out event
} timer_event_e;
typedef void (*timer_event_cb_t)(int32_t idx, timer_event_e event); ///< Pointer to \ref timer_event_cb_t : TIMER Event call back.
/**
\brief Initialize TIMER Interface. 1. Initializes the resources needed for the TIMER interface 2.registers event callback function
\param[in] idx timer index
\param[in] cb_event event call back function \ref timer_event_cb_t
\param[in] cb_arg arguments of cb_event
\return pointer to timer instance
*/
timer_handle_t csi_timer_initialize(int32_t idx, timer_event_cb_t cb_event);
/**
\brief De-initialize TIMER Interface. stops operation and releases the software resources used by the interface
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_uninitialize(timer_handle_t handle);
/**
\brief control timer power.
\param[in] handle timer handle to operate.
\param[in] state power state.\ref csi_power_stat_e.
\return error code
*/
int32_t csi_timer_power_control(timer_handle_t handle, csi_power_stat_e state);
/**
\brief config timer mode.
\param[in] handle timer handle to operate.
\param[in] mode \ref timer_mode_e
\return error code
*/
int32_t csi_timer_config(timer_handle_t handle, timer_mode_e mode);
/**
\brief Set timeout just for the reload mode.
\param[in] handle timer handle to operate.
\param[in] timeout the timeout value in microseconds(us).
\return error code
*/
int32_t csi_timer_set_timeout(timer_handle_t handle, uint32_t timeout);
/**
\brief Start timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_start(timer_handle_t handle);
/**
\brief Stop timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_stop(timer_handle_t handle);
/**
\brief suspend timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_suspend(timer_handle_t handle);
/**
\brief resume timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_resume(timer_handle_t handle);
/**
\brief get timer current value
\param[in] handle timer handle to operate.
\param[out] value timer current value
\return error code
*/
int32_t csi_timer_get_current_value(timer_handle_t handle, uint32_t *value);
/**
\brief Get TIMER status.
\param[in] handle timer handle to operate.
\return TIMER status \ref timer_status_t
*/
timer_status_t csi_timer_get_status(timer_handle_t handle);
/**
\brief get timer reload value
\param[in] handle timer handle to operate.
\param[out] value timer reload value
\return error code
*/
int32_t csi_timer_get_load_value(timer_handle_t handle, uint32_t *value);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_TIMER_H_ */

View File

@ -0,0 +1,446 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen header file for usart driver
*/
#ifndef _CSI_USART_H_
#define _CSI_USART_H_
#include <drv_common.h>
#ifdef __cplusplus
extern "C" {
#endif
/// definition for usart handle.
typedef void *usart_handle_t;
/****** USART specific error codes *****/
typedef enum
{
USART_ERROR_MODE = (DRV_ERROR_SPECIFIC + 1), ///< Specified Mode not supported
USART_ERROR_BAUDRATE, ///< Specified baudrate not supported
USART_ERROR_DATA_BITS, ///< Specified number of Data bits not supported
USART_ERROR_PARITY, ///< Specified Parity not supported
USART_ERROR_STOP_BITS, ///< Specified number of Stop bits not supported
USART_ERROR_FLOW_CONTROL, ///< Specified Flow Control not supported
USART_ERROR_CPOL, ///< Specified Clock Polarity not supported
USART_ERROR_CPHA ///< Specified Clock Phase not supported
} usart_error_e;
/*----- USART Control Codes: Mode -----*/
typedef enum
{
USART_MODE_ASYNCHRONOUS = 0, ///< USART (Asynchronous)
USART_MODE_SYNCHRONOUS_MASTER, ///< Synchronous Master
USART_MODE_SYNCHRONOUS_SLAVE, ///< Synchronous Slave (external clock signal)
USART_MODE_SINGLE_WIRE, ///< USART Single-wire (half-duplex)
USART_MODE_SINGLE_IRDA, ///< UART IrDA
USART_MODE_SINGLE_SMART_CARD, ///< UART Smart Card
} usart_mode_e;
/*----- USART Control Codes: Mode Parameters: Data Bits -----*/
typedef enum
{
USART_DATA_BITS_5 = 0, ///< 5 Data bits
USART_DATA_BITS_6, ///< 6 Data bit
USART_DATA_BITS_7, ///< 7 Data bits
USART_DATA_BITS_8, ///< 8 Data bits (default)
USART_DATA_BITS_9 ///< 9 Data bits
} usart_data_bits_e;
/*----- USART Control Codes: Mode Parameters: Parity -----*/
typedef enum
{
USART_PARITY_NONE = 0, ///< No Parity (default)
USART_PARITY_EVEN, ///< Even Parity
USART_PARITY_ODD, ///< Odd Parity
USART_PARITY_1, ///< Parity forced to 1
USART_PARITY_0 ///< Parity forced to 0
} usart_parity_e;
/*----- USART Control Codes: Mode Parameters: Stop Bits -----*/
typedef enum
{
USART_STOP_BITS_1 = 0, ///< 1 Stop bit (default)
USART_STOP_BITS_2, ///< 2 Stop bits
USART_STOP_BITS_1_5, ///< 1.5 Stop bits
USART_STOP_BITS_0_5 ///< 0.5 Stop bits
} usart_stop_bits_e;
/*----- USART Control Codes: Mode Parameters: Clock Polarity (Synchronous mode) -----*/
typedef enum
{
USART_CPOL0 = 0, ///< CPOL = 0 (default). data are captured on rising edge (low->high transition)
USART_CPOL1 ///< CPOL = 1. data are captured on falling edge (high->lowh transition)
} usart_cpol_e;
/*----- USART Control Codes: Mode Parameters: Clock Phase (Synchronous mode) -----*/
typedef enum
{
USART_CPHA0 = 0, ///< CPHA = 0 (default). sample on first (leading) edge
USART_CPHA1 ///< CPHA = 1. sample on second (trailing) edge
} usart_cpha_e;
/*----- USART Control Codes: flush data type-----*/
typedef enum
{
USART_FLUSH_WRITE,
USART_FLUSH_READ
} usart_flush_type_e;
/*----- USART Control Codes: flow control type-----*/
typedef enum
{
USART_FLOWCTRL_NONE,
USART_FLOWCTRL_CTS,
USART_FLOWCTRL_RTS,
USART_FLOWCTRL_CTS_RTS
} usart_flowctrl_type_e;
/*----- USART Modem Control -----*/
typedef enum
{
USART_RTS_CLEAR, ///< Deactivate RTS
USART_RTS_SET, ///< Activate RTS
USART_DTR_CLEAR, ///< Deactivate DTR
USART_DTR_SET ///< Activate DTR
} usart_modem_ctrl_e;
/*----- USART Modem Status -----*/
typedef struct
{
uint32_t cts : 1; ///< CTS state: 1=Active, 0=Inactive
uint32_t dsr : 1; ///< DSR state: 1=Active, 0=Inactive
uint32_t dcd : 1; ///< DCD state: 1=Active, 0=Inactive
uint32_t ri : 1; ///< RI state: 1=Active, 0=Inactive
} usart_modem_stat_t;
/*----- USART Control Codes: on-off intrrupte type-----*/
typedef enum
{
USART_INTR_WRITE,
USART_INTR_READ
} usart_intr_type_e;
/**
\brief USART Status
*/
typedef struct {
uint32_t tx_busy : 1; ///< Transmitter busy flag
uint32_t rx_busy : 1; ///< Receiver busy flag
uint32_t tx_underflow : 1; ///< Transmit data underflow detected (cleared on start of next send operation)(Synchronous Slave)
uint32_t rx_overflow : 1; ///< Receive data overflow detected (cleared on start of next receive operation)
uint32_t rx_break : 1; ///< Break detected on receive (cleared on start of next receive operation)
uint32_t rx_framing_error : 1; ///< Framing error detected on receive (cleared on start of next receive operation)
uint32_t rx_parity_error : 1; ///< Parity error detected on receive (cleared on start of next receive operation)
uint32_t tx_enable : 1; ///< Transmitter enable flag
uint32_t rx_enable : 1; ///< Receiver enbale flag
} usart_status_t;
/****** USART Event *****/
typedef enum
{
USART_EVENT_SEND_COMPLETE = 0, ///< Send completed; however USART may still transmit data
USART_EVENT_RECEIVE_COMPLETE = 1, ///< Receive completed
USART_EVENT_TRANSFER_COMPLETE = 2, ///< Transfer completed
USART_EVENT_TX_COMPLETE = 3, ///< Transmit completed (optional)
USART_EVENT_TX_UNDERFLOW = 4, ///< Transmit data not available (Synchronous Slave)
USART_EVENT_RX_OVERFLOW = 5, ///< Receive data overflow
USART_EVENT_RX_TIMEOUT = 6, ///< Receive character timeout (optional)
USART_EVENT_RX_BREAK = 7, ///< Break detected on receive
USART_EVENT_RX_FRAMING_ERROR = 8, ///< Framing error detected on receive
USART_EVENT_RX_PARITY_ERROR = 9, ///< Parity error detected on receive
USART_EVENT_CTS = 10, ///< CTS state changed (optional)
USART_EVENT_DSR = 11, ///< DSR state changed (optional)
USART_EVENT_DCD = 12, ///< DCD state changed (optional)
USART_EVENT_RI = 13, ///< RI state changed (optional)
USART_EVENT_RECEIVED = 14, ///< Data Received, only in usart fifo, call receive()/transfer() get the data
} usart_event_e;
typedef void (*usart_event_cb_t)(int32_t idx, usart_event_e event); ///< Pointer to \ref usart_event_cb_t : USART Event call back.
/**
\brief USART Driver Capabilities.
*/
typedef struct {
uint32_t asynchronous : 1; ///< supports UART (Asynchronous) mode
uint32_t synchronous_master : 1; ///< supports Synchronous Master mode
uint32_t synchronous_slave : 1; ///< supports Synchronous Slave mode
uint32_t single_wire : 1; ///< supports UART Single-wire mode
uint32_t irda : 1; ///< supports UART IrDA mode
uint32_t smart_card : 1; ///< supports UART Smart Card mode
uint32_t smart_card_clock : 1; ///< Smart Card Clock generator available
uint32_t flow_control_rts : 1; ///< RTS Flow Control available
uint32_t flow_control_cts : 1; ///< CTS Flow Control available
uint32_t event_tx_complete : 1; ///< Transmit completed event: \ref USART_EVENT_TX_COMPLETE
uint32_t event_rx_timeout : 1; ///< Signal receive character timeout event: \ref USART_EVENT_RX_TIMEOUT
uint32_t rts : 1; ///< RTS Line: 0=not available, 1=available
uint32_t cts : 1; ///< CTS Line: 0=not available, 1=available
uint32_t dtr : 1; ///< DTR Line: 0=not available, 1=available
uint32_t dsr : 1; ///< DSR Line: 0=not available, 1=available
uint32_t dcd : 1; ///< DCD Line: 0=not available, 1=available
uint32_t ri : 1; ///< RI Line: 0=not available, 1=available
uint32_t event_cts : 1; ///< Signal CTS change event: \ref USART_EVENT_CTS
uint32_t event_dsr : 1; ///< Signal DSR change event: \ref USART_EVENT_DSR
uint32_t event_dcd : 1; ///< Signal DCD change event: \ref USART_EVENT_DCD
uint32_t event_ri : 1; ///< Signal RI change event: \ref USART_EVENT_RI
} usart_capabilities_t;
/**
\brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
\param[in] idx usart index
\param[in] cb_event event call back function \ref usart_event_cb_t
\return return usart handle if success
*/
usart_handle_t csi_usart_initialize(int32_t idx, usart_event_cb_t cb_event);
/**
\brief De-initialize USART Interface. stops operation and releases the software resources used by the interface
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_uninitialize(usart_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] idx usart index
\return \ref usart_capabilities_t
*/
usart_capabilities_t csi_usart_get_capabilities(int32_t idx);
/**
\brief config usart mode.
\param[in] handle usart handle to operate.
\param[in] baud baud rate.
\param[in] mode \ref usart_mode_e .
\param[in] parity \ref usart_parity_e .
\param[in] stopbits \ref usart_stop_bits_e .
\param[in] bits \ref usart_data_bits_e .
\return error code
*/
int32_t csi_usart_config(usart_handle_t handle,
uint32_t baud,
usart_mode_e mode,
usart_parity_e parity,
usart_stop_bits_e stopbits,
usart_data_bits_e bits);
/**
\brief Start sending data to USART transmitter,(received data is ignored).
This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens.
\ref csi_usart_get_status can get operation status.
\param[in] handle usart handle to operate.
\param[in] data Pointer to buffer with data to send to USART transmitter. data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[in] num Number of data items to send
\return error code
*/
int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num);
/**
\brief Abort Send data to USART transmitter
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_send(usart_handle_t handle);
/**
\brief Start receiving data from USART receiver. \n
This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens.
\ref csi_usart_get_status can get operation status.
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from USART receiver.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[in] num Number of data items to receive
\return error code
*/
int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num);
/**
\brief query data from UART receiver FIFO.
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from UART receiver
\param[in] num Number of data items to receive
\return fifo data num to receive
*/
int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num);
/**
\brief Abort Receive data from USART receiver
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_receive(usart_handle_t handle);
/**
\brief Start synchronously sends data to the USART transmitter and receives data from the USART receiver. used in synchronous mode
This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens.
\ref csi_usart_get_status can get operation status.
\param[in] handle usart handle to operate.
\param[in] data_out Pointer to buffer with data to send to USART transmitter.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[out] data_in Pointer to buffer for data to receive from USART receiver.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[in] num Number of data items to transfer
\return error code
*/
int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num);
/**
\brief abort sending/receiving data to/from USART transmitter/receiver.
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_transfer(usart_handle_t handle);
/**
\brief Get USART status.
\param[in] handle usart handle to operate.
\return USART status \ref usart_status_t
*/
usart_status_t csi_usart_get_status(usart_handle_t handle);
/**
\brief flush receive/send data.
\param[in] handle usart handle to operate.
\param[in] type \ref usart_flush_type_e .
\return error code
*/
int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type);
/**
\brief set interrupt mode.
\param[in] handle usart handle to operate.
\param[in] type \ref usart_intr_type_e.
\param[in] flag 0-OFF, 1-ON.
\return error code
*/
int32_t csi_usart_set_interrupt(usart_handle_t handle, usart_intr_type_e type, int32_t flag);
/**
\brief set the baud rate of usart.
\param[in] baud usart base to operate.
\param[in] baudrate baud rate
\return error code
*/
int32_t csi_usart_config_baudrate(usart_handle_t handle, uint32_t baud);
/**
\brief config usart mode.
\param[in] handle usart handle to operate.
\param[in] mode \ref usart_mode_e
\return error code
*/
int32_t csi_usart_config_mode(usart_handle_t handle, usart_mode_e mode);
/**
\brief config usart parity.
\param[in] handle usart handle to operate.
\param[in] parity \ref usart_parity_e
\return error code
*/
int32_t csi_usart_config_parity(usart_handle_t handle, usart_parity_e parity);
/**
\brief config usart stop bit number.
\param[in] handle usart handle to operate.
\param[in] stopbits \ref usart_stop_bits_e
\return error code
*/
int32_t csi_usart_config_stopbits(usart_handle_t handle, usart_stop_bits_e stopbit);
/**
\brief config usart data length.
\param[in] handle usart handle to operate.
\param[in] databits \ref usart_data_bits_e
\return error code
*/
int32_t csi_usart_config_databits(usart_handle_t handle, usart_data_bits_e databits);
/**
\brief get character in query mode.
\param[in] handle usart handle to operate.
\param[out] ch the pointer to the received character.
\return error code
*/
int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch);
/**
\brief transmit character in query mode.
\param[in] handle usart handle to operate.
\param[in] ch the input character
\return error code
*/
int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch);
/**
\brief Get usart send data count.
\param[in] handle usart handle to operate.
\return number of currently transmitted data bytes
*/
uint32_t csi_usart_get_tx_count(usart_handle_t handle);
/**
\brief Get usart received data count.
\param[in] handle usart handle to operate.
\return number of currently received data bytes
*/
uint32_t csi_usart_get_rx_count(usart_handle_t handle);
/**
\brief control usart power.
\param[in] handle usart handle to operate.
\param[in] state power state.\ref csi_power_stat_e.
\return error code
*/
int32_t csi_usart_power_control(usart_handle_t handle, csi_power_stat_e state);
/**
\brief config usart flow control type.
\param[in] handle usart handle to operate.
\param[in] flowctrl_type flow control type.\ref usart_flowctrl_type_e.
\return error code
*/
int32_t csi_usart_config_flowctrl(usart_handle_t handle,
usart_flowctrl_type_e flowctrl_type);
/**
\brief config usart clock Polarity and Phase.
\param[in] handle usart handle to operate.
\param[in] cpol Clock Polarity.\ref usart_cpol_e.
\param[in] cpha Clock Phase.\ref usart_cpha_e.
\return error code
*/
int32_t csi_usart_config_clock(usart_handle_t handle, usart_cpol_e cpol, usart_cpha_e cpha);
/**
\brief control the transmitter.
\param[in] handle usart handle to operate.
\param[in] enable 1 - enable the transmitter. 0 - disable the transmitter
\return error code
*/
int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable);
/**
\brief control the receiver.
\param[in] handle usart handle to operate.
\param[in] enable 1 - enable the receiver. 0 - disable the receiver
\return error code
*/
int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable);
/**
\brief control the break.
\param[in] handle usart handle to operate.
\param[in] enable 1- Enable continuous Break transmission,0 - disable continuous Break transmission
\return error code
*/
int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_USART_H_ */

View File

@ -0,0 +1,635 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen gpio driver
*/
/******************************************************************************
* @file dw_gpio.c
* @brief CSI Source File for GPIO Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <csi_config.h>
#include <stdbool.h>
#include <stdio.h>
#include <drv_irq.h>
#include <drv_gpio.h>
#include <dw_gpio.h>
#include <csi_core.h>
#include <pin_name.h>
extern int32_t drv_pin_config_mode(port_name_e port, uint8_t offset, gpio_mode_e pin_mode);
#define ERR_GPIO(errno) (CSI_DRV_ERRNO_GPIO_BASE | errno)
#define GPIO_NULL_PARAM_CHK(para) HANDLE_PARAM_CHK(para, ERR_GPIO(DRV_ERROR_PARAMETER))
typedef void *gpio_port_handle_t;
typedef struct
{
#ifdef CONFIG_LPM
uint8_t gpio_power_status;
uint32_t gpio_regs_saved[7];
#endif
uint32_t base; ///< handle register base
uint32_t irq; ///< irq of this handle
uint32_t pin_num; ///< pin number of this handle
gpio_mode_e mode; ///< gpio mode
gpio_direction_e dir; ///< gpio direction
uint32_t mask; ///< gpio mask bit
uint32_t value; ///< gpio value
} dw_gpio_priv_t;
typedef struct
{
uint8_t portidx;
uint8_t idx;
uint8_t offset;
gpio_event_cb_t cb;
} dw_gpio_pin_priv_t;
extern int32_t target_gpio_port_init(port_name_e port, uint32_t *base, uint32_t *irq, void **handler, uint32_t *pin_num);
extern int32_t target_gpio_pin_init(int32_t gpio_pin, uint32_t *port_idx);
static dw_gpio_priv_t gpio_handle[CONFIG_GPIO_NUM];
static dw_gpio_pin_priv_t gpio_pin_handle[CONFIG_GPIO_PIN_NUM];
//
// Functions
//
static int32_t gpio_set_direction(
void *port,
gpio_direction_e direction
)
{
dw_gpio_priv_t *gpio_priv = port;
dw_gpio_reg_t *gpio_reg = (dw_gpio_reg_t *)(gpio_priv->base);
if (direction == GPIO_DIRECTION_INPUT)
{
gpio_reg->SWPORT_DDR &= (~gpio_priv->mask);
} else if (direction == GPIO_DIRECTION_OUTPUT)
{
gpio_reg->SWPORT_DDR |= gpio_priv->mask;
} else
{
return ERR_GPIO(GPIO_ERROR_DIRECTION);
}
return 0;
}
/*
* Read the statu of the Port choosed.
* Parameters:
* port: use to choose a I/O port among Port A, B, or C.
* return: the value of the corresponding Port.
*/
static int32_t gpio_read(void *port, uint32_t *value)
{
dw_gpio_priv_t *gpio_priv = port;
dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(gpio_priv->base + 0x30);
*value = gpio_control_reg->EXT_PORTA;
return 0;
}
/*
* Write an output value to corresponding Port.
* Parameters:
* port: use to choose a I/O port among Port A, B, or C.
* output: value that will be written to the corresponding Port.
* return: SUCCESS
*/
static int32_t gpio_write(void *port, uint32_t mask)
{
dw_gpio_priv_t *gpio_priv = port;
dw_gpio_reg_t *gpio_reg = (dw_gpio_reg_t *)(gpio_priv->base);
uint32_t value = gpio_reg->SWPORT_DR;
value &= ~(mask);
value |= gpio_priv->value;
gpio_reg->SWPORT_DR = value;
return 0;
}
/**
* Configure a GPIO gpio_set_irq_mode.
* @param[in] pin the addr store the pin num.
* @param[in] _irqmode the irqmode of gpio
* @return zero on success. -1 on falure.
*/
static int32_t gpio_set_irq_mode(gpio_pin_handle_t pin, gpio_irq_mode_e irq_mode)
{
dw_gpio_pin_priv_t *gpio_pin_priv = pin;
/* convert portidx to port handle */
dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(port_handle->base + 0x30);
uint32_t offset = gpio_pin_priv->idx;
uint32_t mask = 1 << offset;
switch (irq_mode)
{
/* rising edge interrupt mode */
case GPIO_IRQ_MODE_RISING_EDGE:
gpio_control_reg->INTTYPE_LEVEL |= mask;
gpio_control_reg->INT_POLARITY |= mask;
break;
/* falling edge interrupt mode */
case GPIO_IRQ_MODE_FALLING_EDGE:
gpio_control_reg->INTTYPE_LEVEL |= mask;
gpio_control_reg->INT_POLARITY &= (~mask);
break;
/* low level interrupt mode */
case GPIO_IRQ_MODE_LOW_LEVEL:
gpio_control_reg->INTTYPE_LEVEL &= (~mask);
gpio_control_reg->INT_POLARITY &= (~mask);
break;
/* high level interrupt mode */
case GPIO_IRQ_MODE_HIGH_LEVEL:
gpio_control_reg->INTTYPE_LEVEL &= (~mask);
gpio_control_reg->INT_POLARITY |= mask;
break;
/* double edge interrupt mode */
case GPIO_IRQ_MODE_DOUBLE_EDGE:
return ERR_GPIO(DRV_ERROR_UNSUPPORTED);
default:
return ERR_GPIO(GPIO_ERROR_IRQ_MODE);
}
return 0;
}
/*
* Clear one or more interrupts of PortA.
* Parameters:
* pinno:
* return: SUCCESS.
*/
static void gpio_irq_clear(gpio_pin_handle_t pin, uint32_t idx)
{
dw_gpio_pin_priv_t *gpio_pin_priv = pin;
/* convert portidx to port handle */
dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(port_handle->base + 0x30);
gpio_control_reg->PORTA_EOI = idx;
}
/*
* Enable one or more interrupts of PortA.
* Parameters:
* pinno:
* return: SUCCESS.
*/
static void gpio_irq_enable(gpio_pin_handle_t pin)
{
dw_gpio_pin_priv_t *gpio_pin_priv = pin;
/* convert portidx to port handle */
dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(port_handle->base + 0x30);
uint32_t offset = gpio_pin_priv->idx;
uint32_t val = gpio_control_reg->INTEN;
val |= (1 << offset);
gpio_control_reg->INTEN = val;
}
/*
* Disable one or more interrupts of PortA.
* Parameters:
* pinno:
* return: SUCCESS.
*/
static void gpio_irq_disable(gpio_pin_handle_t pin)
{
dw_gpio_pin_priv_t *gpio_pin_priv = pin;
uint32_t offset = gpio_pin_priv->idx;
/* convert portidx to port handle */
dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(port_handle->base + 0x30);
uint32_t val = gpio_control_reg->INTEN;
val &= ~(1 << offset);
gpio_control_reg->INTEN = val;
}
void dw_gpio_irqhandler(int idx)
{
if (idx >= CONFIG_GPIO_NUM)
{
return;
}
dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(gpio_handle[idx].base + 0x30);
uint32_t value = gpio_control_reg->INTSTATUS;
uint8_t i;
/* find the interrput pin */
for (i = 0; i < 32; i++)
{
if (value & (1U << i))
{
uint32_t pin_idx = i;
#ifndef CONFIG_CHIP_DANICA
uint8_t j;
if (idx > 0)
{
for (j = 0; j < idx; j++)
{
pin_idx += gpio_handle[j].pin_num;
}
}
if (pin_idx >= CONFIG_GPIO_PIN_NUM)
{
return;
}
#endif
dw_gpio_pin_priv_t *gpio_pin_priv = (dw_gpio_pin_priv_t *)&gpio_pin_handle[pin_idx];
gpio_irq_clear(gpio_pin_priv, (1 << i)); //clear the gpio interrupt
/* execute the callback function */
if ((gpio_event_cb_t)(gpio_pin_priv->cb))
{
((gpio_event_cb_t)(gpio_pin_priv->cb))(gpio_pin_priv->offset);
}
}
}
}
/**
\brief Initialize GPIO module. 1. Initializes the resources needed for the GPIO handle 2.registers event callback function
3.get gpio_port_handle
\param[in] port port_name.
\return gpio_port_handle
*/
gpio_port_handle_t csi_gpio_port_initialize(int32_t port)
{
dw_gpio_priv_t *gpio_priv = NULL;
/* obtain the gpio port information */
uint32_t base = 0u;
uint32_t pin_num;
uint32_t irq;
void *handler;
int32_t idx = target_gpio_port_init(port, &base, &irq, &handler, &pin_num);
if (idx < 0 || idx >= CONFIG_GPIO_NUM)
{
return NULL;
}
gpio_priv = &gpio_handle[idx];
gpio_priv->base = base;
gpio_priv->irq = irq;
gpio_priv->pin_num = pin_num;
#ifdef CONFIG_LPM
csi_gpio_power_control(gpio_priv, DRV_POWER_FULL);
#endif
drv_irq_register(gpio_priv->irq, handler);
drv_irq_enable(gpio_priv->irq);
return (gpio_port_handle_t)gpio_priv;
}
/**
\brief De-initialize GPIO handle. stops operation and releases the software resources used by the handle
\param[in] handle gpio port handle to operate.
\return error code
*/
int32_t csi_gpio_port_uninitialize(gpio_port_handle_t handle)
{
GPIO_NULL_PARAM_CHK(handle);
dw_gpio_priv_t *gpio_priv = handle;
drv_irq_disable(gpio_priv->irq);
drv_irq_unregister(gpio_priv->irq);
#ifdef CONFIG_LPM
csi_gpio_power_control(gpio_priv, DRV_POWER_OFF);
#endif
return 0;
}
#ifdef CONFIG_LPM
static void manage_clock(gpio_pin_handle_t handle, uint8_t enable)
{
dw_gpio_pin_priv_t *gpio_pin_priv = (dw_gpio_pin_priv_t *)handle;
uint8_t device[] = {CLOCK_MANAGER_GPIO0, CLOCK_MANAGER_GPIO1};
drv_clock_manager_config(device[gpio_pin_priv->portidx], enable);
}
static void do_prepare_sleep_action(void *handle)
{
dw_gpio_priv_t *gpio_handle = handle;
uint32_t *gbase = (uint32_t *)(gpio_handle->base);
uint32_t *control_base = (uint32_t *)(gpio_handle->base + 0x30);
registers_save(gpio_handle->gpio_regs_saved, gbase, 3);
registers_save(&gpio_handle->gpio_regs_saved[3], control_base, 4);
}
static void do_wakeup_sleep_action(void *handle)
{
dw_gpio_priv_t *gpio_handle = handle;
uint32_t *gbase = (uint32_t *)(gpio_handle->base);
uint32_t *control_base = (uint32_t *)(gpio_handle->base + 0x30);
registers_restore(gbase, gpio_handle->gpio_regs_saved, 3);
registers_restore(control_base, &gpio_handle->gpio_regs_saved[3], 4);
}
#endif
/**
\brief Initialize GPIO handle.
\param[in] gpio_pin Pointer to the int32_t.
\param[in] cb_event Pointer to \ref gpio_event_cb_t.
\param[in] arg Pointer to \ref arg used for the callback.
\return gpio_pin_handle
*/
gpio_pin_handle_t csi_gpio_pin_initialize(int32_t gpio_pin, gpio_event_cb_t cb_event)
{
if (gpio_pin < 0 || gpio_pin >= CONFIG_GPIO_PIN_NUM)
{
return NULL;
}
uint32_t i;
for (i = 0; i < CONFIG_GPIO_NUM; i++)
{
csi_gpio_port_initialize(i);
}
/* obtain the gpio pin information */
uint32_t port_idx;
int32_t pin_idx = target_gpio_pin_init(gpio_pin, &port_idx);
if (pin_idx < 0)
{
return NULL;
}
int32_t idx = pin_idx;
for (i = 0; i < port_idx; i++)
{
idx += (gpio_handle[i].pin_num);
}
dw_gpio_pin_priv_t *gpio_pin_priv = &(gpio_pin_handle[idx]);
gpio_pin_priv->portidx = port_idx;
gpio_pin_priv->idx = pin_idx;
gpio_pin_priv->cb = cb_event;
gpio_pin_priv->offset = gpio_pin;
return (gpio_pin_handle_t)gpio_pin_priv;
}
/**
\brief De-initialize GPIO pin handle. stops operation and releases the software resources used by the handle
\param[in] handle gpio pin handle to operate.
\return error code
*/
int32_t csi_gpio_pin_uninitialize(gpio_pin_handle_t handle)
{
if (handle == NULL)
{
return ERR_GPIO(DRV_ERROR_PARAMETER);
}
dw_gpio_pin_priv_t *gpio_pin_priv = (dw_gpio_pin_priv_t *)handle;
gpio_pin_priv->cb = NULL;
gpio_irq_disable(handle);
return 0;
}
/**
\brief control gpio power.
\param[in] idx gpio index.
\param[in] state power state.\ref csi_power_stat_e.
\return error code
*/
int32_t csi_gpio_power_control(gpio_pin_handle_t handle, csi_power_stat_e state)
{
GPIO_NULL_PARAM_CHK(handle);
#ifdef CONFIG_LPM
dw_gpio_pin_priv_t *gpio_pin_priv = (dw_gpio_pin_priv_t *)handle;
power_cb_t callback =
{
.wakeup = do_wakeup_sleep_action,
.sleep = do_prepare_sleep_action,
.manage_clock = manage_clock
};
return drv_soc_power_control(&gpio_handle[gpio_pin_priv->portidx], state, &callback);
#else
return ERR_GPIO(DRV_ERROR_UNSUPPORTED);
#endif
}
/**
\brief config pin mode
\param[in] pin gpio pin handle to operate.
\param[in] mode \ref gpio_mode_e
\return error code
*/
int32_t csi_gpio_pin_config_mode(gpio_pin_handle_t handle,
gpio_mode_e mode)
{
GPIO_NULL_PARAM_CHK(handle);
/* config the gpio pin mode direction mask bits */
dw_gpio_pin_priv_t *gpio_pin_priv = handle;
uint8_t offset = gpio_pin_priv->idx;
int32_t ret = drv_pin_config_mode(gpio_pin_priv->portidx, offset, mode);
return ret;
}
/**
\brief config pin direction
\param[in] pin gpio pin handle to operate.
\param[in] dir \ref gpio_direction_e
\return error code
*/
int32_t csi_gpio_pin_config_direction(gpio_pin_handle_t handle,
gpio_direction_e dir)
{
GPIO_NULL_PARAM_CHK(handle);
/* config the gpio pin mode direction mask bits */
dw_gpio_pin_priv_t *gpio_pin_priv = handle;
/* convert portidx to port handle */
dw_gpio_priv_t *gpio_priv = &gpio_handle[gpio_pin_priv->portidx];
gpio_priv->dir = dir;
gpio_priv->mask = 1 << gpio_pin_priv->idx;
uint32_t ret = gpio_set_direction(gpio_priv, dir);
if (ret)
{
return ret;
}
return 0;
}
/**
\brief config pin
\param[in] handle gpio pin handle to operate.
\param[in] mode \ref gpio_mode_e
\param[in] dir \ref gpio_direction_e
\return error code
*/
int32_t csi_gpio_pin_config(gpio_pin_handle_t handle,
gpio_mode_e mode,
gpio_direction_e dir)
{
GPIO_NULL_PARAM_CHK(handle);
/* config the gpio pin mode direction mask bits */
dw_gpio_pin_priv_t *gpio_pin_priv = handle;
/* convert portidx to port handle */
dw_gpio_priv_t *gpio_priv = &gpio_handle[gpio_pin_priv->portidx];
gpio_priv->mode = mode;
gpio_priv->dir = dir;
gpio_priv->mask = 1 << gpio_pin_priv->idx;
uint32_t ret = gpio_set_direction(gpio_priv, dir);
if (ret)
{
return ret;
}
return 0;
}
/**
\brief Set one or zero to the selected GPIO pin.
\param[in] handle gpio pin handle to operate.
\param[in] value the value to be set
\return error code
*/
int32_t csi_gpio_pin_write(gpio_pin_handle_t handle, bool value)
{
GPIO_NULL_PARAM_CHK(handle);
dw_gpio_pin_priv_t *gpio_pin_priv = handle;
/* convert portidx to port handle */
dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
uint8_t offset = gpio_pin_priv->idx;
uint32_t port_value = value << offset;
port_handle->value = port_value;
gpio_write(port_handle, (1 << offset));
return 0;
}
/**
\brief Get the value of selected GPIO pin.
\param[in] handle gpio pin handle to operate.
\param[out] value buf to store the pin value
\return error code
*/
int32_t csi_gpio_pin_read(gpio_pin_handle_t handle, bool *value)
{
GPIO_NULL_PARAM_CHK(handle);
GPIO_NULL_PARAM_CHK(value);
dw_gpio_pin_priv_t *gpio_pin_priv = handle;
uint32_t port_value;
uint8_t offset = gpio_pin_priv->idx;
/* convert portidx to port handle */
dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
gpio_read(port_handle, &port_value);
*value = (port_value & (1 << offset)) >> offset;
return 0;
}
/**
\brief set GPIO interrupt mode.
\param[in] handle gpio pin handle to operate.
\param[in] mode the irq mode to be set
\param[in] enable the enable flag
\return error code
*/
int32_t csi_gpio_pin_set_irq(gpio_pin_handle_t handle, gpio_irq_mode_e mode, bool enable)
{
GPIO_NULL_PARAM_CHK(handle);
uint32_t ret = 0;
if (enable)
{
ret = gpio_set_irq_mode(handle, mode);
if (ret)
{
return ret;
}
gpio_irq_enable(handle);
} else
{
gpio_irq_disable(handle);
}
return ret;
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen header file for GPIO Driver
*/
#ifndef _DW_GPIO_H_
#define _DW_GPIO_H_
#include "drv_gpio.h"
#include "soc.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
__IOM uint32_t SWPORT_DR; /* Offset: 0x000 (W/R) PortA data register */
__IOM uint32_t SWPORT_DDR; /* Offset: 0x004 (W/R) PortA data direction register */
__IOM uint32_t PORT_CTL; /* Offset: 0x008 (W/R) PortA source register */
} dw_gpio_reg_t;
typedef struct
{
__IOM uint32_t INTEN; /* Offset: 0x000 (W/R) Interrupt enable register */
__IOM uint32_t INTMASK; /* Offset: 0x004 (W/R) Interrupt mask register */
__IOM uint32_t INTTYPE_LEVEL; /* Offset: 0x008 (W/R) Interrupt level register */
__IOM uint32_t INT_POLARITY; /* Offset: 0x00c (W/R) Interrupt polarity register */
__IM uint32_t INTSTATUS; /* Offset: 0x010 (R) Interrupt status of Port */
__IM uint32_t RAWINTSTATUS; /* Offset: 0x014 (W/R) Raw interrupt status of Port */
__IOM uint32_t revreg1; /* Offset: 0x018 (W/R) Reserve register */
__OM uint32_t PORTA_EOI; /* Offset: 0x01c (W/R) Port clear interrupt register */
__IM uint32_t EXT_PORTA; /* Offset: 0x020 (W/R) PortA external port register */
__IM uint32_t EXT_PORTB; /* Offset: 0x024 (W/R) PortB external port register */
__IOM uint32_t revreg2[2]; /* Offset: 0x028 (W/R) Reserve register */
__IOM uint32_t LS_SYNC; /* Offset: 0x030 (W/R) Level-sensitive synchronization enable register */
} dw_gpio_control_reg_t;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,409 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen CSI Source File for timer Driver
*/
#include <csi_config.h>
#include <drv_irq.h>
#include <drv_timer.h>
#include <dw_timer.h>
#include <soc.h>
#include <csi_core.h>
#define ERR_TIMER(errno) (CSI_DRV_ERRNO_TIMER_BASE | errno)
#define TIMER_NULL_PARAM_CHK(para) HANDLE_PARAM_CHK(para, ERR_TIMER(DRV_ERROR_PARAMETER))
typedef struct
{
#ifdef CONFIG_LPM
uint8_t timer_power_status;
uint32_t timer_regs_saved[2];
#endif
uint8_t idx;
uint32_t base;
uint32_t irq;
timer_event_cb_t cb_event;
uint32_t timeout; ///< the set time (us)
uint32_t timeout_flag;
} dw_timer_priv_t;
extern int32_t target_get_timer_count(void);
extern int32_t target_get_timer(int32_t idx, uint32_t *base, uint32_t *irq, void **handler);
static dw_timer_priv_t timer_instance[CONFIG_TIMER_NUM];
/**
\brief Make all the timers in the idle state.
\param[in] pointer to timer register base
*/
static void timer_deactive_control(dw_timer_reg_t *addr)
{
/* stop the corresponding timer */
addr->TxControl &= ~DW_TIMER_TXCONTROL_ENABLE;
/* Disable interrupt. */
addr->TxControl |= DW_TIMER_TXCONTROL_INTMASK;
}
void dw_timer_irqhandler(int idx)
{
dw_timer_priv_t *timer_priv = &timer_instance[idx];
timer_priv->timeout_flag = 1;
dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
addr->TxEOI;
if (timer_priv->cb_event)
{
return timer_priv->cb_event(idx, TIMER_EVENT_TIMEOUT);
}
}
#ifdef CONFIG_LPM
static void manage_clock(timer_handle_t handle, uint8_t enable)
{
if (handle == &timer_instance[0] || handle == &timer_instance[1])
{
drv_clock_manager_config(CLOCK_MANAGER_TIM, enable);
} else if (handle == &timer_instance[3] || handle == &timer_instance[2])
{
drv_clock_manager_config(CLOCK_MANAGER_TIM1, enable);
}
}
static void do_prepare_sleep_action(timer_handle_t handle)
{
dw_timer_priv_t *timer_priv = (dw_timer_priv_t *)handle;
uint32_t *tbase = (uint32_t *)(timer_priv->base);
registers_save(timer_priv->timer_regs_saved, tbase, 1);
registers_save(&timer_priv->timer_regs_saved[1], tbase + 2, 1);
}
static void do_wakeup_sleep_action(timer_handle_t handle)
{
dw_timer_priv_t *timer_priv = (dw_timer_priv_t *)handle;
uint32_t *tbase = (uint32_t *)(timer_priv->base);
registers_restore(tbase, timer_priv->timer_regs_saved, 1);
registers_restore(tbase + 2, &timer_priv->timer_regs_saved[1], 1);
}
#endif
/**
\brief Initialize TIMER Interface. 1. Initializes the resources needed for the TIMER interface 2.registers event callback function
\param[in] idx instance timer index
\param[in] cb_event Pointer to \ref timer_event_cb_t
\return pointer to timer instance
*/
timer_handle_t csi_timer_initialize(int32_t idx, timer_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_TIMER_NUM)
{
return NULL;
}
uint32_t base = 0u;
uint32_t irq = 0u;
void *handler;
int32_t real_idx = target_get_timer(idx, &base, &irq, &handler);
if (real_idx != idx)
{
return NULL;
}
dw_timer_priv_t *timer_priv = &timer_instance[idx];
timer_priv->base = base;
timer_priv->irq = irq;
timer_priv->idx = idx;
dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
timer_priv->timeout = DW_TIMER_INIT_DEFAULT_VALUE;
#ifdef CONFIG_LPM
csi_timer_power_control(timer_priv, DRV_POWER_FULL);
#endif
timer_deactive_control(addr);
timer_priv->cb_event = cb_event;
if (cb_event != NULL)
{
drv_irq_register(timer_priv->irq, handler);
drv_irq_enable(timer_priv->irq);
}
return (timer_handle_t)timer_priv;
}
/**
\brief De-initialize TIMER Interface. stops operation and releases the software resources used by the interface
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_uninitialize(timer_handle_t handle)
{
TIMER_NULL_PARAM_CHK(handle);
dw_timer_priv_t *timer_priv = (dw_timer_priv_t *)handle;
dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
timer_deactive_control(addr);
timer_priv->cb_event = NULL;
drv_irq_disable(timer_priv->irq);
drv_irq_unregister(timer_priv->irq);
#ifdef CONFIG_LPM
csi_timer_power_control(timer_priv, DRV_POWER_OFF);
#endif
return 0;
}
int32_t csi_timer_power_control(timer_handle_t handle, csi_power_stat_e state)
{
TIMER_NULL_PARAM_CHK(handle);
#ifdef CONFIG_LPM
power_cb_t callback =
{
.wakeup = do_wakeup_sleep_action,
.sleep = do_prepare_sleep_action,
.manage_clock = manage_clock
};
return drv_soc_power_control(handle, state, &callback);
#else
return ERR_TIMER(DRV_ERROR_UNSUPPORTED);
#endif
}
/**
\brief config timer mode.
\param[in] handle timer handle to operate.
\param[in] mode \ref timer_mode_e
\return error code
*/
int32_t csi_timer_config(timer_handle_t handle, timer_mode_e mode)
{
TIMER_NULL_PARAM_CHK(handle);
dw_timer_priv_t *timer_priv = handle;
dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
switch (mode)
{
case TIMER_MODE_FREE_RUNNING:
addr->TxControl &= ~DW_TIMER_TXCONTROL_MODE;
break;
case TIMER_MODE_RELOAD:
addr->TxControl |= DW_TIMER_TXCONTROL_MODE;
break;
default:
return ERR_TIMER(DRV_ERROR_PARAMETER);
}
addr->TxControl |= (DW_TIMER_TXCONTROL_TRIGGER);
return 0;
}
/**
\brief Set timer.
\param[in] instance timer instance to operate.
\param[in] timeout the timeout value in microseconds(us).
\return error code
*/
int32_t csi_timer_set_timeout(timer_handle_t handle, uint32_t timeout)
{
TIMER_NULL_PARAM_CHK(handle);
dw_timer_priv_t *timer_priv = handle;
timer_priv->timeout = timeout;
return 0;
}
/**
\brief Start timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_start(timer_handle_t handle)
{
TIMER_NULL_PARAM_CHK(handle);
dw_timer_priv_t *timer_priv = handle;
timer_priv->timeout_flag = 0;
uint32_t min_us = drv_get_timer_freq(timer_priv->idx) / 1000000;
uint32_t load;
if (((timer_priv->timeout * drv_get_timer_freq(timer_priv->idx)) / 1000000) > 0xffffffff)
{
return ERR_TIMER(DRV_ERROR_PARAMETER);
}
if (min_us)
{
load = (uint32_t)(timer_priv->timeout * min_us);
} else
{
load = (uint32_t)(((uint64_t)(timer_priv->timeout) * drv_get_timer_freq(timer_priv->idx)) / 1000000);
}
dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
if (timer_priv->timeout == 0) {
addr->TxLoadCount = 0xffffffff; /* load time(us) */
} else
{
if ((addr->TxControl | 0x2) == 0x2) {
addr->TxLoadCount = 0xffffffff; /* load time(us) */
} else
{
addr->TxLoadCount = load; /* load time(us) */
}
}
addr->TxControl &= ~DW_TIMER_TXCONTROL_ENABLE; /* disable the timer */
addr->TxControl |= DW_TIMER_TXCONTROL_ENABLE; /* enable the corresponding timer */
addr->TxControl &= ~DW_TIMER_TXCONTROL_INTMASK; /* enable interrupt */
/* avoid timer bug on yunvoice soc */
#ifdef CONFIG_CHIP_YUNVOICE
if (addr->TxCurrentValue > addr->TxLoadCount) {
addr->TxControl &= ~DW_TIMER_TXCONTROL_ENABLE; /* disable the timer */
addr->TxControl |= DW_TIMER_TXCONTROL_ENABLE; /* enable the corresponding timer */
addr->TxControl &= ~DW_TIMER_TXCONTROL_INTMASK; /* enable interrupt */
}
#endif
return 0;
}
/**
\brief Stop timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_stop(timer_handle_t handle)
{
TIMER_NULL_PARAM_CHK(handle);
dw_timer_priv_t *timer_priv = handle;
dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
addr->TxControl |= DW_TIMER_TXCONTROL_INTMASK; /* enable interrupt */
addr->TxControl &= ~DW_TIMER_TXCONTROL_ENABLE; /* disable the timer */
return 0;
}
/**
\brief suspend timer.
\param[in] instance timer instance to operate.
\return error code
*/
int32_t csi_timer_suspend(timer_handle_t handle)
{
TIMER_NULL_PARAM_CHK(handle);
return ERR_TIMER(DRV_ERROR_UNSUPPORTED);
}
/**
\brief resume timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_resume(timer_handle_t handle)
{
TIMER_NULL_PARAM_CHK(handle);
dw_timer_priv_t *timer_priv = handle;
dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
addr->TxControl &= ~DW_TIMER_TXCONTROL_ENABLE; /* stop the corresponding timer */
addr->TxControl &= DW_TIMER_TXCONTROL_ENABLE; /* restart the corresponding timer */
return 0;
}
/**
\brief get timer current value
\param[in] handle timer handle to operate.
\param[out] value timer current value
\return error code
*/
int32_t csi_timer_get_current_value(timer_handle_t handle, uint32_t *value)
{
TIMER_NULL_PARAM_CHK(handle);
TIMER_NULL_PARAM_CHK(value);
dw_timer_priv_t *timer_priv = handle;
dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
*value = addr->TxCurrentValue;
return 0;
}
/**
\brief Get TIMER status.
\param[in] handle timer handle to operate.
\return TIMER status \ref timer_status_t
*/
timer_status_t csi_timer_get_status(timer_handle_t handle)
{
timer_status_t timer_status = {0};
if (handle == NULL)
{
return timer_status;
}
dw_timer_priv_t *timer_priv = handle;
dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
if (addr->TxControl & DW_TIMER_TXCONTROL_ENABLE)
{
timer_status.active = 1;
}
if (timer_priv->timeout_flag == 1)
{
timer_status.timeout = 1;
}
return timer_status;
}
/**
\brief get timer reload value
\param[in] handle timer handle to operate.
\param[out] value timer reload value
\return error code
*/
int32_t csi_timer_get_load_value(timer_handle_t handle, uint32_t *value)
{
TIMER_NULL_PARAM_CHK(handle);
TIMER_NULL_PARAM_CHK(value);
dw_timer_priv_t *timer_priv = handle;
dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
*value = addr->TxLoadCount;
return 0;
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen header file for timer driver
*/
#ifndef __DW_TIMER_H
#define __DW_TIMER_H
#include <stdio.h>
#include "soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* define the bits for TxControl
*/
#define DW_TIMER_TXCONTROL_ENABLE (1UL << 0)
#define DW_TIMER_TXCONTROL_MODE (1UL << 1)
#define DW_TIMER_TXCONTROL_INTMASK (1UL << 2)
#define DW_TIMER_TXCONTROL_TRIGGER (1UL << 4)
#define DW_TIMER_INIT_DEFAULT_VALUE (0xffffffff / drv_get_timer_freq(0) * 1000000)
typedef struct
{
__IOM uint32_t TxLoadCount; /* Offset: 0x000 (R/W) Receive buffer register */
__IM uint32_t TxCurrentValue; /* Offset: 0x004 (R) Transmission hold register */
__IOM uint8_t TxControl: 5; /* Offset: 0x008 (R/W) Clock frequency division low section register */
uint8_t RESERVED0[3];
__IM uint8_t TxEOI: 1; /* Offset: 0x00c (R) Clock frequency division high section register */
uint8_t RESERVED1[3];
__IM uint8_t TxIntStatus: 1; /* Offset: 0x010 (R) Interrupt enable register */
uint8_t RESERVED2[3];
} dw_timer_reg_t;
#ifdef __cplusplus
}
#endif
#endif /* __DW_TIMER_H */

View File

@ -0,0 +1,195 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen source file for the interrupt server route
*/
#include <drv_common.h>
#include <csi_config.h>
#include "soc.h"
#ifndef CONFIG_SYSTICK_HZ
#define CONFIG_SYSTICK_HZ 100
#endif
extern volatile uint32_t rt_thread_switch_interrupt_flag;
extern void ck_usart_irqhandler(int32_t idx);
extern void dw_timer_irqhandler(int32_t idx);
extern void dw_gpio_irqhandler(int32_t idx);
extern void systick_handler(void);
extern void xPortSysTickHandler(void);
extern void OSTimeTick(void);
#define ATTRIBUTE_ISR
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#if(CONFIG_KERNEL_RTTHREAD == 1)
#define CSI_INTRPT_ENTER() rt_interrupt_enter()
#define CSI_INTRPT_EXIT() rt_interrupt_leave()
#endif
void __attribute__((isr)) SysTick_Handler(void)
{
#if(CONFIG_KERNEL_RTTHREAD == 1)
CSI_INTRPT_ENTER();
#endif
csi_coret_config(drv_get_sys_freq() / CONFIG_SYSTICK_HZ, CORET_IRQn);
#if defined(CONFIG_KERNEL_RHINO)
systick_handler();
#elif defined(CONFIG_KERNEL_FREERTOS)
xPortSysTickHandler();
#elif defined(CONFIG_KERNEL_RTTHREAD)
rt_tick_increase();
#elif defined(CONFIG_KERNEL_UCOS)
OSTimeTick();
#endif
#if(CONFIG_KERNEL_RTTHREAD == 1)
CSI_INTRPT_EXIT();
#endif
}
ATTRIBUTE_ISR void USART_IRQHandler(void)
{
CSI_INTRPT_ENTER();
ck_usart0_irqhandler();
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIM0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIM1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIM2_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(2);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIM3_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(3);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIM4_NMIHandler(void)
{
dw_timer_irqhandler(4);
}
ATTRIBUTE_ISR void TIM6_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(6);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIM7_IRQHandler(void)
{
dw_timer_irqhandler(7);
}
ATTRIBUTE_ISR void TIM8_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(8);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIM9_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(9);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIM10_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(10);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void TIM11_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_timer_irqhandler(11);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIO0_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(0);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIO1_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(1);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIO2_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(2);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIO3_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(3);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIO4_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(4);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIO5_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(5);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIO6_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(6);
CSI_INTRPT_EXIT();
}
ATTRIBUTE_ISR void GPIO7_IRQHandler(void)
{
CSI_INTRPT_ENTER();
dw_gpio_irqhandler(7);
CSI_INTRPT_EXIT();
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen novic table init
*/
#include <csi_config.h>
#include <soc.h>
extern void Default_Handler(void);
extern void SysTick_Handler(void);
extern void TIM4_NMIHandler(void);
void (*g_irqvector[48])(void);
void (*g_nmivector)(void);
void irq_vectors_init(void)
{
int i;
for (i = 0; i < 48; i++)
{
g_irqvector[i] = Default_Handler;
}
g_irqvector[CORET_IRQn] = SysTick_Handler;
g_nmivector = TIM4_NMIHandler;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen header file for the pin_name
*/
#ifndef _PINNAMES_H
#define _PINNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
PA0 = 0,
PA1,
PA2,
PA3,
PA4,
PA5,
PA6,
PA7,
PAD_UART0_SIN,
PAD_UART0_SOUT
}
pin_name_e;
typedef enum
{
PORTA = 0,
PORTB = 1,
PORTC = 2,
PORTD = 3,
PORTE = 4,
PORTF = 5,
PORTG = 6,
PORTH = 7
} port_name_e;
typedef enum
{
NONE = 0
} pin_func_e;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,119 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen CSI Core Peripheral Access Layer Header File for
* CSKYSOC Device Series
*/
#ifndef _SOC_H_
#define _SOC_H_
#include <stdint.h>
#include <csi_core.h>
#include <sys_freq.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef IHS_VALUE
#define IHS_VALUE (20000000)
#endif
#ifndef EHS_VALUE
#define EHS_VALUE (20000000)
#endif
/* ------------------------- Interrupt Number Definition ------------------------ */
typedef enum IRQn {
NMI_EXPn = -2, /* NMI Exception */
/* ---------------------- SmartL Specific Interrupt Numbers --------------------- */
Machine_Software_IRQn = 3, /* Machine software interrupt */
User_Timer_IRQn = 4, /* User timer interrupt */
Supervisor_Timer_IRQn = 5, /* Supervisor timer interrupt */
CORET_IRQn = 7, /* core Timer Interrupt */
Machine_External_IRQn = 11, /* Machine external interrupt */
UART_IRQn = 16, /* uart Interrupt */
TIM0_IRQn = 18, /* timer0 Interrupt */
TIM1_IRQn = 19, /* timer1 Interrupt */
TIM2_IRQn = 20, /* timer2 Interrupt */
TIM3_IRQn = 21, /* timer3 Interrupt */
GPIO0_IRQn = 23, /* gpio0 Interrupt */
GPIO1_IRQn = 24, /* gpio1 Interrupt */
GPIO2_IRQn = 25, /* gpio2 Interrupt */
GPIO3_IRQn = 26, /* gpio3 Interrupt */
GPIO4_IRQn = 27, /* gpio4 Interrupt */
GPIO5_IRQn = 28, /* gpio5 Interrupt */
GPIO6_IRQn = 29, /* gpio6 Interrupt */
GPIO7_IRQn = 30, /* gpio7 Interrupt */
STIM0_IRQn = 31, /* stimer0 Interrupt */
STIM1_IRQn = 32, /* stimer1 Interrupt */
STIM2_IRQn = 33, /* stimer2 Interrupt */
STIM3_IRQn = 34, /* stimer3 Interrupt */
PAD_IRQn = 35, /* pad Interrupt */
TIM6_IRQn = 36, /* timer6 Interrupt */
TIM7_IRQn = 37, /* timer7 Interrupt */
TIM8_IRQn = 38, /* timer8 Interrupt */
TIM9_IRQn = 39, /* timer9 Interrupt */
TIM10_IRQn = 40, /* timer10 Interrupt */
TIM11_IRQn = 41, /* timer11 Interrupt */
}
IRQn_Type;
/* ================================================================================ */
/* ================ Device Specific Peripheral Section ================ */
/* ================================================================================ */
#define CONFIG_TIMER_NUM 12
#define CONFIG_USART_NUM 1
#define CONFIG_GPIO_NUM 8
#define CONFIG_GPIO_PIN_NUM 8
/* ================================================================================ */
/* ================ Peripheral memory map ================ */
/* ================================================================================ */
/* -------------------------- CPU FPGA memory map ------------------------------- */
#define CSKY_SRAM_BASE (0x20000000UL)
#define CSKY_UART_BASE (0x40015000UL)
#define CSKY_PMU_BASE (0x40016000UL)
#define CSKY_TIMER0_BASE (0x40011000UL)
#define CSKY_TIMER1_BASE (0x40011014UL)
#define CSKY_TIMER2_BASE (0x40011028UL)
#define CSKY_TIMER3_BASE (0x4001103cUL)
#define CSKY_TIMER4_BASE (0x40021000UL)
#define CSKY_TIMER5_BASE (0x40021014UL)
#define CSKY_TIMER6_BASE (0x40021028UL)
#define CSKY_TIMER7_BASE (0x4002103cUL)
#define CSKY_TIMER8_BASE (0x40031000UL)
#define CSKY_TIMER9_BASE (0x40031014UL)
#define CSKY_TIMER10_BASE (0x40031028UL)
#define CSKY_TIMER11_BASE (0x4003103cUL)
#define CSKY_TIMER_CONTROL_BASE (0x400110a0UL)
#define CSKY_CLK_GEN_BASE (0x40017000UL)
#define CSKY_STIMER0_BASE (0x40018000UL)
#define CSKY_STIMER1_BASE (0x40018014UL)
#define CSKY_STIMER2_BASE (0x40018028UL)
#define CSKY_STIMER3_BASE (0x4001803cUL)
#define CSKY_STIMER_CONTROL_BASE (0x400110a0UL)
#define CSKY_GPIOA_BASE (0x40019000UL)
#define CSKY_GPIOA_CONTROL_BASE (0x40019030UL)
#define CSKY_SMPU_BASE (0x4001a000UL)
/* ================================================================================ */
/* ================ Peripheral declaration ================ */
/* ================================================================================ */
#define CSKY_UART (( CSKY_UART_TypeDef *) CSKY_UART_BASE)
#ifdef __cplusplus
}
#endif
#endif /* _SOC_H_ */

View File

@ -0,0 +1,132 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen startup file. Should use with
* GCC for T-HEAD Embedded Processors
*/
#include <csi_config.h>
.section .vectors, "aw", @progbits
.align 6
.globl __Vectors
.type __Vectors, @object
__Vectors:
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long PendSV_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_IRQHandler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
/* External interrupts */
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.text
.align 2
_start:
.text
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
.option push
.option norelax
la gp, __global_pointer$
.option pop
la a0, Default_Handler
ori a0, a0, 3
csrw mtvec, a0
la a0, __Vectors
csrw mtvt, a0
la sp, __StackTop
csrw mscratch, sp
/* Load data section */
la a0, __erodata
la a1, __data_start__
la a2, __data_end__
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, __bss_end__
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
#ifndef __NO_SYSTEM_INIT
jal SystemInit
#endif
jal entry
.size Reset_Handler, . - Reset_Handler
__exit:
j __exit
.section .bss
.align 3
.global g_base_irqstack
.global g_top_irqstack
g_base_irqstack:
.space CONFIG_ARCH_INTERRUPTSTACK
g_top_irqstack:

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen setting system frequency
*/
#include <stdint.h>
#include <soc.h>
#include <sys_freq.h>
extern int g_system_clock;
int32_t drv_get_cpu_freq(int32_t idx)
{
return g_system_clock;
}
int32_t drv_get_usi_freq(int32_t idx)
{
return g_system_clock;
}
int32_t drv_get_usart_freq(int32_t idx)
{
return g_system_clock;
}
int32_t drv_get_pwm_freq(int32_t idx)
{
return g_system_clock;
}
int32_t drv_get_i2s_freq(int32_t idx)
{
return g_system_clock;
}
int32_t drv_get_sys_freq(void)
{
return g_system_clock;
}
int32_t drv_get_rtc_freq(int32_t idx)
{
return g_system_clock;
}
int32_t drv_get_apb_freq(void)
{
return g_system_clock;
}
int32_t drv_get_timer_freq(int32_t idx)
{
return g_system_clock;
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen header file for setting system frequency
*/
#ifndef _SYS_FREQ_H_
#define _SYS_FREQ_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int32_t drv_get_i2s_freq(int32_t idx);
int32_t drv_get_pwm_freq(int32_t idx);
int32_t drv_get_usart_freq(int32_t idx);
int32_t drv_get_usi_freq(int32_t idx);
int32_t drv_get_sys_freq(void);
int32_t drv_get_apb_freq(void);
int32_t drv_get_rtc_freq(int32_t idx);
int32_t drv_get_timer_freq(int32_t idx);
int32_t drv_get_cpu_freq(int32_t idx);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_FREQ_H_ */

View File

@ -0,0 +1,85 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen CSI Device System Source File
*/
#include <csi_config.h>
#include <soc.h>
#include <csi_core.h>
#include <drv_irq.h>
#ifndef CONFIG_SYSTICK_HZ
#define CONFIG_SYSTICK_HZ 100
#endif
int g_system_clock = IHS_VALUE;
extern int32_t g_top_irqstack;
extern void irq_vectors_init(void);
extern void mm_heap_initialize(void);
int SystemCoreClock = IHS_VALUE; /* System Core Clock Frequency */
extern int __Vectors;
void SystemCoreClockUpdate(void)
{
SystemCoreClock = IHS_VALUE;
}
static void _system_init_for_kernel(void)
{
irq_vectors_init();
csi_coret_config(drv_get_sys_freq() / CONFIG_SYSTICK_HZ, CORET_IRQn); //10ms
drv_irq_enable(CORET_IRQn);
}
/**
* @brief initialize the system
* Initialize the psr and vbr.
* @param None
* @return None
*/
void SystemInit(void)
{
int i;
/* enable mstatus FS */
#if ((CONFIG_CPU_E906F==1) || (CONFIG_CPU_E906FD==1))
uint32_t mstatus = __get_MSTATUS();
mstatus |= (1 << 13);
__set_MSTATUS(mstatus);
#endif
/* enable mxstatus THEADISAEE */
uint32_t mxstatus = __get_MXSTATUS();
mxstatus |= (1 << 22);
/* enable mxstatus MM */
#if ((CONFIG_CPU_E906==1) || (CONFIG_CPU_E906F==1) || (CONFIG_CPU_E906FD==1))
mxstatus |= (1 << 15);
#endif
__set_MXSTATUS(mxstatus);
/* get interrupt level from info */
CLIC->CLICCFG = (((CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos) << CLIC_CLICCFG_NLBIT_Pos);
for (i = 0; i < 64; i++)
{
CLIC->CLICINT[i].IP = 0;
CLIC->CLICINT[i].ATTR = 1; /* use vector interrupt */
}
/* tspend use positive interrupt */
CLIC->CLICINT[Machine_Software_IRQn].ATTR = 0x3;
csi_dcache_enable();
csi_icache_enable();
drv_irq_enable(Machine_Software_IRQn);
_system_init_for_kernel();
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen source file for the trap process
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <csi_config.h>
#include <csi_core.h>
void (*trap_c_callback)(void);
void trap_c(uint32_t *regs)
{
int i;
uint32_t vec = 0;
vec = __get_MCAUSE() & 0x3FF;
printf("CPU Exception: NO.%d", vec);
printf("\n");
for (i = 0; i < 31; i++)
{
printf("x%d: %08x\t", i + 1, regs[i]);
if ((i % 4) == 3)
{
printf("\n");
}
}
printf("\n");
printf("mepc : %08x\n", regs[31]);
printf("mstatus: %08x\n", regs[32]);
if (trap_c_callback)
{
trap_c_callback();
}
while (1);
}

View File

@ -0,0 +1,349 @@
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen define default vector handlers.
*/
#include <csi_config.h>
/* Enable interrupts when returning from the handler */
#define MSTATUS_PRV1 0x1880
.section .bss
.align 2
.globl g_trapstackalloc
.global g_trapstackbase
.global g_top_trapstack
g_trapstackalloc:
g_trapstackbase:
.space 768
g_top_trapstack:
.align 2
.globl g_trap_sp
.type g_trap_sp, object
g_trap_sp:
.long 0
.size g_trap_sp, .-g_trap_sp
irq_nested_level:
.long 0
#ifdef ARCH_RISCV_FPU
irq_mstatus_fs_flag:
.long 0
#endif
.text
.align 2
.global Default_IRQHandler
.weak Default_IRQHandler
.type Default_IRQHandler, %function
Default_IRQHandler:
ipush
#ifdef ARCH_RISCV_FPU
csrr t1, mstatus
srli t1, t1, 13
andi t1, t1, 0x3
la t3, irq_mstatus_fs_flag
sw t1, (t3)
li t0, 0x3
bne t1, t0, .F_RegNotSave1
addi sp, sp, -(20 * FREGBYTES)
FSTORE ft0, 0 * FREGBYTES(sp)
FSTORE ft1, 1 * FREGBYTES(sp)
FSTORE ft2, 2 * FREGBYTES(sp)
FSTORE ft3, 3 * FREGBYTES(sp)
FSTORE ft4, 4 * FREGBYTES(sp)
FSTORE ft5, 5 * FREGBYTES(sp)
FSTORE ft6, 6 * FREGBYTES(sp)
FSTORE ft7, 7 * FREGBYTES(sp)
FSTORE fa0, 8 * FREGBYTES(sp)
FSTORE fa1, 9 * FREGBYTES(sp)
FSTORE fa2, 10 * FREGBYTES(sp)
FSTORE fa3, 11 * FREGBYTES(sp)
FSTORE fa4, 12 * FREGBYTES(sp)
FSTORE fa5, 13 * FREGBYTES(sp)
FSTORE fa6, 14 * FREGBYTES(sp)
FSTORE fa7, 15 * FREGBYTES(sp)
FSTORE ft8, 16 * FREGBYTES(sp)
FSTORE ft9, 17 * FREGBYTES(sp)
FSTORE ft10, 18 * FREGBYTES(sp)
FSTORE ft11, 19 * FREGBYTES(sp)
.F_RegNotSave1:
#endif
csrr t1, mcause
andi t1, t1, 0x3FF
slli t1, t1, 2
la t0, g_irqvector
add t0, t0, t1
lw t2, (t0)
jalr t2
li t0, MSTATUS_PRV1
csrs mstatus, t0
#ifdef ARCH_RISCV_FPU
la t0, irq_mstatus_fs_flag
lw t1, (t0)
li t0, 0x3
bne t1, t0, .F_RegNotLoad
FLOAD ft0, 0 * FREGBYTES(sp)
FLOAD ft1, 1 * FREGBYTES(sp)
FLOAD ft2, 2 * FREGBYTES(sp)
FLOAD ft3, 3 * FREGBYTES(sp)
FLOAD ft4, 4 * FREGBYTES(sp)
FLOAD ft5, 5 * FREGBYTES(sp)
FLOAD ft6, 6 * FREGBYTES(sp)
FLOAD ft7, 7 * FREGBYTES(sp)
FLOAD fa0, 8 * FREGBYTES(sp)
FLOAD fa1, 9 * FREGBYTES(sp)
FLOAD fa2, 10 * FREGBYTES(sp)
FLOAD fa3, 11 * FREGBYTES(sp)
FLOAD fa4, 12 * FREGBYTES(sp)
FLOAD fa5, 13 * FREGBYTES(sp)
FLOAD fa6, 14 * FREGBYTES(sp)
FLOAD fa7, 15 * FREGBYTES(sp)
FLOAD ft8, 16 * FREGBYTES(sp)
FLOAD ft9, 17 * FREGBYTES(sp)
FLOAD ft10,18 * FREGBYTES(sp)
FLOAD ft11,19 * FREGBYTES(sp)
addi sp, sp, (20 * FREGBYTES)
.F_RegNotLoad:
#endif
ipop
/******************************************************************************
* Functions:
* void trap(void);
* default exception handler
******************************************************************************/
.align 2
.global trap
.type trap, %function
trap:
/* Check for interrupt */
addi sp, sp, -4
sw t0, 0x0(sp)
csrr t0, mcause
blt t0, x0, .Lirq
addi sp, sp, 4
la t0, g_trap_sp
addi t0, t0, -132
sw x1, 0(t0)
sw x2, 4(t0)
sw x3, 8(t0)
sw x4, 12(t0)
sw x6, 20(t0)
sw x7, 24(t0)
sw x8, 28(t0)
sw x9, 32(t0)
sw x10, 36(t0)
sw x11, 40(t0)
sw x12, 44(t0)
sw x13, 48(t0)
sw x14, 52(t0)
sw x15, 56(t0)
sw x16, 60(t0)
sw x17, 64(t0)
sw x18, 68(t0)
sw x19, 72(t0)
sw x20, 76(t0)
sw x21, 80(t0)
sw x22, 84(t0)
sw x23, 88(t0)
sw x24, 92(t0)
sw x25, 96(t0)
sw x26, 100(t0)
sw x27, 104(t0)
sw x28, 108(t0)
sw x29, 112(t0)
sw x30, 116(t0)
sw x31, 120(t0)
csrr a0, mepc
sw a0, 124(t0)
csrr a0, mstatus
sw a0, 128(t0)
mv a0, t0
lw t0, -4(sp)
mv sp, a0
sw t0, 16(sp)
jal trap_c
.Lirq:
lw t0, 0x0(sp)
addi sp, sp, 4
j Default_IRQHandler
.align 6
.weak Default_Handler
.global Default_Handler
.type Default_Handler, %function
Default_Handler:
/* Check for nmi */
addi sp, sp, -8
sw t0, 0x0(sp)
sw t1, 0x4(sp)
csrr t0, mcause
andi t0, t0, 0x3FF
li t1, 24
beq t0, t1, .NMI_Handler
lw t0, 0x0(sp)
lw t1, 0x4(sp)
addi sp, sp, 8
j trap
.NMI_Handler:
lw t0, 0x0(sp)
lw t1, 0x4(sp)
addi sp, sp, 8
addi sp, sp, -64
sw ra, 0(sp)
sw t0, 4(sp)
sw t1, 8(sp)
sw t2, 12(sp)
sw a0, 16(sp)
sw a1, 20(sp)
sw a2, 24(sp)
sw a3, 28(sp)
sw a4, 32(sp)
sw a5, 36(sp)
sw a6, 40(sp)
sw a7, 44(sp)
sw t3, 48(sp)
sw t4, 52(sp)
sw t5, 56(sp)
sw t6, 60(sp)
#ifdef ARCH_RISCV_FPU
addi sp, sp, -(20*FREGBYTES)
FSTORE ft0, 0 * FREGBYTES(sp)
FSTORE ft1, 1 * FREGBYTES(sp)
FSTORE ft2, 2 * FREGBYTES(sp)
FSTORE ft3, 3 * FREGBYTES(sp)
FSTORE ft4, 4 * FREGBYTES(sp)
FSTORE ft5, 5 * FREGBYTES(sp)
FSTORE ft6, 6 * FREGBYTES(sp)
FSTORE ft7, 7 * FREGBYTES(sp)
FSTORE fa0, 8 * FREGBYTES(sp)
FSTORE fa1, 9 * FREGBYTES(sp)
FSTORE fa2, 10 * FREGBYTES(sp)
FSTORE fa3, 11 * FREGBYTES(sp)
FSTORE fa4, 12 * FREGBYTES(sp)
FSTORE fa5, 13 * FREGBYTES(sp)
FSTORE fa6, 14 * FREGBYTES(sp)
FSTORE fa7, 15 * FREGBYTES(sp)
FSTORE ft8, 16 * FREGBYTES(sp)
FSTORE ft9, 17 * FREGBYTES(sp)
FSTORE ft10, 18 * FREGBYTES(sp)
FSTORE ft11, 19 * FREGBYTES(sp)
#endif
la t0, g_nmivector
lw t0, (t0)
jalr t0
#ifdef ARCH_RISCV_FPU
FLOAD ft0, 0 * FREGBYTES(sp)
FLOAD ft1, 1 * FREGBYTES(sp)
FLOAD ft2, 2 * FREGBYTES(sp)
FLOAD ft3, 3 * FREGBYTES(sp)
FLOAD ft4, 4 * FREGBYTES(sp)
FLOAD ft5, 5 * FREGBYTES(sp)
FLOAD ft6, 6 * FREGBYTES(sp)
FLOAD ft7, 7 * FREGBYTES(sp)
FLOAD fa0, 8 * FREGBYTES(sp)
FLOAD fa1, 9 * FREGBYTES(sp)
FLOAD fa2, 10 * FREGBYTES(sp)
FLOAD fa3, 11 * FREGBYTES(sp)
FLOAD fa4, 12 * FREGBYTES(sp)
FLOAD fa5, 13 * FREGBYTES(sp)
FLOAD fa6, 14 * FREGBYTES(sp)
FLOAD fa7, 15 * FREGBYTES(sp)
FLOAD ft8, 16 * FREGBYTES(sp)
FLOAD ft9, 17 * FREGBYTES(sp)
FLOAD ft10, 18 * FREGBYTES(sp)
FLOAD ft11, 19 * FREGBYTES(sp)
addi sp, sp, (20 * FREGBYTES)
#endif
lw ra, 0(sp)
lw t0, 4(sp)
lw t1, 8(sp)
lw t2, 12(sp)
lw a0, 16(sp)
lw a1, 20(sp)
lw a2, 24(sp)
lw a3, 28(sp)
lw a4, 32(sp)
lw a5, 36(sp)
lw a6, 40(sp)
lw a7, 44(sp)
lw t3, 48(sp)
lw t4, 52(sp)
lw t5, 56(sp)
lw t6, 60(sp)
addi sp, sp, 64
mret
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.globl \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler STIM0_IRQHandler
def_irq_handler STIM1_IRQHandler
def_irq_handler STIM2_IRQHandler
def_irq_handler STIM3_IRQHandler
def_irq_handler TIM0_IRQHandler
def_irq_handler TIM1_IRQHandler
def_irq_handler TIM2_IRQHandler
def_irq_handler TIM3_IRQHandler
def_irq_handler USART_IRQHandler
def_irq_handler GPIO0_IRQHandler
def_irq_handler GPIO1_IRQHandler
def_irq_handler GPIO2_IRQHandler
def_irq_handler GPIO3_IRQHandler
def_irq_handler GPIO4_IRQHandler
def_irq_handler GPIO5_IRQHandler
def_irq_handler GPIO6_IRQHandler
def_irq_handler GPIO7_IRQHandler
def_irq_handler PAD_IRQHandler
def_irq_handler TIM6_IRQHandler
def_irq_handler TIM7_IRQHandler
def_irq_handler TIM8_IRQHandler
def_irq_handler TIM9_IRQHandler
def_irq_handler TIM10_IRQHandler
def_irq_handler TIM11_IRQHandler

184
bsp/thead-smart/gcc_csky.ld Normal file
View File

@ -0,0 +1,184 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* 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
*
* http://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_csky.h
* @brief csky linker file for PHOBOS
* @version V1.0
* @date 02. June 2017
******************************************************************************/
MEMORY
{
I-SRAM : ORIGIN = 0x0 , LENGTH = 0x40000 /* I-SRAM 256KB */
D-SRAM : ORIGIN = 0x20000000 , LENGTH = 0xc0000 /* D-SRAM 768KB */
O-SRAM : ORIGIN = 0x50000000 , LENGTH = 0x800000 /* off-chip SRAM 8MB */
SRAM : ORIGIN = 0x60000000 , LENGTH = 0x20000 /* on-chip SRAM 128KB */
}
PROVIDE (__StackTop = 0x200c0000 - 0x8);
PROVIDE (Stack_Size = 0x1000);
REGION_ALIAS("REGION_TEXT", I-SRAM);
REGION_ALIAS("REGION_RODATA", I-SRAM);
REGION_ALIAS("REGION_CUSTOM1", D-SRAM);
REGION_ALIAS("REGION_CUSTOM2", D-SRAM);
REGION_ALIAS("REGION_DATA", D-SRAM);
REGION_ALIAS("REGION_BSS", D-SRAM);
ENTRY(Reset_Handler)
SECTIONS
{
.text : AT(ADDR(.text)){
. = ALIGN(0x4) ;
__stext = . ;
KEEP(*startup.o(*.text*))
*(.text)
*(.text*)
*(.text.*)
*(.gnu.warning)
*(.stub)
*(.gnu.linkonce.t*)
*(.glue_7t)
*(.glue_7)
*(.jcr)
*(.init)
*(.fini)
. = ALIGN (4) ;
PROVIDE(__ctbp = .);
*(.call_table_data)
*(.call_table_text)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
. = ALIGN(0x10) ;
__etext = . ;
} > REGION_TEXT
.eh_frame_hdr : {
*(.eh_frame_hdr)
} > REGION_TEXT
.eh_frame : ONLY_IF_RO {
KEEP (*(.eh_frame))
} > REGION_TEXT
.gcc_except_table : ONLY_IF_RO {
*(.gcc_except_table .gcc_except_table.*)
} > REGION_TEXT
.rodata :{
. = ALIGN(0x4) ;
__srodata = .;
*(.rdata)
*(.rdata*)
*(.rdata1)
*(.rdata.*)
*(.rodata)
*(.rodata1)
*(.rodata*)
*(.rodata.*)
*(.rodata.str1.4)
. = ALIGN(0x4) ;
__ctor_start__ = .;
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__ctor_end__ = .;
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__dtor_end__ = .;
. = ALIGN(0x4) ;
__erodata = .;
__rodata_end__ = .;
} > REGION_RODATA
.data : {
. = ALIGN(0x4) ;
__sdata = . ;
__data_start__ = . ;
data_start = . ;
KEEP(*startup.o(*.vectors*))
*(.got.plt)
*(.got)
*(.gnu.linkonce.r*)
*(.data)
*(.data*)
*(.data1)
*(.data.*)
*(.gnu.linkonce.d*)
*(.data1)
*(.gcc_except_table)
*(.gcc_except_table*)
__start_init_call = .;
*(.initcall.init)
__stop_init_call = .;
__start_cmd = .;
*(.bootloaddata.cmd)
. = ALIGN(4) ;
__stop_cmd = .;
__global_pointer$ = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(__libc_atexit)
*(__libc_subinit)
*(__libc_subfreeres)
*(.note.ABI-tag)
__edata = .;
__data_end__ = .;
. = ALIGN(0x4) ;
} > REGION_DATA AT > REGION_RODATA
.eh_frame : ONLY_IF_RW {
KEEP (*(.eh_frame))
} > REGION_DATA AT > REGION_RODATA
.gcc_except_table : ONLY_IF_RW {
*(.gcc_except_table .gcc_except_table.*)
__edata = .;
__data_end__ = .;
} > REGION_DATA AT > REGION_RODATA
.bss : {
. = ALIGN(0x4) ;
__sbss = ALIGN(0x4) ;
__bss_start__ = . ;
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.scommon)
*(.dynbss)
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(0x4) ;
__ebss = . ;
__end = . ;
end = . ;
__bss_end__ = .;
} > REGION_BSS
/* End of uninitalized data segement */
PROVIDE(end = .);
}

158
bsp/thead-smart/rtconfig.h Normal file
View File

@ -0,0 +1,158 @@
#ifndef RT_CONFIG_H__
#define RT_CONFIG_H__
/* Automatically generated file; DO NOT EDIT. */
/* RT-Thread Configuration */
/* RT-Thread Kernel */
#define RT_NAME_MAX 8
#define RT_ALIGN_SIZE 4
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 1000
#define RT_USING_OVERFLOW_CHECK
#define RT_USING_HOOK
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 512
/* Inter-Thread communication */
#define RT_USING_SEMAPHORE
#define RT_USING_MUTEX
#define RT_USING_EVENT
#define RT_USING_MAILBOX
#define RT_USING_MESSAGEQUEUE
/* Memory Management */
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_HEAP
/* Kernel Device Object */
#define RT_USING_DEVICE
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uart1"
#define RT_VER_NUM 0x40003
/* RT-Thread CPU arch and features */
/* risc-v arch */
#define ARCH_RISCV
#define ARCH_RISCV_32
#define ARCH_RISCV_FPU
#define ARCH_RISCV_FPU_S
/* RT-Thread Components */
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 2048
#define RT_MAIN_THREAD_PRIORITY 10
/* C++ features */
/* Command shell */
#define RT_USING_FINSH
#define FINSH_THREAD_NAME "tshell"
#define FINSH_USING_HISTORY
#define FINSH_HISTORY_LINES 1
#define FINSH_USING_SYMTAB
#define FINSH_USING_DESCRIPTION
#define FINSH_THREAD_PRIORITY 20
#define FINSH_THREAD_STACK_SIZE 2048
#define FINSH_CMD_SIZE 80
#define FINSH_USING_MSH
#define FINSH_USING_MSH_DEFAULT
#define FINSH_USING_MSH_ONLY
#define FINSH_ARG_MAX 10
/* Device virtual file system */
/* Device Drivers */
#define RT_USING_DEVICE_IPC
#define RT_PIPE_BUFSZ 512
#define RT_USING_SERIAL
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_PIN
/* Using USB */
/* POSIX layer and C standard library */
/* Network */
/* Socket abstraction layer */
/* Network interface device */
/* light weight TCP/IP stack */
/* AT commands */
/* VBUS(Virtual Software BUS) */
/* Utilities */
/* RT-Thread online packages */
/* IoT - internet of things */
/* Wi-Fi */
/* Marvell WiFi */
/* Wiced WiFi */
/* IoT Cloud */
/* security packages */
/* language packages */
/* multimedia packages */
/* tools packages */
/* system packages */
/* peripheral libraries and drivers */
/* miscellaneous packages */
/* samples: kernel and components samples */
#define SOC_THEAD_SMART
#define RT_USING_UART1
#endif

View File

@ -0,0 +1,68 @@
import os
# toolchains options
ARCH ='risc-v'
CPU ='e906'
CPUNAME ='e906f'
VENDOR ='t-head'
CROSS_TOOL ='gcc'
if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = r'/home/xinge/tools/riscv64-elf-x86_64-20200616-1.9.6/bin'
else:
print 'Please make sure your toolchains is GNU GCC!'
exit(0)
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
# BUILD = 'debug'
BUILD = 'release'
if PLATFORM == 'gcc':
# toolchains
PREFIX = 'riscv64-unknown-elf-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'g++'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
STRIP = PREFIX + 'strip'
if CPUNAME == 'e906fd':
DEVICE = ' -march=rv32imafdcxthead -mabi=ilp32d'
if CPUNAME == 'e906f':
DEVICE = ' -march=rv32imafcxthead -mabi=ilp32f'
if CPUNAME == 'e906':
DEVICE = ' -march=rv32imacxthead -mabi=ilp32'
CFLAGS = DEVICE + ' -c -g -ffunction-sections -fdata-sections -Wall -mcmodel=medlow'
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -nostartfiles -Wl,--no-whole-archive -T gcc_csky.ld -lm -lc -lgcc -Wl,-gc-sections -Wl,-zmax-page-size=1024'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -gdwarf-2'
AFLAGS += ' -gdwarf-2'
else:
CFLAGS += ' -O2 -g2'
CXXFLAGS = CFLAGS
# M_CFLAGS = DEVICE + ' -EL -G0 -O2 -mno-abicalls -fno-common -fno-exceptions -fno-omit-frame-pointer -mlong-calls -fno-pic '
# M_CXXFLAGS = M_CFLAGS
# M_LFLAGS = DEVICE + ' -EL -r -Wl,--gc-sections,-z,max-page-size=0x4' +\
# ' -nostartfiles -static-libgcc'
# M_POST_ACTION = STRIP + ' -R .hash $TARGET\n' + SIZE + ' $TARGET \n'
DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n'
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'

View File

@ -10,10 +10,17 @@ group = []
list = os.listdir(cwd)
# add common code files
if rtconfig.CPU != "nuclei":
group = group + SConscript(os.path.join('common', 'SConscript'))
if rtconfig.VENDOR == "t-head" :
group = group
elif rtconfig.CPU == "nuclei" :
group = group
else :
group = group + SConscript(os.path.join(cwd, 'common', 'SConscript'))
# cpu porting code files
group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript'))
if rtconfig.VENDOR == "t-head" :
group = group + SConscript(os.path.join(cwd, rtconfig.VENDOR, rtconfig.CPU, 'SConscript'))
else :
group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript'))
Return('group')

View File

@ -0,0 +1,12 @@
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
ASFLAGS = ''
group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
Return('group')

View File

@ -0,0 +1,323 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020/08/20 zx.chen The T-HEAD RISC-V CPU E906 porting implementation
*/
#include "cpuport.h"
#ifdef RT_USING_SMP
#define rt_hw_interrupt_disable rt_hw_local_irq_disable
#define rt_hw_interrupt_enable rt_hw_local_irq_enable
#endif
/*
* Functions: vPortYield
*/
.global vPortYield
.type vPortYield, %function
vPortYield:
li t0, 0xE080100C
lb t1, (t0)
li t2, 0x01
or t1, t1, t2
sb t1, (t0)
ret
/*
* #ifdef RT_USING_SMP
* void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread);
* #else
* void rt_hw_context_switch_to(rt_ubase_t to);
* #endif
* a0 --> to
* a1 --> to_thread
*/
.globl rt_hw_context_switch_to
rt_hw_context_switch_to:
/* save a0 to to_thread */
la t0, rt_interrupt_to_thread
STORE a0, (t0)
/* save 0 to from_thread */
la t0, rt_interrupt_from_thread
li t1, 0
STORE t1, (t0)
/* set rt_thread_switch_interrupt_flag=1 */
la t0, rt_thread_switch_interrupt_flag
li t1, 1
STORE t1, (t0)
/* enable mexstatus SPUSHEN and SPSWAPEN */
#if ((CONFIG_CPU_E906==1) || (CONFIG_CPU_E906F==1) || (CONFIG_CPU_E906FD==1))
uint32_t mexstatus;
mexstatus = __get_MEXSTATUS();
mexstatus |= (0x2 << 16);
__set_MEXSTATUS(mexstatus);
#endif
csrw mscratch, sp
/* set software interrupt */
li t0, 0xE080100C
lb t1, (t0)
li t2, 0x01
or t1, t1, t2
sb t1, (t0)
/* enable global interrup */
csrsi mstatus, 8
ret
/*
* #ifdef RT_USING_SMP
* void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
* #else
* void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
* #endif
*
* a0 --> from
* a1 --> to
* a2 --> to_thread
*/
.globl rt_hw_context_switch
rt_hw_context_switch:
.globl rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
/* check rt_thread_switch_interrupt_flag */
la t0, rt_thread_switch_interrupt_flag
lw t1, (t0)
li t2, 1
beq t1, t2, .reswitch
/* set rt_thread_switch_interrupt_flag=1 */
STORE t2, (t0)
/* update from_thread */
la t0, rt_interrupt_from_thread
STORE a0, (t0)
.reswitch:
/* update to_thread */
la t0, rt_interrupt_to_thread
STORE a1, (t0)
/* set software interrupt */
li t0, 0xE080100C
lb t1, (t0)
li t2, 0x01
or t1, t1, t2
sb t1, (t0)
ret
/*
* PendSV_Handler
*/
.global PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
/* check rt_thread_switch_interrupt_flag */
sw t0, (-4)(sp)
sw t1, (-8)(sp)
la t0, rt_thread_switch_interrupt_flag
lw t1, (t0)
beqz t1, .pendsv_exit
/* clear rt_thread_switch_interrupt_flag */
li t1, 0x0
sw t1, (t0)
/* check rt_interrupt_from_thread */
la t0, rt_interrupt_from_thread
lw t1, (t0)
beqz t1, .switch_to_thead
/* save from thread context */
lw t0, (-4)(sp)
lw t1, (-8)(sp)
#ifdef ARCH_RISCV_FPU
addi sp, sp, -32 * FREGBYTES
FSTORE f0, 0 * FREGBYTES(sp)
FSTORE f1, 1 * FREGBYTES(sp)
FSTORE f2, 2 * FREGBYTES(sp)
FSTORE f3, 3 * FREGBYTES(sp)
FSTORE f4, 4 * FREGBYTES(sp)
FSTORE f5, 5 * FREGBYTES(sp)
FSTORE f6, 6 * FREGBYTES(sp)
FSTORE f7, 7 * FREGBYTES(sp)
FSTORE f8, 8 * FREGBYTES(sp)
FSTORE f9, 9 * FREGBYTES(sp)
FSTORE f10, 10 * FREGBYTES(sp)
FSTORE f11, 11 * FREGBYTES(sp)
FSTORE f12, 12 * FREGBYTES(sp)
FSTORE f13, 13 * FREGBYTES(sp)
FSTORE f14, 14 * FREGBYTES(sp)
FSTORE f15, 15 * FREGBYTES(sp)
FSTORE f16, 16 * FREGBYTES(sp)
FSTORE f17, 17 * FREGBYTES(sp)
FSTORE f18, 18 * FREGBYTES(sp)
FSTORE f19, 19 * FREGBYTES(sp)
FSTORE f20, 20 * FREGBYTES(sp)
FSTORE f21, 21 * FREGBYTES(sp)
FSTORE f22, 22 * FREGBYTES(sp)
FSTORE f23, 23 * FREGBYTES(sp)
FSTORE f24, 24 * FREGBYTES(sp)
FSTORE f25, 25 * FREGBYTES(sp)
FSTORE f26, 26 * FREGBYTES(sp)
FSTORE f27, 27 * FREGBYTES(sp)
FSTORE f28, 28 * FREGBYTES(sp)
FSTORE f29, 29 * FREGBYTES(sp)
FSTORE f30, 30 * FREGBYTES(sp)
FSTORE f31, 31 * FREGBYTES(sp)
#endif
addi sp, sp, -32 * REGBYTES
STORE x1, 1 * REGBYTES(sp)
csrr x1, mepc
STORE x1, 0 * REGBYTES(sp)
csrr x1, mstatus
andi x1, x1, 8
beqz x1, .save_mpie
li x1, 0x80
.save_mpie:
STORE x1, 2 * REGBYTES(sp)
/* x3 don't need save */
STORE x4, 4 * REGBYTES(sp)
STORE x5, 5 * REGBYTES(sp)
STORE x6, 6 * REGBYTES(sp)
STORE x7, 7 * REGBYTES(sp)
STORE x8, 8 * REGBYTES(sp)
STORE x9, 9 * REGBYTES(sp)
STORE x10, 10 * REGBYTES(sp)
STORE x11, 11 * REGBYTES(sp)
STORE x12, 12 * REGBYTES(sp)
STORE x13, 13 * REGBYTES(sp)
STORE x14, 14 * REGBYTES(sp)
STORE x15, 15 * REGBYTES(sp)
STORE x16, 16 * REGBYTES(sp)
STORE x17, 17 * REGBYTES(sp)
STORE x18, 18 * REGBYTES(sp)
STORE x19, 19 * REGBYTES(sp)
STORE x20, 20 * REGBYTES(sp)
STORE x21, 21 * REGBYTES(sp)
STORE x22, 22 * REGBYTES(sp)
STORE x23, 23 * REGBYTES(sp)
STORE x24, 24 * REGBYTES(sp)
STORE x25, 25 * REGBYTES(sp)
STORE x26, 26 * REGBYTES(sp)
STORE x27, 27 * REGBYTES(sp)
STORE x28, 28 * REGBYTES(sp)
STORE x29, 29 * REGBYTES(sp)
STORE x30, 30 * REGBYTES(sp)
STORE x31, 31 * REGBYTES(sp)
/* store from_thread sp */
la t0, rt_interrupt_from_thread
lw t0, (t0)
sw sp, (t0)
.switch_to_thead:
/* restore to thread context
* sp(0) -> epc;
* sp(1) -> ra;
* sp(i) -> x(i+2)
*/
la t0, rt_interrupt_to_thread
lw t0, (t0)
LOAD sp, (t0)
/* restore ra to mepc */
LOAD a1, 0 * REGBYTES(sp)
csrw mepc, a1
LOAD x1, 1 * REGBYTES(sp)
/* force to machin mode(MPP=11) */
li a1, 0x1880
csrs mstatus, a1
LOAD a1, 2 * REGBYTES(sp)
csrs mstatus, a1
/* x3 don't need restore */
LOAD x4, 4 * REGBYTES(sp)
LOAD x5, 5 * REGBYTES(sp)
LOAD x6, 6 * REGBYTES(sp)
LOAD x7, 7 * REGBYTES(sp)
LOAD x8, 8 * REGBYTES(sp)
LOAD x9, 9 * REGBYTES(sp)
LOAD x10, 10 * REGBYTES(sp)
LOAD x11, 11 * REGBYTES(sp)
LOAD x12, 12 * REGBYTES(sp)
LOAD x13, 13 * REGBYTES(sp)
LOAD x14, 14 * REGBYTES(sp)
LOAD x15, 15 * REGBYTES(sp)
LOAD x16, 16 * REGBYTES(sp)
LOAD x17, 17 * REGBYTES(sp)
LOAD x18, 18 * REGBYTES(sp)
LOAD x19, 19 * REGBYTES(sp)
LOAD x20, 20 * REGBYTES(sp)
LOAD x21, 21 * REGBYTES(sp)
LOAD x22, 22 * REGBYTES(sp)
LOAD x23, 23 * REGBYTES(sp)
LOAD x24, 24 * REGBYTES(sp)
LOAD x25, 25 * REGBYTES(sp)
LOAD x26, 26 * REGBYTES(sp)
LOAD x27, 27 * REGBYTES(sp)
LOAD x28, 28 * REGBYTES(sp)
LOAD x29, 29 * REGBYTES(sp)
LOAD x30, 30 * REGBYTES(sp)
LOAD x31, 31 * REGBYTES(sp)
addi sp, sp, 32 * REGBYTES
#ifdef ARCH_RISCV_FPU
FLOAD f0, 0 * FREGBYTES(sp)
FLOAD f1, 1 * FREGBYTES(sp)
FLOAD f2, 2 * FREGBYTES(sp)
FLOAD f3, 3 * FREGBYTES(sp)
FLOAD f4, 4 * FREGBYTES(sp)
FLOAD f5, 5 * FREGBYTES(sp)
FLOAD f6, 6 * FREGBYTES(sp)
FLOAD f7, 7 * FREGBYTES(sp)
FLOAD f8, 8 * FREGBYTES(sp)
FLOAD f9, 9 * FREGBYTES(sp)
FLOAD f10, 10 * FREGBYTES(sp)
FLOAD f11, 11 * FREGBYTES(sp)
FLOAD f12, 12 * FREGBYTES(sp)
FLOAD f13, 13 * FREGBYTES(sp)
FLOAD f14, 14 * FREGBYTES(sp)
FLOAD f15, 15 * FREGBYTES(sp)
FLOAD f16, 16 * FREGBYTES(sp)
FLOAD f17, 17 * FREGBYTES(sp)
FLOAD f18, 18 * FREGBYTES(sp)
FLOAD f19, 19 * FREGBYTES(sp)
FLOAD f20, 20 * FREGBYTES(sp)
FLOAD f21, 21 * FREGBYTES(sp)
FLOAD f22, 22 * FREGBYTES(sp)
FLOAD f23, 23 * FREGBYTES(sp)
FLOAD f24, 24 * FREGBYTES(sp)
FLOAD f25, 25 * FREGBYTES(sp)
FLOAD f26, 26 * FREGBYTES(sp)
FLOAD f27, 27 * FREGBYTES(sp)
FLOAD f28, 28 * FREGBYTES(sp)
FLOAD f29, 29 * FREGBYTES(sp)
FLOAD f30, 30 * FREGBYTES(sp)
FLOAD f31, 31 * FREGBYTES(sp)
addi sp, sp, 32 * FREGBYTES
#endif
.pendsv_exit:
mret

View File

@ -0,0 +1,170 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020/08/20 zx.chen The T-HEAD RISC-V CPU E906 porting code.
*/
#include <rthw.h>
#include <rtthread.h>
#include "cpuport.h"
#ifndef RT_USING_SMP
volatile rt_ubase_t rt_interrupt_from_thread = 0;
volatile rt_ubase_t rt_interrupt_to_thread = 0;
volatile rt_uint32_t rt_thread_switch_interrupt_flag = 0;
#endif
struct rt_hw_stack_frame
{
rt_ubase_t epc; /* epc - epc - program counter */
rt_ubase_t ra; /* x1 - ra - return address for jumps */
rt_ubase_t mstatus; /* - machine status register */
rt_ubase_t gp; /* x3 - gp - global pointer */
rt_ubase_t tp; /* x4 - tp - thread pointer */
rt_ubase_t t0; /* x5 - t0 - temporary register 0 */
rt_ubase_t t1; /* x6 - t1 - temporary register 1 */
rt_ubase_t t2; /* x7 - t2 - temporary register 2 */
rt_ubase_t s0_fp; /* x8 - s0/fp - saved register 0 or frame pointer */
rt_ubase_t s1; /* x9 - s1 - saved register 1 */
rt_ubase_t a0; /* x10 - a0 - return value or function argument 0 */
rt_ubase_t a1; /* x11 - a1 - return value or function argument 1 */
rt_ubase_t a2; /* x12 - a2 - function argument 2 */
rt_ubase_t a3; /* x13 - a3 - function argument 3 */
rt_ubase_t a4; /* x14 - a4 - function argument 4 */
rt_ubase_t a5; /* x15 - a5 - function argument 5 */
rt_ubase_t a6; /* x16 - a6 - function argument 6 */
rt_ubase_t a7; /* x17 - s7 - function argument 7 */
rt_ubase_t s2; /* x18 - s2 - saved register 2 */
rt_ubase_t s3; /* x19 - s3 - saved register 3 */
rt_ubase_t s4; /* x20 - s4 - saved register 4 */
rt_ubase_t s5; /* x21 - s5 - saved register 5 */
rt_ubase_t s6; /* x22 - s6 - saved register 6 */
rt_ubase_t s7; /* x23 - s7 - saved register 7 */
rt_ubase_t s8; /* x24 - s8 - saved register 8 */
rt_ubase_t s9; /* x25 - s9 - saved register 9 */
rt_ubase_t s10; /* x26 - s10 - saved register 10 */
rt_ubase_t s11; /* x27 - s11 - saved register 11 */
rt_ubase_t t3; /* x28 - t3 - temporary register 3 */
rt_ubase_t t4; /* x29 - t4 - temporary register 4 */
rt_ubase_t t5; /* x30 - t5 - temporary register 5 */
rt_ubase_t t6; /* x31 - t6 - temporary register 6 */
#ifdef ARCH_RISCV_FPU
rv_floatreg_t f0; /* f0 */
rv_floatreg_t f1; /* f1 */
rv_floatreg_t f2; /* f2 */
rv_floatreg_t f3; /* f3 */
rv_floatreg_t f4; /* f4 */
rv_floatreg_t f5; /* f5 */
rv_floatreg_t f6; /* f6 */
rv_floatreg_t f7; /* f7 */
rv_floatreg_t f8; /* f8 */
rv_floatreg_t f9; /* f9 */
rv_floatreg_t f10; /* f10 */
rv_floatreg_t f11; /* f11 */
rv_floatreg_t f12; /* f12 */
rv_floatreg_t f13; /* f13 */
rv_floatreg_t f14; /* f14 */
rv_floatreg_t f15; /* f15 */
rv_floatreg_t f16; /* f16 */
rv_floatreg_t f17; /* f17 */
rv_floatreg_t f18; /* f18 */
rv_floatreg_t f19; /* f19 */
rv_floatreg_t f20; /* f20 */
rv_floatreg_t f21; /* f21 */
rv_floatreg_t f22; /* f22 */
rv_floatreg_t f23; /* f23 */
rv_floatreg_t f24; /* f24 */
rv_floatreg_t f25; /* f25 */
rv_floatreg_t f26; /* f26 */
rv_floatreg_t f27; /* f27 */
rv_floatreg_t f28; /* f28 */
rv_floatreg_t f29; /* f29 */
rv_floatreg_t f30; /* f30 */
rv_floatreg_t f31; /* f31 */
#endif
};
/**
* This function will initialize thread stack
*
* @param tentry the entry of thread
* @param parameter the parameter of entry
* @param stack_addr the beginning stack address
* @param texit the function will be called when thread exit
*
* @return stack address
*/
rt_uint8_t *rt_hw_stack_init(void *tentry,
void *parameter,
rt_uint8_t *stack_addr,
void *texit)
{
struct rt_hw_stack_frame *frame;
rt_uint8_t *stk;
int i;
stk = stack_addr + sizeof(rt_ubase_t);
stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_ubase_t)stk, REGBYTES);
stk -= sizeof(struct rt_hw_stack_frame);
frame = (struct rt_hw_stack_frame *)stk;
for (i = 0; i < sizeof(struct rt_hw_stack_frame) / sizeof(rt_ubase_t); i++)
{
((rt_ubase_t *)frame)[i] = 0xdeadbeef;
}
frame->ra = (rt_ubase_t)texit;
frame->a0 = (rt_ubase_t)parameter;
frame->epc = (rt_ubase_t)tentry;
/* force to machine mode(MPP=11) and set MPIE to 1 */
frame->mstatus = 0x00007880;
return stk;
}
/**
* This function will disable global interrupt
*
* @param none
*
* @return zero
*/
rt_base_t rt_hw_interrupt_disable(void)
{
__asm volatile("csrc mstatus, 8");
return 0;
}
/**
* This function will ennable global interrupt
*
* @param level not used
*
* @return none
*/
void rt_hw_interrupt_enable(rt_base_t level)
{
__asm volatile("csrs mstatus, 8");
}
/** shutdown CPU */
void rt_hw_cpu_shutdown()
{
rt_uint32_t level;
rt_kprintf("shutdown...\n");
level = rt_hw_interrupt_disable();
while (level)
{
RT_ASSERT(0);
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-20 zx.chen The first version
*/
#ifndef CPUPORT_H__
#define CPUPORT_H__
#include <rtconfig.h>
/* bytes of register width */
#ifdef ARCH_RISCV_64
#define DFSTORE fsd
#define DFLOAD fld
#define SFSTORE fsw
#define SFLOAD flw
#define STORE sd
#define LOAD ld
#define REGBYTES 8
#define SFREGBYTES 4
#define DFREGBYTES 8
#else
#define DFSTORE fsd
#define DFLOAD fld
#define SFSTORE fsw
#define SFLOAD flw
#define STORE sw
#define LOAD lw
#define REGBYTES 4
#define SFREGBYTES 4
#define DFREGBYTES 8
#endif
#ifdef ARCH_RISCV_FPU
#ifdef ARCH_RISCV_FPU_D
#define FSTORE fsd
#define FLOAD fld
#define FREGBYTES 8
#define rv_floatreg_t rt_int64_t
#endif
#ifdef ARCH_RISCV_FPU_S
#define FSTORE fsw
#define FLOAD flw
#define FREGBYTES 4
#define rv_floatreg_t rt_int32_t
#endif
#endif
#endif