summaryrefslogtreecommitdiff
path: root/bsp/ck802
diff options
context:
space:
mode:
authorliang yongxiang <[email protected]>2018-06-05 14:36:29 +0800
committerliang yongxiang <[email protected]>2018-06-11 09:45:07 +0800
commitb085393cde20f073121446543b79fe2da949740c (patch)
treeb1af2f7677bb1dc2aafe934409f364ac89c6b6c5 /bsp/ck802
parent4e937887f6cfe67275d87a7b9d102520bcc1a9b0 (diff)
[bsp] add ck802 bsp
Diffstat (limited to 'bsp/ck802')
-rw-r--r--bsp/ck802/.config275
-rw-r--r--bsp/ck802/Kconfig30
-rw-r--r--bsp/ck802/README.md84
-rw-r--r--bsp/ck802/SConscript14
-rw-r--r--bsp/ck802/SConstruct35
-rw-r--r--bsp/ck802/applications/SConscript13
-rw-r--r--bsp/ck802/applications/main.c33
-rw-r--r--bsp/ck802/drivers/SConscript14
-rw-r--r--bsp/ck802/drivers/board.c60
-rw-r--r--bsp/ck802/drivers/board.h32
-rw-r--r--bsp/ck802/drivers/board_coretimer.c81
-rw-r--r--bsp/ck802/drivers/board_coretimer.h52
-rw-r--r--bsp/ck802/drivers/board_uart.c273
-rw-r--r--bsp/ck802/drivers/config.h44
-rw-r--r--bsp/ck802/drivers/isr.c174
-rw-r--r--bsp/ck802/drivers/pin_name.h88
-rw-r--r--bsp/ck802/drivers/pinmux.c158
-rw-r--r--bsp/ck802/drivers/pinmux.h220
-rw-r--r--bsp/ck802/drivers/soc.h318
-rw-r--r--bsp/ck802/drivers/system.c64
-rw-r--r--bsp/ck802/gcc_csky.ld226
-rw-r--r--bsp/ck802/libraries/SConscript48
-rw-r--r--bsp/ck802/libraries/common/aes/ck_aes.c499
-rw-r--r--bsp/ck802/libraries/common/aes/ck_aes.h54
-rw-r--r--bsp/ck802/libraries/common/crc/ck_crc.c277
-rw-r--r--bsp/ck802/libraries/common/crc/ck_crc.h34
-rw-r--r--bsp/ck802/libraries/common/dmac/ck_dmac.c517
-rw-r--r--bsp/ck802/libraries/common/dmac/ck_dmac.h75
-rw-r--r--bsp/ck802/libraries/common/eflash/ck_eflash.c288
-rw-r--r--bsp/ck802/libraries/common/eflash/ck_eflash.h38
-rw-r--r--bsp/ck802/libraries/common/eth/ethernet_enc28j60.c1259
-rw-r--r--bsp/ck802/libraries/common/eth/ethernet_enc28j60.h427
-rw-r--r--bsp/ck802/libraries/common/gpio/dw_gpio.c528
-rw-r--r--bsp/ck802/libraries/common/gpio/dw_gpio.h54
-rw-r--r--bsp/ck802/libraries/common/iic/dw_iic.c646
-rw-r--r--bsp/ck802/libraries/common/iic/dw_iic.h123
-rw-r--r--bsp/ck802/libraries/common/pwm/ck_pwm.c315
-rw-r--r--bsp/ck802/libraries/common/pwm/ck_pwm.h101
-rw-r--r--bsp/ck802/libraries/common/rsa/ck_rsa.c1256
-rw-r--r--bsp/ck802/libraries/common/rsa/ck_rsa.h86
-rw-r--r--bsp/ck802/libraries/common/rtc/ck_rtc.c703
-rw-r--r--bsp/ck802/libraries/common/rtc/ck_rtc.h44
-rw-r--r--bsp/ck802/libraries/common/sha/ck_sha.c538
-rw-r--r--bsp/ck802/libraries/common/sha/ck_sha.h63
-rw-r--r--bsp/ck802/libraries/common/spi/dw_spi.c1237
-rw-r--r--bsp/ck802/libraries/common/spi/dw_spi.h159
-rw-r--r--bsp/ck802/libraries/common/timer/dw_timer.c330
-rw-r--r--bsp/ck802/libraries/common/timer/dw_timer.h49
-rw-r--r--bsp/ck802/libraries/common/trng/ck_trng.c237
-rw-r--r--bsp/ck802/libraries/common/trng/ck_trng.h40
-rw-r--r--bsp/ck802/libraries/common/usart/dw_usart.c768
-rw-r--r--bsp/ck802/libraries/common/usart/dw_usart.h110
-rw-r--r--bsp/ck802/libraries/common/wdt/dw_wdt.c267
-rw-r--r--bsp/ck802/libraries/common/wdt/dw_wdt.h44
-rw-r--r--bsp/ck802/libraries/include/drv_aes.h189
-rw-r--r--bsp/ck802/libraries/include/drv_common.h47
-rw-r--r--bsp/ck802/libraries/include/drv_crc.h150
-rw-r--r--bsp/ck802/libraries/include/drv_dmac.h171
-rw-r--r--bsp/ck802/libraries/include/drv_eflash.h157
-rw-r--r--bsp/ck802/libraries/include/drv_errno.h116
-rw-r--r--bsp/ck802/libraries/include/drv_eth.h105
-rw-r--r--bsp/ck802/libraries/include/drv_eth_mac.h367
-rw-r--r--bsp/ck802/libraries/include/drv_eth_phy.h124
-rw-r--r--bsp/ck802/libraries/include/drv_gpio.h183
-rw-r--r--bsp/ck802/libraries/include/drv_iic.h195
-rw-r--r--bsp/ck802/libraries/include/drv_pwm.h94
-rw-r--r--bsp/ck802/libraries/include/drv_rsa.h222
-rw-r--r--bsp/ck802/libraries/include/drv_rtc.h161
-rw-r--r--bsp/ck802/libraries/include/drv_sha.h172
-rw-r--r--bsp/ck802/libraries/include/drv_spi.h240
-rw-r--r--bsp/ck802/libraries/include/drv_timer.h160
-rw-r--r--bsp/ck802/libraries/include/drv_trng.h118
-rw-r--r--bsp/ck802/libraries/include/drv_usart.h282
-rw-r--r--bsp/ck802/libraries/include/drv_wdt.h119
-rw-r--r--bsp/ck802/libraries/startup_gcc.S244
-rw-r--r--bsp/ck802/project.cdkproj252
-rw-r--r--bsp/ck802/rtconfig.h145
-rw-r--r--bsp/ck802/rtconfig.py63
-rw-r--r--bsp/ck802/template.cdkproj176
79 files changed, 17754 insertions, 0 deletions
diff --git a/bsp/ck802/.config b/bsp/ck802/.config
new file mode 100644
index 0000000000..4284658f94
--- /dev/null
+++ b/bsp/ck802/.config
@@ -0,0 +1,275 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=8
+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_DEBUG=y
+CONFIG_RT_USING_OVERFLOW_CHECK=y
+CONFIG_RT_DEBUG_INIT=0
+CONFIG_RT_DEBUG_THREAD=0
+CONFIG_RT_USING_HOOK=y
+CONFIG_IDLE_THREAD_STACK_SIZE=256
+# CONFIG_RT_USING_TIMER_SOFT 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_INTERRUPT_INFO is not set
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
+# CONFIG_RT_USING_MODULE 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
+
+#
+# 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=512
+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
+# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_3 is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_USING_SERIAL=y
+# 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_PWM is not set
+# CONFIG_RT_USING_MTD_NOR is not set
+# CONFIG_RT_USING_MTD_NAND 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_WIFI is not set
+# CONFIG_RT_USING_AUDIO 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
+
+#
+# Network stack
+#
+
+#
+# light weight TCP/IP stack
+#
+# CONFIG_RT_USING_LWIP is not set
+
+#
+# Modbus master and slave stack
+#
+# CONFIG_RT_USING_MODBUS is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_LOGTRACE is not set
+# CONFIG_RT_USING_RYM is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_MONGOOSE 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_LJSON is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_NANOPB is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD 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_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+# CONFIG_PKG_USING_NETUTILS is not set
+# CONFIG_PKG_USING_ONENET 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
+
+#
+# language packages
+#
+# 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
+
+#
+# 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
+
+#
+# system packages
+#
+
+#
+# RT-Thread GUI Engine
+#
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_FAL is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+
+#
+# peripheral libraries and drivers
+#
+# CONFIG_PKG_USING_STM32F4_HAL is not set
+# CONFIG_PKG_USING_STM32F4_DRIVERS is not set
+
+#
+# miscellaneous packages
+#
+# 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_CANFESTIVAL is not set
+# CONFIG_PKG_USING_ZLIB is not set
+# CONFIG_PKG_USING_DSTR is not set
+
+#
+# sample package
+#
+# CONFIG_PKG_USING_SAMPLES is not set
+
+#
+# example package: hello
+#
+# CONFIG_PKG_USING_HELLO is not set
+
+#
+# Privated Packages of RealThread
+#
+# CONFIG_PKG_USING_CODEC is not set
+# CONFIG_PKG_USING_PLAYER is not set
+# CONFIG_PKG_USING_PERSIMMON_SRC is not set
+
+#
+# Network Utilities
+#
+# CONFIG_PKG_USING_WLAN_WICED_SRC is not set
+# CONFIG_PKG_USING_CLOUDSDK is not set
+# CONFIG_PKG_USING_COREMARK is not set
+# CONFIG_PKG_USING_POWER_MANAGER is not set
+# CONFIG_PKG_USING_RT_OTA is not set
+# CONFIG_PKG_USING_RT_AT is not set
+# CONFIG_PKG_USING_RDB is not set
+# CONFIG_PKG_USING_RTINSIGHT is not set
+CONFIG_RT_USING_UART1=y
diff --git a/bsp/ck802/Kconfig b/bsp/ck802/Kconfig
new file mode 100644
index 0000000000..7bce24ab3f
--- /dev/null
+++ b/bsp/ck802/Kconfig
@@ -0,0 +1,30 @@
+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"
+
+if RT_USING_SERIAL
+
+ config RT_USING_UART1
+ bool "Using uart1"
+ default y
+
+endif
diff --git a/bsp/ck802/README.md b/bsp/ck802/README.md
new file mode 100644
index 0000000000..c8e20dbeff
--- /dev/null
+++ b/bsp/ck802/README.md
@@ -0,0 +1,84 @@
+CK802
+
+## 简介
+
+CK802是杭州中天微系统有限公司自主开发的极低功耗、极低成本嵌入式CPU核产品,它以8位CPU的成本获得32位CPU的运行效率与性能。 BSP基于中天微提供的一块FPGA开发板完成。
+
+| 介绍 | 描述 |
+| ---- | ---- |
+| 主CPU平台 | CK802 |
+| 最高频率 | 600MHz |
+| SRAM | 128K |
+| FLASH | 256K |
+
+## 编译说明
+
+CK802板级包支持CDK集成开发环境和Scons编译。使用的编译器是csky-abiv2-elf-toolchain。
+
+| IDE/编译器 | 已测试版本 |
+| ---------- | --------- |
+| CDK | CDK 1.6.0 |
+| GCC | (C-SKY Tools V2.10.00(Minilibc), ABIV2, B20161206) 4.5.1 |
+
+使用scons编译,需要指定环境变量RTT_EXEC_PATH为正确的编译器路径,例如:
+
+Windows:
+
+```shell
+RTT_EXEC_PATH=r'D:\c-sky\CSKY\MinGW\csky-abiv2-elf-toolchain\bin'
+```
+
+Linux:
+
+```shell
+RTT_EXEC_PATH=r'/opt/csky-abiv2-elf-tools-x86_64-minilibc-20161211/bin'
+```
+
+
+
+## BSP使用
+
+### CDK
+#### 编译仿真
+打开project.cdkproj工程,点击菜单栏的`Project->Build Active Project`进行编译,编译完成后点击`Debug->Start/Stop Debugger`,就可以进入仿真。点击`Debug->Continue Debugger`全速运行。
+#### 更新工程
+在需要添加或者删除组件的时候,可以使用`menuconfig`进行配置。配置完成后输入`scons --target=cdk`更新工程
+### Scons
+
+#### 编译
+
+配置好环境变量`RTT_EXEC_PATH`后,使用[env工具][https://www.rt-thread.org/page/download.html],可以在console下进入到bsp目录中,运行以下命令就可以编译该BSP:
+```
+scons
+```
+
+#### 仿真
+
+Windows平台打开CSkyDebugServer.exe,该软件会连接到仿真器并且提供一个gdb server。使用DebugServerConsole.exe在命令行下进行调试。
+
+Linux平台使用CSkyDebugServer.elf来连接仿真器,使用DebugServerConsole.exe在命令行下进行调试。
+
+### 运行结果
+
+如果编译 & 烧写无误,当复位设备后,会在串口上看到RT-Thread的启动logo信息:
+
+```
+\ | /
+- RT - Thread Operating System
+ / | \ 3.0.4 build Jun 5 2018
+ 2006 - 2018 Copyright by rt-thread team
+msh >
+```
+
+## 4. 驱动支持情况及计划
+
+| 驱动 | 支持情况 | 备注 |
+| ------ | ---- | ------ |
+| UART | 支持 | UART 1 |
+
+
+## 5. 联系人信息
+
+维护人:
+
+- [tanek](https://github.com/TanekLiang) \ No newline at end of file
diff --git a/bsp/ck802/SConscript b/bsp/ck802/SConscript
new file mode 100644
index 0000000000..c7ef7659ec
--- /dev/null
+++ b/bsp/ck802/SConscript
@@ -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')
diff --git a/bsp/ck802/SConstruct b/bsp/ck802/SConstruct
new file mode 100644
index 0000000000..1a9f0b7616
--- /dev/null
+++ b/bsp/ck802/SConstruct
@@ -0,0 +1,35 @@
+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() + '/../..')
+
+print RTT_ROOT
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+TARGET = 'rtthread-ck802.' + 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)
diff --git a/bsp/ck802/applications/SConscript b/bsp/ck802/applications/SConscript
new file mode 100644
index 0000000000..78698e4ad3
--- /dev/null
+++ b/bsp/ck802/applications/SConscript
@@ -0,0 +1,13 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd = os.path.join(str(Dir('#')), 'applications')
+src = Glob('*.c')
+CPPPATH = [cwd, str(Dir('#'))]
+
+CCFLAGS = ' -c -mistack -ffunction-sections'
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH, CCFLAGS=CCFLAGS)
+
+Return('group')
diff --git a/bsp/ck802/applications/main.c b/bsp/ck802/applications/main.c
new file mode 100644
index 0000000000..65d7985e43
--- /dev/null
+++ b/bsp/ck802/applications/main.c
@@ -0,0 +1,33 @@
+
+/*
+ * File : clock.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-10-10 Tanek first version
+ */
+
+#include <rtthread.h>
+
+int main(void)
+{
+ return 0;
+}
+
+/*@}*/
diff --git a/bsp/ck802/drivers/SConscript b/bsp/ck802/drivers/SConscript
new file mode 100644
index 0000000000..11acddcea6
--- /dev/null
+++ b/bsp/ck802/drivers/SConscript
@@ -0,0 +1,14 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd = os.path.join(str(Dir('#')), 'drivers')
+
+# add the general drivers.
+src = Glob("*.c") + Glob("*.cpp")
+
+CPPPATH = [cwd]
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/bsp/ck802/drivers/board.c b/bsp/ck802/drivers/board.c
new file mode 100644
index 0000000000..55f0e47331
--- /dev/null
+++ b/bsp/ck802/drivers/board.c
@@ -0,0 +1,60 @@
+/*
+ * File : board.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2018, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-08-10 Urey first implementation
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "board.h"
+#include "csi_core.h"
+#include "pinmux.h"
+
+extern int __bss_end__;
+#define SYS_HEAP_BEGIN (&__bss_end__)
+
+#include "core_ck802.h"
+
+/**
+ * This function will initial CK802 board.
+ */
+void rt_hw_board_init(void)
+{
+ phobos_ioreuse_initial();
+
+ /* NVIC Configuration */
+ drv_nvic_init(2);
+
+#ifdef RT_USING_COMPONENTS_INIT
+ rt_components_board_init();
+#endif
+
+#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 *)CK802_IRAM_END);
+#endif
+}
+
+/*@}*/
diff --git a/bsp/ck802/drivers/board.h b/bsp/ck802/drivers/board.h
new file mode 100644
index 0000000000..9c404a29c7
--- /dev/null
+++ b/bsp/ck802/drivers/board.h
@@ -0,0 +1,32 @@
+/*
+ * File : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2018, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-08-10 Urey first implementation
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#define APB_DEFAULT_FREQ 20000000 /* Hz */
+#define CK802_IRAM_SIZE 94
+#define CK802_IRAM_END (0x20000000 + CK802_IRAM_SIZE * 1024)
+
+#endif /* __BOARD_H__ */
diff --git a/bsp/ck802/drivers/board_coretimer.c b/bsp/ck802/drivers/board_coretimer.c
new file mode 100644
index 0000000000..d3275e68d8
--- /dev/null
+++ b/bsp/ck802/drivers/board_coretimer.c
@@ -0,0 +1,81 @@
+/*
+ * File : board_coretimer.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-01-01 Urey first version
+ */
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "board.h"
+#include "board_coretimer.h"
+
+#include <stdint.h>
+
+static inline unsigned int readreg32(volatile unsigned int *addr)
+{
+ return *(volatile unsigned int *)addr;
+}
+
+static inline void writereg32(unsigned int b, volatile unsigned int *addr)
+{
+ *(volatile unsigned int *)addr = b;
+}
+
+void CKTimerInit(uint32_t timer_id, uint32_t freq)
+{
+ uint32_t reg;
+
+ writereg32(APB_DEFAULT_FREQ / freq, CORET_RVR);
+ writereg32(0, CORET_CVR);
+
+ reg = readreg32(CORET_CSR);
+ reg |= CORETIM_TXCONTROL_ENABLE;
+ reg |= CORETIM_TXCONTROL_INTMASK;
+ writereg32(reg, CORET_CSR);
+
+ return;
+}
+
+void CKTimerClear(uint32_t timer_id)
+{
+ uint32_t reg;
+
+ reg = readreg32(CORET_CSR);
+ reg |= ~CORETIM_TXCONTROL_MODE;
+ writereg32(reg, CORET_CSR);
+}
+
+uint32_t CKTimer_CurrentValue(void)
+{
+ return readreg32(CORET_CVR);
+}
+
+void __attribute__((isr)) SysTick_Handler(void)
+{
+ CKTimerClear(0x1);
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ rt_tick_increase();
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
diff --git a/bsp/ck802/drivers/board_coretimer.h b/bsp/ck802/drivers/board_coretimer.h
new file mode 100644
index 0000000000..e911c8e838
--- /dev/null
+++ b/bsp/ck802/drivers/board_coretimer.h
@@ -0,0 +1,52 @@
+/*
+ * File : board_coretimer.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-01-01 Urey first version
+ */
+#ifndef _BOARD_CORETIMER_H_
+#define _BOARD_CORETIMER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define CK_TIMER_BASE (0xE000E000)
+
+#define CORET_CSR (volatile unsigned int *)(CK_TIMER_BASE + 0x10)
+#define CORET_RVR (volatile unsigned int *)(CK_TIMER_BASE + 0x14)
+#define CORET_CVR (volatile unsigned int *)(CK_TIMER_BASE + 0x18)
+#define CORET_CALIB (volatile unsigned int *)(CK_TIMER_BASE + 0x1c)
+
+/*
+ * define the bits for TxControl
+ */
+#define CORETIM_TXCONTROL_ENABLE (1UL << 0)
+#define CORETIM_TXCONTROL_INTMASK (1UL << 1)
+#define CORETIM_TXCONTROL_MODE (1UL << 16)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BOARD_CORETIMER_H_ */
diff --git a/bsp/ck802/drivers/board_uart.c b/bsp/ck802/drivers/board_uart.c
new file mode 100644
index 0000000000..5dd7018f56
--- /dev/null
+++ b/bsp/ck802/drivers/board_uart.c
@@ -0,0 +1,273 @@
+/*
+ * File : board_uart.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2018, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-09-23 Urey 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 "dw_usart.h"
+#include "drv_usart.h"
+#include "pin_name.h"
+#include "pinmux.h"
+
+#if CONFIG_USART
+struct
+{
+ uint32_t base;
+ uint32_t irq;
+} const sg_usart_config[CONFIG_USART_NUM] =
+{
+ { CSKY_UART0_BASE, UART0_IRQn },
+ { CSKY_UART1_BASE, UART1_IRQn },
+ { CSKY_UART2_BASE, UART2_IRQn },
+ { CSKY_UART3_BASE, UART3_IRQn }
+};
+
+typedef struct
+{
+ pin_t tx;
+ pin_t rx;
+ uint16_t cfg_idx; //idx of sg_usart_config[]
+ uint16_t function;
+} usart_pin_map_t;
+const static usart_pin_map_t s_usart_pin_map[] =
+{
+ {
+ PA0_TXD0_PWM0_XX_SIROUT0,
+ PA1_RXD0_PWM1_XX_SIRIN0,
+ 0,
+ 0
+ },
+ {
+ PA10_TXD1_PWM1_XX_SIROUT1,
+ PA11_RXD1_PWM2_XX_SIRIN1,
+ 1,
+ 0
+ },
+ {
+ PA23_TXD2_PWM5_XX_SIROUT2,
+ PA22_RXD2_PWM4_XX_SIRIN2,
+ 2,
+ 0
+ },
+ {
+ PA26_TXD3_PWMFAULT_XX_SIROUT3,
+ PA27_RXD3_PWM0_XX_SIRIN3,
+ 3,
+ 0
+ }
+};
+
+int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq)
+{
+ uint32_t idx;
+
+ for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++)
+ {
+ if (s_usart_pin_map[idx].tx == tx && s_usart_pin_map[idx].rx == rx)
+ {
+ *base = sg_usart_config[s_usart_pin_map[idx].cfg_idx].base;
+ *irq = sg_usart_config[s_usart_pin_map[idx].cfg_idx].irq;
+
+ /*pinmux*/
+ pin_mux(s_usart_pin_map[idx].tx, s_usart_pin_map[idx].function);
+ pin_mux(s_usart_pin_map[idx].rx, s_usart_pin_map[idx].function);
+ return s_usart_pin_map[idx].cfg_idx;
+ }
+ }
+ return -1;
+}
+#endif
+
+#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;
+/*
+static void usart1_event_cb(uint32_t event, void *cb_arg)
+{
+ switch (event)
+ {
+ case USART_EVENT_SEND_COMPLETE:
+ rt_hw_serial_isr(&serial1,RT_SERIAL_EVENT_TX_DONE);
+ break;
+
+ case USART_EVENT_RECEIVED:
+ rt_hw_serial_isr(&serial1,RT_SERIAL_EVENT_RX_IND);
+ break;
+
+ default:
+ break;
+ }
+}
+*/
+
+__attribute__((isr)) void USART1_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, SYSTEM_CLOCK, 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 */
+ dw_usart_clr_int_flag(uart,IER_RDA_INT_ENABLE);
+ break;
+
+ case RT_DEVICE_CTRL_SET_INT:
+ /* Enable the UART Interrupt */
+ dw_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);
+
+ dw_usart_putchar(uart,c);
+
+ return (1);
+}
+
+static int uart_getc(struct rt_serial_device *serial)
+{
+ uint8_t ch;
+ usart_handle_t uart;
+
+ RT_ASSERT(serial != RT_NULL);
+ uart = (usart_handle_t)serial->parent.user_data;
+ RT_ASSERT(uart != RT_NULL);
+
+ if (!dw_usart_getchar_no_poll(uart, &ch))
+ {
+ return (int)(ch);
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+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(UART_TXD1, UART_RXD1, NULL/*usart1_event_cb*/,
+ (void *) 0);
+
+ 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
diff --git a/bsp/ck802/drivers/config.h b/bsp/ck802/drivers/config.h
new file mode 100644
index 0000000000..e02d3204f9
--- /dev/null
+++ b/bsp/ck802/drivers/config.h
@@ -0,0 +1,44 @@
+/* config.h -- Autogenerated! Do not edit. */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_KERNEL_NONE 1
+//#define CONFIG_AES 1
+//#define CONFIG_SPI 1
+//#define CONFIG_SPI_DMA 1
+//#define CONFIG_DMAC 1
+//#define CONFIG_GPIO 1
+//#define CONFIG_IIC 1
+//#define CONFIG_SHA 1
+//#define CONFIG_RSA 1
+//#define CONFIG_TIMER 1
+#define CONFIG_USART 1
+//#define CONFIG_TRNG 1
+//#define CONFIG_CRC 1
+//#define CONFIG_EFLASH 1
+//#define CONFIG_WDT 1
+//#define CONFIG_RTC 1
+//#define CONFIG_PWM 1
+//#define CONFIG_TEST 1
+//#define CONFIG_ETH 1
+//#define CONFIG_TEST_DRIVER 1
+//#define CONFIG_TEST_AES 1
+//#define CONFIG_TEST_ETH 1
+//#define CONFIG_TEST_DMAC 1
+//#define CONFIG_TEST_GPIO 1
+//#define CONFIG_TEST_IIC 1
+//#define CONFIG_TEST_SHA 1
+//#define CONFIG_TEST_RSA 1
+//#define CONFIG_TEST_TIMER 1
+//#define CONFIG_TEST_USART 1
+//#define CONFIG_TEST_TRNG 1
+//#define CONFIG_TEST_CRC 1
+//#define CONFIG_TEST_EFLASH 1
+//#define CONFIG_TEST_SPI 1
+//#define CONFIG_TEST_WDT 1
+//#define CONFIG_TEST_RTC 1
+//#define CONFIG_TEST_PWM 1
+
+#endif /* __CONFIG_H */
+
diff --git a/bsp/ck802/drivers/isr.c b/bsp/ck802/drivers/isr.c
new file mode 100644
index 0000000000..c8c3f909d0
--- /dev/null
+++ b/bsp/ck802/drivers/isr.c
@@ -0,0 +1,174 @@
+/*
+ * 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 isr.c
+ * @brief source file for the interrupt server route
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <drv_common.h>
+#include "config.h"
+#include "soc.h"
+
+extern void dw_usart_irqhandler(int32_t idx);
+extern void dw_timer_irqhandler(int32_t idx);
+extern void dw_gpio_irqhandler(int32_t idx);
+extern void dw_iic_irqhandler(int32_t idx);
+extern void ck_rtc_irqhandler(int32_t idx);
+extern void dw_spi_irqhandler(int32_t idx);
+extern void dw_wdt_irqhandler(int32_t idx);
+extern void ck_dma_irqhandler(int32_t idx);
+extern void ck_aes_irqhandler(int32_t idx);
+extern void ck_sha_irqhandler(int32_t idx);
+#ifdef CONFIG_KERNEL_FREERTOS
+extern void CKTimer1Isr(void);
+extern void CKPendSVIsr(void);
+#endif
+
+#define readl(addr) \
+ ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+
+__attribute__((isr)) void CORET_IRQHandler(void)
+{
+ readl(0xE000E010);
+}
+
+#if defined(CONFIG_USART)
+/*
+__attribute__((isr)) void USART0_IRQHandler(void)
+{
+ dw_usart_irqhandler(0);
+}
+
+
+__attribute__((isr)) void USART1_IRQHandler(void)
+{
+ dw_usart_irqhandler(1);
+}
+
+
+__attribute__((isr)) void USART2_IRQHandler(void)
+{
+ dw_usart_irqhandler(2);
+}
+
+__attribute__((isr)) void USART3_IRQHandler(void)
+{
+ dw_usart_irqhandler(3);
+}
+*/
+#endif
+
+#if defined(CONFIG_TIMER)
+__attribute__((isr)) void TIMA0_IRQHandler(void)
+{
+ dw_timer_irqhandler(0);
+}
+
+__attribute__((isr)) void TIMA1_IRQHandler(void)
+{
+ dw_timer_irqhandler(1);
+}
+__attribute__((isr)) void TIMB0_IRQHandler(void)
+{
+ dw_timer_irqhandler(2);
+}
+
+__attribute__((isr)) void TIMB1_IRQHandler(void)
+{
+ dw_timer_irqhandler(3);
+}
+
+#endif
+
+#if defined(CONFIG_GPIO)
+
+__attribute__((isr)) void GPIOA_IRQHandler(void)
+{
+ dw_gpio_irqhandler(0);
+}
+
+__attribute__((isr)) void GPIOB_IRQHandler(void)
+{
+ dw_gpio_irqhandler(1);
+}
+#endif
+
+#if defined(CONFIG_IIC)
+__attribute__((isr)) void I2C0_IRQHandler(void)
+{
+ dw_iic_irqhandler(0);
+}
+
+__attribute__((isr)) void I2C1_IRQHandler(void)
+{
+ dw_iic_irqhandler(1);
+}
+#endif
+
+#if defined(CONFIG_RTC)
+
+__attribute__((isr)) void RTC_IRQHandler(void)
+{
+ ck_rtc_irqhandler(0);
+}
+
+#endif
+
+#if defined(CONFIG_AES)
+
+__attribute__((isr)) void AES_IRQHandler(void)
+{
+ ck_aes_irqhandler(0);
+}
+
+#endif
+
+#if defined(CONFIG_SHA)
+
+__attribute__((isr)) void SHA_IRQHandler(void)
+{
+ ck_sha_irqhandler(0);
+}
+
+#endif
+
+#if defined(CONFIG_SPI) && defined(CONFIG_GPIO)
+__attribute__((isr)) void SPI0_IRQHandler(void)
+{
+ dw_spi_irqhandler(0);
+}
+
+__attribute__((isr)) void SPI1_IRQHandler(void)
+{
+ dw_spi_irqhandler(1);
+}
+#endif
+
+#if defined(CONFIG_WDT)
+__attribute__((isr)) void WDT_IRQHandler(void)
+{
+ dw_wdt_irqhandler(0);
+}
+#endif
+
+#if defined(CONFIG_DMAC)
+__attribute__((isr)) void DMAC_IRQHandler(void)
+{
+ ck_dma_irqhandler(0);
+}
+#endif
diff --git a/bsp/ck802/drivers/pin_name.h b/bsp/ck802/drivers/pin_name.h
new file mode 100644
index 0000000000..73141f0865
--- /dev/null
+++ b/bsp/ck802/drivers/pin_name.h
@@ -0,0 +1,88 @@
+/*
+ * 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 pn_name.h
+ * @brief header file for the pin_name
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _PINNAMES_H
+#define _PINNAMES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ PA0_TXD0_PWM0_XX_SIROUT0 = 0,
+ PA1_RXD0_PWM1_XX_SIRIN0,
+ PA2_CTS0_PWM2_SPI0CLK_XX,
+ PA3_RTS0_PWM3_SPI0TX_XX,
+ PA4_SCL0_PWM4_SPI0RX_XX,
+ PA5_SDA0_PWM5_SPI0CS_XX,
+ PA6_SPI0CLK_PWMTRIG0_SCL0_XX,
+ PA7_SPI0TX_PWMTRIG1_SDA0_XX,
+ PA8_SPI0RX_TRIGFAULT_SCL1_XX,
+ PA9_SPI0CS_PWM0_SDA1_XX,
+ PA10_TXD1_PWM1_XX_SIROUT1,
+ PA11_RXD1_PWM2_XX_SIRIN1,
+ PA12_CTS1_PWM3_SPI1CLK_XX,
+ PA13_RTS1_PWM4_SPI1TX_XX,
+ PA14_SCL1_PWM5_SPI1RX_XX,
+ PA15_SDA1_PWMTRIG0_SPI1CS0_XX,
+ PA16_SPI1CLK_PWMTRIG1_XX_XX,
+ PA17_SPI1TX_PWMFAULT_XX_XX,
+ PA18_SPI1RX_PWM0_XX_XX,
+ PA19_SPI1CS0_PWM1_XX_XX,
+ PA20_SPI1CS1_PWM2_XX_XX,
+ PA21_SPI1CS2_PWM3_XX_XX,
+ PA22_RXD2_PWM4_XX_SIRIN2,
+ PA23_TXD2_PWM5_XX_SIROUT2,
+ PA24_CTS2_PWMTRIG0_SPI1CS1_XX,
+ PA25_XX_PWMTRIG1_SPI1CS2_XX,
+ PA26_TXD3_PWMFAULT_XX_SIROUT3,
+ PA27_RXD3_PWM0_XX_SIRIN3,
+ PA28_I2SMCLK_PWM1_XX_XX,
+ PA29_I2SSCLK_PWM2_XX_XX,
+ PA30_I2SWSCLK_PWM3_XX_XX,
+ PA31_I2SSDA__SCL0_PWM4_XX,
+ PB0_ADC0_SDA0_PWM5_XX,
+ PB1_ADC1_SCL1_USISCLK_XX,
+ PB2_ADC2_SDA1_USISD0_XX,
+ PB3_ADC3_SPI1CLK_USISD1_XX,
+ PB4_ADC4_SPI1TX_USINSS_XX,
+ PB5_ADC5_SPI1RX_USISCLK_XX,
+ PB6_ADC6_SPI1CS0_USISD0_XX,
+ PB7_ADC7_SPI1CS1_USISD1_XX,
+ PB8_PWMTRIG0_SPI1CS2_USINSS_XX,
+ PB9_PWMTRIG1_CTS3_XX_XX,
+ PB10_PWMFAULT_RTS3_XX_XX
+}
+pin_name_t;
+
+typedef enum
+{
+ PORTA = 0,
+ PORTB = 1
+} port_name_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/ck802/drivers/pinmux.c b/bsp/ck802/drivers/pinmux.c
new file mode 100644
index 0000000000..5990285ed0
--- /dev/null
+++ b/bsp/ck802/drivers/pinmux.c
@@ -0,0 +1,158 @@
+/*
+ * 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 pinmux.c
+ * @brief source file for the pinmux
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <stdint.h>
+#include "pinmux.h"
+#include "pin_name.h"
+
+#define readl(addr) \
+ ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
+
+#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
+
+/*******************************************************************************
+ * function: phobos_ioreuse_inital
+ *
+ * description:
+ * initial phobos_pinmux
+ *******************************************************************************/
+
+void phobos_ioreuse_initial(void)
+{
+ unsigned int value;
+
+ /* gpio data source select */
+ value = readl(PHOBOS_GIPO0_PORTCTL_REG);
+ value |= GPIO0_REUSE_EN;
+ writel(value, PHOBOS_GIPO0_PORTCTL_REG);
+
+ value = readl(PHOBOS_GIPO1_PORTCTL_REG);
+ value |= GPIO1_REUSE_EN;
+ writel(value, PHOBOS_GIPO1_PORTCTL_REG);
+
+ /* reuse function select */
+ value = readl(PHOBOS_IOMUX0L_REG);
+ value |= IOMUX0L_FUNCTION_SEL;
+ writel(value, PHOBOS_IOMUX0L_REG);
+
+ value = readl(PHOBOS_IOMUX0H_REG);
+ value |= IOMUX1L_FUNCTION_SEL;
+ writel(value, PHOBOS_IOMUX0H_REG);
+
+ value = readl(PHOBOS_IOMUX1L_REG);
+ value |= IOMUX1L_FUNCTION_SEL;
+ writel(value, PHOBOS_IOMUX1L_REG);
+}
+
+void phobos_pwm_ioreuse(void)
+{
+ unsigned int value;
+
+ /* gpio data source select */
+ value = readl(PHOBOS_GIPO0_PORTCTL_REG);
+ value |= PWM_GPIO0_REUSE_EN;
+ writel(value, PHOBOS_GIPO0_PORTCTL_REG);
+
+ /* reuse function select */
+ value = readl(PHOBOS_IOMUX0L_REG);
+ value |= PWM_IOMUX0L_FUNCTION_SEL;
+ writel(value, PHOBOS_IOMUX0L_REG);
+}
+
+
+int32_t pin_mux(pin_name_t pin, uint16_t function)
+{
+ unsigned int val = 0;
+ unsigned int reg_val = 0;
+
+ uint8_t offset;
+
+ if (function > 3)
+ {
+ if (pin < PB0_ADC0_SDA0_PWM5_XX)
+ {
+ offset = pin;
+ /* gpio data source select */
+ val = readl(PHOBOS_GIPO0_PORTCTL_REG);
+ val &= ~(1 << offset);
+ writel(val, PHOBOS_GIPO0_PORTCTL_REG);
+ return 0;
+ }
+ else if (pin >= PB0_ADC0_SDA0_PWM5_XX)
+ {
+ offset = pin - 32;
+ /* gpio data source select */
+ val = readl(PHOBOS_GIPO1_PORTCTL_REG);
+ val &= ~(1 << offset);
+ writel(val, PHOBOS_GIPO1_PORTCTL_REG);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ if (pin >= PB0_ADC0_SDA0_PWM5_XX)
+ {
+ offset = pin - 32;
+
+ /* gpio data source select */
+ val = readl(PHOBOS_GIPO1_PORTCTL_REG);
+ val |= (1 << offset);
+ writel(val, PHOBOS_GIPO1_PORTCTL_REG);
+
+ reg_val = (0x3 << (offset * 2));
+ /* reuse function select */
+ val = readl(PHOBOS_IOMUX1L_REG);
+ val &= ~(reg_val);
+ val |= (function << (2 * offset));
+ writel(val, PHOBOS_IOMUX1L_REG);
+ return 0;
+ }
+
+ offset = pin;
+ /* gpio data source select */
+ val = readl(PHOBOS_GIPO0_PORTCTL_REG);
+ val |= (1 << offset);
+ writel(val, PHOBOS_GIPO0_PORTCTL_REG);
+
+ if (pin >= PA16_SPI1CLK_PWMTRIG1_XX_XX)
+ {
+ offset = pin - 16;
+ reg_val = (0x3 << (offset * 2));
+ /* reuse function select */
+ val = readl(PHOBOS_IOMUX0H_REG);
+ val &= ~(reg_val);
+ val |= (function << (2 * offset));
+ writel(val, PHOBOS_IOMUX0H_REG);
+ return 0;
+ }
+
+ reg_val = (0x3 << (offset * 2));
+ /* reuse function select */
+ val = readl(PHOBOS_IOMUX0L_REG);
+ val &= ~(reg_val);
+ val |= (function << (2 * offset));
+ writel(val, PHOBOS_IOMUX0L_REG);
+ return 0;
+}
diff --git a/bsp/ck802/drivers/pinmux.h b/bsp/ck802/drivers/pinmux.h
new file mode 100644
index 0000000000..e299c9a8fb
--- /dev/null
+++ b/bsp/ck802/drivers/pinmux.h
@@ -0,0 +1,220 @@
+/*
+ * 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 pinmux.h
+ * @brief Header file for the pinmux
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef PHOBOS_PINMUX_H
+#define PHOBOS_PINMUX_H
+
+#include <stdint.h>
+#include "pin_name.h"
+
+void phobos_ioreuse_initial(void);
+int32_t pin_mux(pin_name_t pin, uint16_t function);
+
+/* IOMUX0L function definition */
+#define PA0_UART0_TX 0x00000000
+#define PA0_PWM_CH0 0x00000001
+#define PA0_UART0_SIROUT 0x00000003
+#define PA1_UART0_RX 0x00000000
+#define PA1_PWM_CH1 0x00000004
+#define PA1_UART0_SIRIN 0x0000000C
+#define PA2_UART0_CTS 0x00000000
+#define PA2_PWM_CH2 0x00000010
+#define PA2_SPI0_CLK 0x00000020
+#define PA3_UART0_TRS 0x00000000
+#define PA3_PWM_CH3 0x00000040
+#define PA3_SPI0_TX 0x00000080
+#define PA4_I2C0_SCL 0x00000000
+#define PA4_PWM_CH4 0x00000100
+#define PA4_SPI0_RX 0x00000200
+#define PA5_I2C0_SDA 0x00000000
+#define PA5_PWM_CH5 0x00000400
+#define PA5_SPI0_CS 0x00000800
+#define PA6_SPI0_CLK 0x00000000
+#define PA6_ETB_TRIG0 0x00001000
+#define PA6_I2C0_SCL 0x00002000
+#define PA7_SPI_TX 0x00000000
+#define PA7_ETB_TRIG1 0x00004000
+#define PA7_I2C0_SDA 0x00008000
+#define PA8_SPI0_TX 0x00000000
+#define PA8_PWM_FAULT 0x00010000
+#define PA8_I2C1_SCL 0x00020000
+#define PA9_SPI0_CS 0x00000000
+#define PA9_PWM_CH0 0x00040000
+#define PA9_I2C1_SDA 0x00080000
+#define PA10_UART1_TX 0x00000000
+#define PA10_PWM_CH1 0x00100000
+#define PA10_UART1_SIROUT 0x00300000
+#define PA11_UART1_RX 0x00000000
+#define PA11_PWM_CH2 0x00400000
+#define PA11_UART1_SIRIN 0x00C00000
+#define PA12_UART1_CTS 0x00000000
+#define PA12_PWM_CH3 0x01000000
+#define PA12_SPI1_CLK 0x02000000
+#define PA13_UART1_RTS 0x00000000
+#define PA13_PWM_CH4 0x04000000
+#define PA13_SPI1_TX 0x08000000
+#define PA14_I2C1_SCL 0x00000000
+#define PA14_PWM_CH5 0x10000000
+#define PA14_SPI1_RX 0x20000000
+#define PA15_I2C1_SDA 0x00000000
+#define PA15_ETB_TRIG0 0x40000000
+#define PA15_SPI1_CS0 0x80000000
+
+/* IOMUX0H function definition */
+#define PA16_SPI1_CLK 0x00000000
+#define PA16_ETB_TRIG1 0x00000001
+#define PA17_SPI1_TX 0x00000000
+#define PA17_PWM_FAULT 0x00000004
+#define PA18_SPI1_RX 0x00000000
+#define PA18_PWM_CH0 0x00000010
+#define PA19_SPI1_CS0 0x00000000
+#define PA19_PWM_CH1 0x00000040
+#define PA20_UART2_RX 0x00000000
+#define PA20_PWM_CH2 0x00000100
+#define PA21_SPI1_CS2 0x00000000
+#define PA21_PWM_CH3 0x00000400
+#define PA22_UART2_RX 0x00000000
+#define PA22_PWM_CH4 0x00001000
+#define PA22_UART2_SIRI 0x00003000
+#define PA23_UART2_TX 0x00000000
+#define PA23_PWM_CH5 0x00004000
+#define PA23_UART2_SIROUT 0x0000C000
+#define PA24_UART2_CTS 0x00000000
+#define PA24_ETB_TRIG0 0x00010000
+#define PA24_SPI1_CS1 0x00020000
+#define PA25_UART2_RTS 0x00000000
+#define PA25_ETB_TRIG1 0x00040000
+#define PA25_SPI1_CS2 0x00080000
+#define PA26_UART3_TX 0x00000000
+#define PA26_PWM_FAULT 0x00100000
+#define PA26_UART3_SIROUT 0x00300000
+#define PA27_UART3_RX 0x00000000
+#define PA27_PWM_CH0 0x00400000
+#define PA27_UART3_SIRIN 0x00C00000
+#define PA28_I2S_MCLK 0x00000000
+#define PA28_PWM_CH1 0x01000000
+#define PA29_I2S_SCLK 0x00000000
+#define PA29_PWM_CH2 0x04000000
+#define PA30_I2S_WSCLK 0x00000000
+#define PA30_PWM_CH3 0x10000000
+#define PA31_I2S_SDA 0x00000000
+#define PA31_I2C0_SCL 0x40000000
+#define PA31_PWM_CH4 0x80000000
+
+/* IOMUX1L function definition */
+#define PB0_ADC0 0x00000000
+#define PB0_I2C0_SDA 0x00000001
+#define PB0_PWM_CH5 0x00000002
+#define PB1_ADC1 0x00000000
+#define PB1_I2C1_SCL 0x00000004
+#define PB1_USI_SCLK 0x00000008
+#define PB2_ADC2 0x00000000
+#define PB2_I2C1_SDA 0x00000010
+#define PB2_USI_SD0 0x00000020
+#define PB3_ADC3 0x00000000
+#define PB3_SPI1_CLK 0x00000040
+#define PB3_USI_SD1 0x00000080
+#define PB4_ADC4 0x00000000
+#define PB4_SPI1_TX 0x00000100
+#define PB4_USI_NSS 0x00000200
+#define PB5_ADC5 0x00000000
+#define PB5_SPI1_RX 0x00000400
+#define PB5_USI_SCLK 0x00000800
+#define PB6_ADC6 0x00000000
+#define PB6_SPI1_CS0 0x00001000
+#define PB6_USI_SD0 0x00002000
+#define PB7_ADC7 0x00000000
+#define PB7_SPI1_CS1 0x00004000
+#define PB7_USI_SD1 0x00008000
+#define PB8_ETB_TRIG0 0x00000000
+#define PB8_SPI1_CS2 0x00010000
+#define PB8_USI_NSS 0x00020000
+#define PB9_ETB_TRIG1 0x00000000
+#define PB9_UART3_CTS 0x00040000
+#define PB10_PWM_FAULT 0x00000000
+#define PB10_UART3_RTS 0x00100000
+
+
+/* flag as identification */
+#define GPIO_SET_BIT0 0x00000001
+#define GPIO_SET_BIT1 0x00000002
+#define GPIO_SET_BIT2 0x00000004
+#define GPIO_SET_BIT3 0x00000008
+#define GPIO_SET_BIT4 0x00000010
+#define GPIO_SET_BIT5 0x00000020
+#define GPIO_SET_BIT6 0x00000040
+#define GPIO_SET_BIT7 0x00000080
+#define GPIO_SET_BIT8 0x00000100
+#define GPIO_SET_BIT9 0x00000200
+#define GPIO_SET_BIT10 0x00000400
+#define GPIO_SET_BIT11 0x00000800
+#define GPIO_SET_BIT12 0x00001000
+#define GPIO_SET_BIT13 0x00002000
+#define GPIO_SET_BIT14 0x00004000
+#define GPIO_SET_BIT15 0x00008000
+#define GPIO_SET_BIT16 0x00010000
+#define GPIO_SET_BIT17 0x00020000
+#define GPIO_SET_BIT18 0x00040000
+#define GPIO_SET_BIT19 0x00080000
+#define GPIO_SET_BIT20 0x00100000
+#define GPIO_SET_BIT21 0x00200000
+#define GPIO_SET_BIT22 0x00400000
+#define GPIO_SET_BIT23 0x00800000
+#define GPIO_SET_BIT24 0x01000000
+#define GPIO_SET_BIT25 0x02000000
+#define GPIO_SET_BIT26 0x04000000
+#define GPIO_SET_BIT27 0x08000000
+#define GPIO_SET_BIT28 0x10000000
+#define GPIO_SET_BIT29 0x20000000
+#define GPIO_SET_BIT30 0x40000000
+#define GPIO_SET_BIT31 0x80000000
+
+/******************************************************************************
+ * phobos gpio control and gpio reuse function
+ * selecting regester adddress
+ ******************************************************************************/
+
+#define PHOBOS_GIPO0_PORTCTL_REG 0x50018008
+#define PHOBOS_GIPO1_PORTCTL_REG 0x60018008
+#define PHOBOS_IOMUX0L_REG 0x50018100
+#define PHOBOS_IOMUX0H_REG 0x50018104
+#define PHOBOS_IOMUX1L_REG 0x50018108
+
+/*************basic gpio reuse v1.0********************************************
+ * UART0(PA0,PA1)
+ * UART1(PA10,PA11)
+ * UART2(PA22,PA23)
+ * UART3(PA26,PA27)
+ * IIS(PA24,PA25,PA26,PA27)
+ * SPI1(PA16,PA17,PA18)
+ * IIC0(PA4,PA5)
+ ******************************************************************************/
+#define GPIO0_REUSE_EN (GPIO_SET_BIT0|GPIO_SET_BIT1|GPIO_SET_BIT4|GPIO_SET_BIT5|GPIO_SET_BIT6|GPIO_SET_BIT9|GPIO_SET_BIT10|GPIO_SET_BIT11|GPIO_SET_BIT16|GPIO_SET_BIT17|GPIO_SET_BIT18|GPIO_SET_BIT22|GPIO_SET_BIT23|GPIO_SET_BIT26|GPIO_SET_BIT27)
+#define GPIO1_REUSE_EN (GPIO_SET_BIT0)
+#define IOMUX0L_FUNCTION_SEL (PA0_UART0_TX|PA1_UART0_RX|PA4_I2C0_SCL|PA5_I2C0_SDA|PA6_ETB_TRIG0|PA9_PWM_CH0|PA10_UART1_TX|PA11_UART1_RX)
+#define IOMUX0H_FUNCTION_SEL (PA16_SPI1_CLK|PA17_SPI1_TX|PA18_SPI1_RX|PA22_UART2_RX|PA23_UART2_TX|PA26_UART3_TX|PA27_UART3_RX)
+#define IOMUX1L_FUNCTION_SEL (PB0_ADC0)
+
+#define PWM_GPIO0_REUSE_EN (GPIO0_REUSE_EN|GPIO_SET_BIT0|GPIO_SET_BIT1|GPIO_SET_BIT2|GPIO_SET_BIT12|GPIO_SET_BIT13|GPIO_SET_BIT14)
+#define PWM_IOMUX0L_FUNCTION_SEL (IOMUX0L_FUNCTION_SEL|PA0_PWM_CH0|PA1_PWM_CH1|PA2_PWM_CH2|PA12_PWM_CH3|PA13_PWM_CH4|PA14_PWM_CH5)
+
+#endif /* PHOBOS_PINMUX_H */
diff --git a/bsp/ck802/drivers/soc.h b/bsp/ck802/drivers/soc.h
new file mode 100644
index 0000000000..7a3b80cf79
--- /dev/null
+++ b/bsp/ck802/drivers/soc.h
@@ -0,0 +1,318 @@
+/*
+ * 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 soc.h
+ * @brief CSI Core Peripheral Access Layer Header File for
+ * CSKYSOC Device Series
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef SOC_H
+#define SOC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SYSTEM_CLOCK (20000000)
+
+/* ------------------------- Interrupt Number Definition ------------------------ */
+
+typedef enum IRQn
+{
+ /* ---------------------- CSKYCK801 Specific Interrupt Numbers --------------------- */
+ GPIOA_IRQn = 0,
+ CORET_IRQn = 1, /* core Timer Interrupt */
+ TIMA0_IRQn = 2, /* timerA0 Interrupt */
+ TIMA1_IRQn = 3, /* timerA1 Interrupt */
+ WDT_IRQn = 5, /* wdt Interrupt */
+ UART0_IRQn = 6, /* uart0 Interrupt */
+ UART1_IRQn = 7, /* uart1 Interrupt */
+ UART2_IRQn = 8, /* uart2 Interrupt */
+ I2C0_IRQn = 9, /* i2c0 Interrupt */
+ I2C1_IRQn = 10, /* i2c1 Interrupt */
+ SPI1_IRQn = 11, /* spi0 Interrupt */
+ SPI0_IRQn = 12, /* spi1 Interrupt */
+ RTC_IRQn = 13, /* rtc Interrupt */
+ EXTWAK_IRQn = 14, /* extwakeup Interrupt */
+ DMAC_IRQn = 17, /* dmac Interrupt */
+ PMU_IRQn = 18, /* pmu Interrupt */
+ PWM_IRQn = 19, /* pwm Interrupt */
+ UART3_IRQn = 21, /* uart3 Interrupt */
+ TIMB0_IRQn = 23, /* timerB0 Interrupt */
+ TIMB1_IRQn = 24, /* timerB1 Interrupt */
+ GPIOB_IRQn = 27, /* GPIOB Interrupt */
+ AES_IRQn = 26, /* aes Interrupt */
+ RSA_IRQn = 28, /* rsa Interrupt */
+ SHA_IRQn = 29, /* sha Interrupt */
+
+}
+IRQn_Type;
+
+/* ================================================================================ */
+/* ================ Processor and Core Peripheral Section ================ */
+/* ================================================================================ */
+
+/* -------- Configuration of the CK801 Processor and Core Peripherals ------- */
+#define __CK802_REV 0x0000U /* Core revision r0p0 */
+#define __MGU_PRESENT 0 /* MGU present or not */
+#define __NVIC_PRIO_BITS 2 /* Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */
+
+#include "core_ck802.h" /* Processor and core peripherals */
+#include "stdint.h"
+
+typedef enum
+{
+ CKENUM_DMA_UART0_RX,
+ CKENUM_DMA_UART0_TX,
+ CKENUM_DMA_UART1_RX,
+ CKENUM_DMA_UART1_TX,
+ CKENUM_DMA_ADC_RX,
+ CKENUM_DMA_ADC_TX,
+ CKENUM_DMA_SPI1_RX,
+ CKENUM_DMA_SPI1_TX,
+ CKENUM_DMA_SPI0_RX,
+ CKENUM_DMA_SPI0_TX,
+ CKENUM_DMA_IIC_RX,
+ CKENUM_DMA_IIC_TX,
+ CKENUM_DMA_IIC1_RX,
+ CKENUM_DMA_IIC1_TX,
+ CKENUM_DMA_IIS_RX,
+ CKENUM_DMA_IIS_TX,
+ CKENUM_DMA_MEMORY
+} ckenum_dma_device_e;
+
+/* ================================================================================ */
+/* ================ Device Specific Peripheral Section ================ */
+/* ================================================================================ */
+#if 0
+
+/* ================================================================================ */
+/* ============== Universal Asyncronous Receiver / Transmitter (UART) ============= */
+/* ================================================================================ */
+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 */
+ __IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem control register */
+ __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 */
+} CSKY_UART_TypeDef;
+
+/* ================================================================================ */
+/* ============== Inter-Integrated Circuit (IIC) ============= */
+/* ================================================================================ */
+typedef struct
+{
+ __IOM uint32_t IC_CON; /* Offset: 0x000 (R/W) Receive buffer register */
+ __IOM uint32_t IC_TAR; /* Offset: 0x004 (R/W) Transmission hold register */
+ __IOM uint32_t IC_SAR; /* Offset: 0x008 (R/W) Clock frequency division low section register */
+ __IOM uint32_t IC_HS_MADDR; /* Offset: 0x00c (R/W) Clock frequency division high section register */
+ __IOM uint32_t IC_DATA_CMD; /* Offset: 0x010 (R/W) Interrupt enable register */
+ __IOM uint32_t IC_SS_SCL_HCNT; /* Offset: 0x014 (R/W) Interrupt indicia register */
+ __IOM uint32_t IC_SS_SCL_LCNT; /* Offset: 0x018 (R/W) Transmission control register */
+ __IOM uint32_t IC_FS_SCL_HCNT; /* Offset: 0x01c (R/W) Modem control register */
+ __IOM uint32_t IC_FS_SCL_LCNT; /* Offset: 0x020 (R/W) Transmission state register */
+ __IOM uint32_t IC_HS_SCL_HCNT; /* Offset: 0x024 (R/W) Transmission state register */
+ __IOM uint32_t IC_HS_SCL_LCNT; /* Offset: 0x028 (R/W) Transmission state register */
+ __IOM uint32_t IC_INTR_STAT; /* Offset: 0x02c (R) Transmission state register */
+ __IOM uint32_t IC_INTR_MASK; /* Offset: 0x030 (R/W) Transmission state register */
+ __IOM uint32_t IC_RAW_INTR_STAT; /* Offset: 0x034 (R) Transmission state register */
+ __IOM uint32_t IC_RX_TL; /* Offset: 0x038 (R/W) Transmission state register */
+ __IOM uint32_t IC_TX_TL; /* Offset: 0x03c (R/W) Transmission state register */
+ __IOM uint32_t IC_CLR_INTR; /* Offset: 0x040 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_RX_UNDER; /* Offset: 0x044 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_RX_OVER; /* Offset: 0x048 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_TX_OVER; /* Offset: 0x04c (R) Transmission state register */
+ __IOM uint32_t IC_CLR_RD_REQ; /* Offset: 0x050 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_TX_ABRT; /* Offset: 0x054 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_RX_DONE; /* Offset: 0x058 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_ACTIVITY; /* Offset: 0x05c (R) Transmission state register */
+ __IOM uint32_t IC_CLR_STOP_DET; /* Offset: 0x060 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_START_DET; /* Offset: 0x064 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_GEN_CALL; /* Offset: 0x068 (R) Transmission state register */
+ __IOM uint32_t IC_ENABLE; /* Offset: 0x06c (R/W) Transmission state register */
+ __IOM uint32_t IC_STATUS; /* Offset: 0x070 (R) Transmission state register */
+ __IOM uint32_t IC_TXFLR; /* Offset: 0x074 (R) Transmission state register */
+ __IOM uint32_t IC_RXFLR; /* Offset: 0x078 (R) Transmission state register */
+ uint32_t RESERVED; /* Offset: 0x014 (R/ ) Transmission state register */
+ __IOM uint32_t IC_TX_ABRT_SOURCE; /* Offset: 0x080 (R/W) Transmission state register */
+ __IOM uint32_t IC_SAR1; /* Offset: 0x084 (R/W) Transmission state register */
+ __IOM uint32_t IC_DMA_CR; /* Offset: 0x088 (R/W) Transmission state register */
+ __IOM uint32_t IC_DMA_TDLR; /* Offset: 0x08c (R/W) Transmission state register */
+ __IOM uint32_t IC_DMA_RDLR; /* Offset: 0x090 (R/W) Transmission state register */
+ __IOM uint32_t IC_SAR2; /* Offset: 0x094 (R/W) Transmission state register */
+ __IOM uint32_t IC_SAR3; /* Offset: 0x098 (R/W) Transmission state register */
+ __IOM uint32_t IC_MULTI_SLAVE; /* Offset: 0x09c (R/W) Transmission state register */
+ __IOM uint32_t IC_GEN_CALL_EN; /* Offset: 0x0a0 (R/W) Transmission state register */
+
+} CSKY_IIC_TypeDef;
+
+/* ================================================================================ */
+/* ============== TIMER ============= */
+/* ================================================================================ */
+typedef struct
+{
+ __IOM uint32_t TxLoadCount; /* Offset: 0x000 (R/W) Receive buffer register */
+ __IOM uint32_t TxCurrentValue; /* Offset: 0x004 (R) Transmission hold register */
+ __IOM uint32_t TxControl; /* Offset: 0x008 (R/W) Clock frequency division low section register */
+ __IOM uint32_t TxEOI; /* Offset: 0x00c (R) Clock frequency division high section register */
+ __IOM uint32_t TxIntStatus; /* Offset: 0x010 (R) Interrupt enable register */
+
+} CSKY_TIMER_TypeDef;
+
+/* ================================================================================ */
+/* ============== TIMER Control ============= */
+/* ================================================================================ */
+typedef struct
+{
+ __IOM uint32_t TimersIntStatus; /* Offset: 0x000 (R) Interrupt indicia register */
+ __IOM uint32_t TimerEOI; /* Offset: 0x004 (R) Transmission control register */
+ __IOM uint32_t TimerRawIntStatus; /* Offset: 0x008 (R) Modem control register */
+
+} CSKY_TIMER_Control_TypeDef;
+
+/* ================================================================================ */
+/* ============== GPIO ============= */
+/* ================================================================================ */
+typedef struct
+{
+ __IOM uint32_t SWPORT_DR; /* Offset: 0x000 (R/W) Interrupt indicia register */
+ __IOM uint32_t SWPORT_DDR; /* Offset: 0x004 (R/W) Interrupt indicia register */
+ __IOM uint32_t PORT_CTL; /* Offset: 0x008 (R/W) Interrupt indicia register */
+} CKStruct_GPIO, *PCKStruct_GPIO;
+
+typedef struct
+{
+ __IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */
+ __IOM uint32_t SHA_INTSTATE; /* Offset: 0x004 (R/W) Instatus register */
+ __IOM uint32_t SHA_H0L; /* Offset: 0x008 (R/W) H0L register */
+ __IOM uint32_t SHA_H1L; /* Offset: 0x00c (R/W) H1L register */
+ __IOM uint32_t SHA_H2L; /* Offset: 0x010 (R/W) H2L register */
+ __IOM uint32_t SHA_H3L; /* Offset: 0x014 (R/W) H3L register */
+ __IOM uint32_t SHA_H4L; /* Offset: 0x018 (R/W) H4L register */
+ __IOM uint32_t SHA_H5L; /* Offset: 0x01c (R/W) H5L register */
+ __IOM uint32_t SHA_H6L; /* Offset: 0x020 (R/W) H6L register */
+ __IOM uint32_t SHA_H7L; /* Offset: 0x024 (R/W) H7L register */
+ __IOM uint32_t SHA_H0H; /* Offset: 0x028 (R/W) H0H register */
+ __IOM uint32_t SHA_H1H; /* Offset: 0x02c (R/W) H1H register */
+ __IOM uint32_t SHA_H2H; /* Offset: 0x030 (R/W) H2H register */
+ __IOM uint32_t SHA_H3H; /* Offset: 0x034 (R/W) H3H register */
+ __IOM uint32_t SHA_H4H; /* Offset: 0x038 (R/W) H4H register */
+ __IOM uint32_t SHA_H5H; /* Offset: 0x03c (R/W) H5H register */
+ __IOM uint32_t SHA_H6H; /* Offset: 0x040 (R/W) H6H register */
+ __IOM uint32_t SHA_H7H; /* Offset: 0x044 (R/W) H7H register */
+ __IOM uint32_t SHA_DATA1; /* Offset: 0x048 (R/W) DATA1 register */
+ uint32_t REV[15];
+ __IOM uint32_t SHA_DATA2; /* Offset: 0x088 (R/W) DATA2 register */
+} CSKY_SHA_TypeDef;
+
+#endif
+
+#define CONFIG_CRC_NUM 1
+#define CONFIG_IIC_NUM 2
+#define CONFIG_TRNG_NUM 1
+#define CONFIG_EFLASH_NUM 1
+#define CONFIG_AES_NUM 1
+#define CONFIG_RSA_NUM 1
+#define CONFIG_SHA_NUM 1
+#define CONFIG_SPI_NUM 2
+#define CONFIG_PWM_NUM 1
+#define CONFIG_TIMER_NUM 4
+#define CONFIG_RTC_NUM 1
+#define CONFIG_WDT_NUM 1
+#define CONFIG_DMAC_NUM 1
+#define CONFIG_ETH_NUM 2
+
+#define CSKY_I2C0_BASE (0x50014000UL)
+#define CSKY_I2C1_BASE (0x60014000UL)
+
+#define CONFIG_USART_NUM 4
+#define CSKY_UART0_BASE (0x50010000UL)
+#define CSKY_UART1_BASE (0x50010400UL)
+#define CSKY_UART2_BASE (0x60010000UL)
+#define CSKY_UART3_BASE (0x60010400UL)
+
+/* ================================================================================ */
+/* ================ Peripheral memory map ================ */
+/* ================================================================================ */
+/* -------------------------- CPU FPGA memory map ------------------------------- */
+#define CSKY_EFLASH_BASE (0x10000000UL)
+#define CSKY_SRAM_BASE (0x20000000UL)
+
+#define CSKY_PMU_BASE (0x40000000UL)
+#define CSKY_DMA_BASE (0x40001000UL)
+#define CSKY_EFLASH_CONTROL_BASE (0x40005000UL)
+#define CSKY_OTP_BASE (0x40006000UL)
+#define CSKY_SRAM_CONTROL_BASE (0x40009000UL)
+#define CSKY_AES_BASE (0x4000d000UL)
+#define CSKY_SHA_BASE (0x4000e000UL)
+#define CSKY_RSA_BASE (0x4000f000UL)
+#define CSKY_CRC_BASE (0x40010000UL)
+#define CSKY_TRNG_BASE (0x40015000UL)
+#define CSKY_TIMERA0_BASE (0x50000000UL)
+#define CSKY_TIMERA1_BASE (0x50000014UL)
+#define CSKY_TIMERA_CONTROL_BASE (0x500000a0UL)
+#define CSKY_RTC_BASE (0x50004000UL)
+#define CSKY_WDT_BASE (0x50008000UL)
+#define CSKY_SPI0_BASE (0x5000c000UL)
+
+#define CONFIG_GPIO_NUM 2
+#define CONFIG_GPIO_PIN_NUM 43
+#define CSKY_GPIOA_BASE (0x50018000UL)
+#define CSKY_GPIOA_CONTROL_BASE (0x50018030UL)
+#define CSKY_PWM_BASE (0x5001c000UL)
+#define CSKY_ADC_BASE (0x50020000UL)
+#define CSKY_I2S0_BASE (0x50030000UL)
+#define CSKY_TIMERB0_BASE (0x60000000UL)
+#define CSKY_TIMERB1_BASE (0x60000014UL)
+#define CSKY_SPI1_BASE (0x6000c000UL)
+
+#define CSKY_GPIOB_BASE (0x60018000UL)
+#define CSKY_GPIOB_CONTROL_BASE (0x60018030UL)
+#define CSKY_TIMERB_CONTROL_BASE (0x600000a0UL)
+#define CSKY_SIPC_BASE (0x6001c000UL)
+#define CSKY_I2S1_BASE (0x60020000UL)
+#define CSKY_ETB_BASE (0x60024000UL)
+#define CSKY_USI_BASE (0x60028000UL)
+
+/* ================================================================================ */
+/* ================ Peripheral declaration ================ */
+/* ================================================================================ */
+#define CSKY_UART1 (( CSKY_UART_TypeDef *) CSKY_UART1_BASE)
+#define CSKY_SHA (( CSKY_SHA_TypeDef *) CSKY_SHA_BASE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SOC_H */
diff --git a/bsp/ck802/drivers/system.c b/bsp/ck802/drivers/system.c
new file mode 100644
index 0000000000..772a8dab5e
--- /dev/null
+++ b/bsp/ck802/drivers/system.c
@@ -0,0 +1,64 @@
+/*
+ * 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 system_PHOBOS.c
+ * @brief CSI Device System Source File for PHOBOS
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#include "soc.h"
+#include "csi_core.h"
+#include "config.h"
+
+/*----------------------------------------------------------------------------
+ Define clocks
+ *----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ System Core Clock Variable
+ *----------------------------------------------------------------------------*/
+int SystemCoreClock = SYSTEM_CLOCK; /* System Core Clock Frequency */
+
+extern int __Vectors;
+
+void SystemCoreClockUpdate(void)
+{
+ SystemCoreClock = SYSTEM_CLOCK;
+}
+
+/**
+ * @brief initialize the system
+ * Initialize the psr and vbr.
+ * @param None
+ * @return None
+ */
+void SystemInit(void)
+{
+ /* Here we may setting exception vector, MGU, cache, and so on. */
+#ifdef CONFIG_SYSTEM_SECURE
+ __set_PSR(0xc0000140);
+#else
+ __set_PSR(0x80000140);
+#endif
+ __set_VBR((uint32_t) & (__Vectors));
+
+ drv_coret_config(200 * 1000, CORET_IRQn); //10ms
+ drv_nvic_enable_irq(CORET_IRQn);
+
+ SystemCoreClock = SYSTEM_CLOCK;
+}
diff --git a/bsp/ck802/gcc_csky.ld b/bsp/ck802/gcc_csky.ld
new file mode 100644
index 0000000000..44ffedd05c
--- /dev/null
+++ b/bsp/ck802/gcc_csky.ld
@@ -0,0 +1,226 @@
+/*
+ * 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
+{
+ ROM : ORIGIN = 0x0 , LENGTH = 0x1FFF /* ROM 8KB*/
+ EFLASH : ORIGIN = 0x10000000 , LENGTH = 0x3FFFF /* E-FLASH 256KB*/
+ SRAM : ORIGIN = 0x20000000 , LENGTH = 0x18000 /* on-chip SRAM 128KB*/
+}
+
+PROVIDE (__StackTop = 0x20020000 - 0x8);
+PROVIDE (Stack_Size = 0x1000);
+/*
+PROVIDE (__heap_start = 0x20018000);
+PROVIDE (__heap_end = 0x2001a000);
+PROVIDE (Heap_Size = 0x2000);
+*/
+
+REGION_ALIAS("REGION_TEXT", SRAM);
+REGION_ALIAS("REGION_RODATA", SRAM);
+REGION_ALIAS("REGION_CUSTOM1", SRAM);
+REGION_ALIAS("REGION_CUSTOM2", SRAM);
+REGION_ALIAS("REGION_DATA", SRAM);
+REGION_ALIAS("REGION_BSS", SRAM);
+
+ENTRY(Reset_Handler)
+SECTIONS
+{
+ .text : AT(ADDR(.text)){
+ . = ALIGN(0x4) ;
+ *(.vectors)
+ __stext = . ;
+ *(.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
+ .rodata : AT(LOADADDR(.text) + SIZEOF(.text)){
+ . = ALIGN(0x4) ;
+ __srodata = .;
+ *(.rdata)
+ *(.rdata*)
+ *(.rdata1)
+ *(.rdata.*)
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata*)
+ *(.rodata.*)
+ *(.rodata.str1.4)
+ . = ALIGN(0x4) ;
+ __erodata = .;
+ } > REGION_RODATA
+ .data : AT(LOADADDR(.rodata) + SIZEOF(.rodata)){
+ . = ALIGN(0x4) ;
+ __sdata = . ;
+ __data_start__ = . ;
+ data_start = . ;
+ *(.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 = .;
+ *(.sdata)
+ *(.sdata.*)
+ *(.gnu.linkonce.s.*)
+ *(__libc_atexit)
+ *(__libc_subinit)
+ *(__libc_subfreeres)
+ *(.note.ABI-tag)
+ . = ALIGN(0x4) ;
+ __edata = .;
+ __data_end__ = .;
+ } > REGION_DATA
+ .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
+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } > REGION_BSS
+ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } > REGION_BSS
+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ }
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ }
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ }
+ .ctors :
+ {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } > REGION_BSS
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } > REGION_BSS
+ .junk 0 : { *(.rel*) *(.rela*) }
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
diff --git a/bsp/ck802/libraries/SConscript b/bsp/ck802/libraries/SConscript
new file mode 100644
index 0000000000..862d3c70c3
--- /dev/null
+++ b/bsp/ck802/libraries/SConscript
@@ -0,0 +1,48 @@
+import rtconfig
+Import('RTT_ROOT')
+from building import *
+
+# get current directory
+cwd = GetCurrentDir()
+
+# The set of source files associated with this SConscript file.
+src = Split("""
+startup_gcc.S
+common/aes/ck_aes.c
+common/crc/ck_crc.c
+common/dmac/ck_dmac.c
+common/eflash/ck_eflash.c
+common/pwm/ck_pwm.c
+common/rsa/ck_rsa.c
+common/sha/ck_sha.c
+common/trng/ck_trng.c
+common/timer/dw_timer.c
+common/gpio/dw_gpio.c
+common/spi/dw_spi.c
+common/iic/dw_iic.c
+common/usart/dw_usart.c
+common/wdt/dw_wdt.c
+""")
+
+path = [cwd + '/include',
+ cwd + '/common/aes',
+ cwd + '/common/aes',
+ cwd + '/common/crc',
+ cwd + '/common/dmac',
+ cwd + '/common/eflash',
+ cwd + '/common/gpio',
+ cwd + '/common/iic',
+ cwd + '/common/pwm',
+ cwd + '/common/rsa',
+ cwd + '/common/rtc',
+ cwd + '/common/sha',
+ cwd + '/common/spi',
+ cwd + '/common/timer',
+ cwd + '/common/trng',
+ cwd + '/common/usart',
+ cwd + '/common/wdt'
+]
+
+group = DefineGroup('libraries', src, depend = [''], CPPPATH = path)
+
+Return('group')
diff --git a/bsp/ck802/libraries/common/aes/ck_aes.c b/bsp/ck802/libraries/common/aes/ck_aes.c
new file mode 100644
index 0000000000..dabeb93c4d
--- /dev/null
+++ b/bsp/ck802/libraries/common/aes/ck_aes.c
@@ -0,0 +1,499 @@
+/*
+ * 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 ck_aes.c
+ * @brief CSI Source File for aes driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include "csi_core.h"
+#include "drv_aes.h"
+#include "ck_aes.h"
+
+#define ERR_AES(errno) (CSI_DRV_ERRNO_AES_BASE | errno)
+#define AES_NULL_PARA_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_AES(EDRV_PARAMETER); \
+ } \
+ } while (0)
+static ck_aes_reg_t *aes_reg = NULL;
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ void *iv;
+ uint8_t *result_out;
+ uint32_t len;
+ aes_event_cb_t cb;
+ aes_mode_e mode;
+ aes_key_len_bits_e keylen;
+ aes_endian_mode_e endian;
+ aes_status_t status;
+} ck_aes_priv_t;
+
+static ck_aes_priv_t aes_handle[CONFIG_AES_NUM];
+
+/* Driver Capabilities */
+static const aes_capabilities_t driver_capabilities = {
+ .ecb_mode = 1, /* ECB mode */
+ .cbc_mode = 1, /* CBC mode */
+ .cfb_mode = 0, /* CFB mode */
+ .ofb_mode = 0, /* OFB mode */
+ .ctr_mode = 0, /* CTR mode */
+ .bits_128 = 1, /* 128bits key length mode */
+ .bits_192 = 1, /* 192bits key lenght mode */
+ .bits_256 = 1 /* 256bits key length mode */
+};
+
+//
+// Functions
+//
+
+static inline void aes_set_opcode(aes_crypto_mode_e opcode)
+{
+ aes_reg->ctrl &= ~(3 << AES_OPCODE_OFFSET); //clear bit[7:6]
+ aes_reg->ctrl |= (opcode << AES_OPCODE_OFFSET); //set opcode
+}
+
+static inline void aes_set_endian(aes_endian_mode_e endian)
+{
+ if (endian == AES_ENDIAN_LITTLE) {
+ aes_reg->ctrl &= ~AES_LITTLE_ENDIAN;
+ } else {
+ aes_reg->ctrl |= AES_LITTLE_ENDIAN;
+ }
+}
+
+static inline uint32_t aes_set_keylen(aes_key_len_bits_e keylength)
+{
+ aes_reg->ctrl &= ~(3 << AES_KEY_LEN_OFFSET); //clear bit[5:4]
+ aes_reg->ctrl |= (keylength << AES_KEY_LEN_OFFSET);// Set key length
+
+ return 0;
+}
+
+static inline void aes_set_mode(aes_mode_e mode)
+{
+ aes_reg->ctrl &= ~(1 << AES_MODE_OFFSET); //clear bit 3
+ aes_reg->ctrl |= (mode << AES_MODE_OFFSET); //set mode
+}
+
+static inline void aes_enable(void)
+{
+ aes_reg->ctrl |= (1 << AES_WORK_ENABLE_OFFSET);
+}
+
+static inline void aes_disable(void)
+{
+ aes_reg->ctrl &= ~(1 << AES_WORK_ENABLE_OFFSET);
+}
+
+static inline void aes_enable_interrupt(void)
+{
+ aes_reg->ctrl |= (1 << AES_INT_ENABLE_OFFSET);
+}
+
+static inline void aes_disable_interrupt(void)
+{
+ aes_reg->ctrl &= ~(1 << AES_INT_ENABLE_OFFSET);
+}
+
+static inline void aes_clear_interrupt(void)
+{
+ aes_reg->state = 0x0;
+}
+
+static inline uint32_t aes_get_intstatus(uint32_t AES_IT)
+{
+ return (aes_reg->state & AES_IT) ? 1 : 0;
+}
+
+static void aes_set_key(void *context, uint8_t *key, uint32_t keylen, uint32_t enc, uint32_t endian)
+{
+ uint8_t keynum = 0;
+
+ if (keylen == AES_KEY_LEN_BITS_128) {
+ keynum = 4;
+ } else if (keylen == AES_KEY_LEN_BITS_192) {
+ keynum = 6;
+ } else if (keylen == AES_KEY_LEN_BITS_256) {
+ keynum = 8;
+ }
+
+ uint32_t i;
+ /* set key according to the endian mode */
+ if (endian == AES_ENDIAN_LITTLE) {
+ for (i = 0; i < keynum; i++) {
+ aes_reg->key[keynum - 1 - i] = *(uint32_t *)key;
+ key += 4;
+ }
+ } else if (endian == AES_ENDIAN_BIG) {
+ for (i = 0; i < keynum; i++) {
+ aes_reg->key[i] = *(uint32_t *)key;
+ key += 4;
+ }
+ }
+
+ if (enc == AES_CRYPTO_MODE_DECRYPT) {
+ aes_set_opcode(AES_CRYPTO_KEYEXP); /* if the mode is decrypt before decrypt you have to keyexpand */
+ aes_enable();
+
+ while (aes_get_intstatus(AES_IT_KEYINT));
+
+ aes_set_opcode(AES_CRYPTO_MODE_DECRYPT);
+ } else if (enc == AES_CRYPTO_MODE_ENCRYPT) {
+ aes_set_opcode(AES_CRYPTO_MODE_ENCRYPT);
+ }
+
+ aes_disable();
+}
+
+static int aes_crypto(void *context, uint8_t *in, uint8_t *out,
+ uint32_t len, uint8_t *iv, uint32_t mode, uint32_t endian)
+{
+ uint32_t i = 0;
+
+ /* set iv if the mode is CBC */
+ if (mode == AES_MODE_CBC) {
+ if (endian == AES_ENDIAN_BIG) {
+ for (i = 0; i < 4; i++) {
+ aes_reg->iv[i] = *(uint32_t *)iv;
+ iv += 4;
+ }
+ } else if (endian == AES_ENDIAN_LITTLE) {
+ for (i = 0; i < 4; i++) {
+ aes_reg->iv[3 - i] = *(uint32_t *)iv;
+ iv += 4;
+ }
+ }
+ }
+
+ uint32_t j = 0;
+ /* set the text before aes calculating */
+ for (i = 0; i < len; i = i + 16) {
+ for (j = 0; j < 4; j++) {
+ if (endian == AES_ENDIAN_BIG) {
+ aes_reg->datain[j] = *(uint32_t *)in;
+ } else if (endian == AES_ENDIAN_LITTLE) {
+ aes_reg->datain[3 - j] = *(uint32_t *)in;
+ }
+
+ in += 4;
+ }
+
+ aes_enable();
+ }
+
+ return 0;
+}
+
+void ck_aes_irqhandler(int32_t idx)
+{
+ ck_aes_priv_t *aes_priv = &aes_handle[idx];
+
+ volatile uint32_t j;
+ uint32_t tmp = 0;
+ /* get the result after aes calculating*/
+ if (aes_priv->result_out != NULL) {
+ for (j = 0; j < 4; j++) {
+ if (aes_priv->endian == AES_ENDIAN_BIG) {
+ tmp = aes_reg->dataout[j];
+ } else if (aes_priv->endian == AES_ENDIAN_LITTLE) {
+ tmp = aes_reg->dataout[3 - j];
+ }
+
+ *(uint32_t *)aes_priv->result_out = tmp;
+ aes_priv->result_out += 4;
+ aes_priv->len -= 4;
+ }
+ }
+
+ /* disable aes and clear the aes interrupt */
+ aes_disable();
+ aes_clear_interrupt();
+
+ /* execute the callback function */
+ if (aes_priv->len == 0) {
+ if (aes_priv->cb) {
+ aes_priv->cb(AES_EVENT_CRYPTO_COMPLETE);
+ }
+ }
+}
+
+
+int32_t __attribute__((weak)) target_get_aes_count(void)
+{
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq)
+{
+ return NULL;
+}
+
+/**
+ \brief get aes instance count.
+ \return aes handle count
+*/
+int32_t csi_aes_get_instance_count(void)
+{
+ return target_get_aes_count();
+}
+
+/**
+ \brief Initialize AES Interface. 1. Initializes the resources needed for the AES interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_aes_get_instance_count().
+ \param[in] cb_event Pointer to \ref aes_event_cb_t
+ \return return aes handle if success
+*/
+aes_handle_t csi_aes_initialize(int32_t idx, aes_event_cb_t cb_event)
+{
+
+ if (idx < 0 || idx >= CONFIG_AES_NUM) {
+ return NULL;
+ }
+
+ uint32_t irq = 0u;
+ uint32_t base = 0u;
+ /* obtain the aes information */
+ int32_t real_idx = target_get_aes(idx, &base, &irq);
+
+ if (real_idx != idx) {
+ return NULL;
+ }
+
+ ck_aes_priv_t *aes_priv = &aes_handle[idx];
+
+ aes_priv->base = base;
+ aes_priv->irq = irq;
+
+ /* initialize the aes context */
+ aes_reg = (ck_aes_reg_t *)(aes_priv->base);
+ aes_priv->cb = cb_event;
+ aes_priv->iv = NULL;
+ aes_priv->len = 16;
+ aes_priv->result_out = NULL;
+ aes_priv->mode = AES_MODE_CBC;
+ aes_priv->keylen = AES_KEY_LEN_BITS_128;
+ aes_priv->endian = AES_ENDIAN_LITTLE;
+ aes_priv->status.busy = 0;
+
+ aes_enable_interrupt(); /* enable the aes interrupt */
+
+ drv_nvic_enable_irq(aes_priv->irq); /* enable the aes bit in nvic */
+
+ return (aes_handle_t)aes_priv;
+}
+
+/**
+ \brief De-initialize AES Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle aes handle to operate.
+ \return error code
+*/
+int32_t csi_aes_uninitialize(aes_handle_t handle)
+{
+ AES_NULL_PARA_CHK(handle);
+
+ ck_aes_priv_t *aes_priv = handle;
+ aes_priv->cb = NULL;
+
+ aes_disable_interrupt(); /* disable the aes interrupt */
+
+ drv_nvic_disable_irq(aes_priv->irq);
+
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle aes handle to operate.
+ \return \ref aes_capabilities_t
+*/
+aes_capabilities_t csi_aes_get_capabilities(aes_handle_t handle)
+{
+ return driver_capabilities;
+}
+
+/**
+ \brief config aes mode.
+ \param[in] handle aes handle to operate.
+ \param[in] mode \ref aes_mode_e
+ \param[in] keylen_bits \ref aes_key_len_bits_e
+ \param[in] endian \ref aes_endian_mode_e
+ \param[in] arg Pointer to the iv address when mode is cbc_mode
+ \return error code
+*/
+int32_t csi_aes_config(aes_handle_t handle, aes_mode_e mode, aes_key_len_bits_e keylen_bits, aes_endian_mode_e endian, uint32_t arg)
+{
+ AES_NULL_PARA_CHK(handle);
+
+ ck_aes_priv_t *aes_priv = handle;
+ aes_reg = (ck_aes_reg_t *)(aes_priv->base);
+
+ /* config the aes mode */
+ switch (mode) {
+ case AES_MODE_CBC:
+ aes_priv->iv = (void *)arg;
+ aes_priv->mode = mode;
+ aes_set_mode(mode);
+ break;
+
+ case AES_MODE_ECB:
+ aes_priv->mode = mode;
+ aes_set_mode(mode);
+ break;
+
+ case AES_MODE_CFB:
+ case AES_MODE_OFB:
+ case AES_MODE_CTR:
+ return ERR_AES(EDRV_UNSUPPORTED);
+
+ default:
+ return ERR_AES(EDRV_PARAMETER);
+ }
+
+ /* config the key length */
+ switch (keylen_bits) {
+ case AES_KEY_LEN_BITS_128:
+ case AES_KEY_LEN_BITS_192:
+ case AES_KEY_LEN_BITS_256:
+ aes_priv->keylen = keylen_bits;
+ aes_set_keylen(keylen_bits);
+ break;
+
+ default:
+ return ERR_AES(EDRV_PARAMETER);
+ }
+
+ /* config the endian mode */
+ switch (endian) {
+ case AES_ENDIAN_LITTLE:
+ aes_priv->endian = endian;
+ aes_set_endian(endian);
+ break;
+
+ case AES_ENDIAN_BIG:
+ aes_priv->endian = endian;
+ aes_set_endian(endian);
+ break;
+
+ default:
+ return ERR_AES(EDRV_PARAMETER);
+ }
+
+ return 0;
+}
+
+/**
+ \brief set crypto key.
+ \param[in] handle aes handle to operate.
+ \param[in] context aes information context(NULL when hardware implementation)
+ \param[in] key Pointer to the key buf
+ \param[in] key_len the key len
+ \param[in] enc \ref aes_crypto_mode_e
+ \return error code
+*/
+int32_t csi_aes_set_key(aes_handle_t handle, void *context, void *key, uint32_t key_len, aes_crypto_mode_e enc)
+{
+ AES_NULL_PARA_CHK(handle);
+ AES_NULL_PARA_CHK(key);
+ if ((key_len != AES_KEY_LEN_BITS_128 &&
+ key_len != AES_KEY_LEN_BITS_192 &&
+ key_len != AES_KEY_LEN_BITS_256) ||
+ (enc != AES_CRYPTO_MODE_ENCRYPT &&
+ enc != AES_CRYPTO_MODE_DECRYPT)) {
+ return ERR_AES(EDRV_PARAMETER);
+ }
+
+ ck_aes_priv_t *aes_priv = handle;
+ aes_set_key(context, key, key_len, enc, aes_priv->endian);
+
+ return 0;
+}
+
+/**
+ \brief encrypt or decrypt
+ \param[in] handle aes handle to operate.
+ \param[in] context aes information context(NULL when hardware implementation)
+ \param[in] in Pointer to the Source data
+ \param[out] out Pointer to the Result data.
+ \param[in] len the Source data len.
+ \param[in] padding \ref aes_padding_mode_e.
+ \return error code
+*/
+int32_t csi_aes_crypto(aes_handle_t handle, void *context, void *in, void *out, uint32_t len, aes_padding_mode_e padding)
+{
+ AES_NULL_PARA_CHK(handle);
+ AES_NULL_PARA_CHK(in);
+ AES_NULL_PARA_CHK(out);
+ AES_NULL_PARA_CHK(len);
+
+ ck_aes_priv_t *aes_priv = handle;
+
+ aes_priv->status.busy = 1;
+
+ uint8_t left_len = len & 0xf;
+ switch (padding) {
+ case AES_PADDING_MODE_NO:
+ if (left_len) {
+ return ERR_AES(EDRV_PARAMETER);
+ }
+
+ /* crypto in padding no mode */
+ aes_priv->result_out = out;
+ aes_priv->len = len;
+ aes_crypto(context, in, out, len, aes_priv->iv, aes_priv->mode, aes_priv->endian);
+ break;
+
+ case AES_PADDING_MODE_ZERO:
+ if (left_len == 0) {
+ return ERR_AES(EDRV_PARAMETER);
+ }
+
+ uint8_t i = 0;
+ for (i = 0; i < (16 - left_len); i++) {
+ *((uint8_t *)in + len + i) = 0x0;
+ }
+
+ /* crypto in padding zero mode */
+ aes_priv->result_out = out;
+ aes_priv->len = len + 16 -left_len;
+ aes_crypto(context, in, out, len + 16 - left_len, aes_priv->iv, aes_priv->mode, aes_priv->endian);
+ break;
+
+ case AES_PADDING_MODE_PKCS5:
+ return ERR_AES(EDRV_UNSUPPORTED);
+
+ default:
+ return ERR_AES(EDRV_PARAMETER);
+ }
+
+ aes_priv->status.busy = 0;
+ return 0;
+}
+
+/**
+ \brief Get AES status.
+ \param[in] handle aes handle to operate.
+ \return AES status \ref aes_status_t
+*/
+aes_status_t csi_aes_get_status(aes_handle_t handle)
+{
+ ck_aes_priv_t *aes_priv = handle;
+ return aes_priv->status;
+}
diff --git a/bsp/ck802/libraries/common/aes/ck_aes.h b/bsp/ck802/libraries/common/aes/ck_aes.h
new file mode 100644
index 0000000000..976ccad61c
--- /dev/null
+++ b/bsp/ck802/libraries/common/aes/ck_aes.h
@@ -0,0 +1,54 @@
+/*
+ * 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 ck_aes.h
+ * @brief header file for aes driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CK_AES_H_
+#define _CK_AES_H_
+
+#include <stdio.h>
+#include "drv_aes.h"
+#include "soc.h"
+
+#define AES_LITTLE_ENDIAN 0x00000100
+
+#define AES_MAX_KEY_LENGTH 32
+#define AES_IT_DATAINT 0x4
+#define AES_IT_KEYINT 0x2
+#define AES_IT_BUSY 0x1
+#define AES_IT_ALL 0x7
+#define AES_CRYPTO_KEYEXP 0x2
+
+#define AES_WORK_ENABLE_OFFSET 0
+#define AES_INT_ENABLE_OFFSET 2
+#define AES_MODE_OFFSET 3
+#define AES_KEY_LEN_OFFSET 4
+#define AES_OPCODE_OFFSET 6
+
+typedef struct {
+ __IOM uint32_t datain[4]; /* Offset: 0x000 (R/W) Data input 0~127 */
+ __IOM uint32_t key[8]; /* Offset: 0x010 (R/W) Key 0~255 */
+ __IOM uint32_t iv[4]; /* Offset: 0x030 (R/W) Initial Vector: 0~127 */
+ __IOM uint32_t ctrl; /* Offset: 0x040 (R/W) AES Control Register */
+ __IOM uint32_t state; /* Offset: 0x044 (R/W) AES State Register */
+ __IOM uint32_t dataout[4]; /* Offset: 0x048 (R/W) Data Output 0~31 */
+} ck_aes_reg_t;
+
+#endif
diff --git a/bsp/ck802/libraries/common/crc/ck_crc.c b/bsp/ck802/libraries/common/crc/ck_crc.c
new file mode 100644
index 0000000000..27354a0d5f
--- /dev/null
+++ b/bsp/ck802/libraries/common/crc/ck_crc.c
@@ -0,0 +1,277 @@
+/*
+ * 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 ck_crc.c
+ * @brief CSI Source File for CRC Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <stdio.h>
+#include "drv_crc.h"
+#include "ck_crc.h"
+
+#define ERR_CRC(errno) (CSI_DRV_ERRNO_CRC_BASE | errno)
+#define CRC_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_CRC(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+typedef struct {
+ uint32_t base;
+ crc_event_cb_t cb;
+ crc_status_t status;
+} ck_crc_priv_t;
+
+
+static ck_crc_priv_t crc_handle[CONFIG_CRC_NUM];
+/* Driver Capabilities */
+static const crc_capabilities_t driver_capabilities = {
+ .ROHC = 1, /* ROHC mode */
+ .MAXIM = 1, /* MAXIM mode */
+ .X25 = 1, /* X25 mode */
+ .CCITT = 1, /* CCITT mode */
+ .USB = 1, /* USB mode */
+ .IBM = 1, /* IBM mode */
+ .MODBUS = 1 /* MODBUS mode */
+};
+
+//
+// Functions
+//
+
+static ck_crc_reg_t *crc_reg = NULL;
+
+static int32_t crc_set_mode(crc_mode_e mode, crc_standard_crc_e standard)
+{
+ if (mode == CRC_MODE_CRC16) {
+ switch (standard) {
+ case CRC_STANDARD_CRC_MODBUS:
+ crc_reg->CRC_SEL = 0x0;
+ crc_reg->CRC_INIT = 0xffff;
+ break;
+
+ case CRC_STANDARD_CRC_IBM:
+ crc_reg->CRC_SEL = 0x0;
+ crc_reg->CRC_INIT = 0x0;
+ break;
+
+ case CRC_STANDARD_CRC_MAXIM:
+ crc_reg->CRC_SEL = 0x4;
+ crc_reg->CRC_INIT = 0x0;
+ break;
+
+ case CRC_STANDARD_CRC_USB:
+ crc_reg->CRC_SEL = 0x4;
+ crc_reg->CRC_INIT = 0xffff;
+ break;
+
+ case CRC_STANDARD_CRC_CCITT:
+ crc_reg->CRC_SEL = 0x1;
+ crc_reg->CRC_INIT = 0x0;
+ break;
+
+ case CRC_STANDARD_CRC_X25:
+ crc_reg->CRC_SEL = 0x5;
+ crc_reg->CRC_INIT = 0xffff;
+ break;
+
+ default:
+ return ERR_CRC(EDRV_PARAMETER);
+ }
+ } else if (mode == CRC_MODE_CRC8) {
+ switch (standard) {
+ case CRC_STANDARD_CRC_MAXIM:
+ crc_reg->CRC_SEL = 0x2;
+ crc_reg->CRC_INIT = 0x0;
+ break;
+
+ case CRC_STANDARD_CRC_ROHC:
+ crc_reg->CRC_SEL = 0x3;
+ crc_reg->CRC_INIT = 0xff;
+ break;
+
+ default:
+ return ERR_CRC(EDRV_PARAMETER);
+ }
+ } else {
+ return ERR_CRC(EDRV_PARAMETER);
+ }
+
+ return 0;
+}
+
+static int32_t crc_set_data(uint32_t data)
+{
+ crc_reg->CRC_DATA = data;
+ return 0;
+}
+
+static int32_t crc_get_data(uint32_t *data)
+{
+ *data = crc_reg->CRC_DATA;
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_crc_count(void)
+{
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_crc(int32_t idx, uint32_t *base)
+{
+ return NULL;
+}
+
+/**
+ \brief get crc handle count.
+ \return crc handle count
+*/
+int32_t csi_crc_get_instance_count(void)
+{
+ return target_get_crc_count();
+}
+
+/**
+ \brief Initialize CRC Interface. 1. Initializes the resources needed for the CRC interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_crc_get_handle_count()
+ \param[in] cb_event Pointer to \ref crc_event_cb_t
+ \return return crc handle if success
+*/
+crc_handle_t csi_crc_initialize(int32_t idx, crc_event_cb_t cb_event)
+{
+ if (idx < 0 || idx >= CONFIG_CRC_NUM) {
+ return NULL;
+ }
+
+ /* obtain the crc information */
+ uint32_t base = 0u;
+ int32_t real_idx = target_get_crc(idx, &base);
+
+ if (real_idx != idx) {
+ return NULL;
+ }
+
+ ck_crc_priv_t *crc_priv = &crc_handle[idx];
+ crc_reg = (ck_crc_reg_t *)(crc_priv->base);
+
+ crc_priv->base = base;
+ crc_priv->cb = cb_event;
+ crc_priv->status.busy = 0;
+
+ return (crc_handle_t)crc_priv;
+}
+
+/**
+ \brief De-initialize CRC Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle crc handle to operate.
+ \return error code
+*/
+int32_t csi_crc_uninitialize(crc_handle_t handle)
+{
+ CRC_NULL_PARAM_CHK(handle);
+
+ ck_crc_priv_t *crc_priv = handle;
+ crc_priv->cb = NULL;
+
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle crc handle to operate.
+ \return \ref crc_capabilities_t
+*/
+crc_capabilities_t csi_crc_get_capabilities(crc_handle_t handle)
+{
+ return driver_capabilities;
+}
+
+/**
+ \brief config crc mode.
+ \param[in] handle crc handle to operate.
+ \param[in] mode \ref crc_mode_e
+ \param[in] standard \ref crc_standard_crc_e
+ \return error code
+*/
+int32_t csi_crc_config(crc_handle_t handle, crc_mode_e mode, crc_standard_crc_e standard)
+{
+ CRC_NULL_PARAM_CHK(handle);
+
+ /* set the crc mode */
+ uint32_t ret = crc_set_mode(mode, standard);
+
+ return ret;
+}
+
+/**
+ \brief calculate crc.
+ \param[in] handle crc handle to operate.
+ \param[in] in Pointer to the input data
+ \param[out] out Pointer to the result.
+ \param[in] len intpu data len.
+ \return error code
+*/
+int32_t csi_crc_calculate(crc_handle_t handle, const void *in, void *out, uint32_t len)
+{
+ CRC_NULL_PARAM_CHK(handle);
+ CRC_NULL_PARAM_CHK(in);
+ CRC_NULL_PARAM_CHK(out);
+ if (len <= 0) {
+ return ERR_CRC(EDRV_PARAMETER);
+ }
+
+ ck_crc_priv_t *crc_priv = handle;
+ crc_reg = (ck_crc_reg_t *)(crc_priv->base);
+
+ crc_priv->status.busy = 1;
+
+ /* put the data int the register */
+ uint8_t cur;
+ uint8_t *p = (uint8_t *)in;
+ for (cur=0; cur<len - 3; cur += 4, p+=4) {
+ crc_set_data(p[0]
+ | (p[1] << 8)
+ | (p[2] << 16)
+ | (p[3] << 24));
+ }
+ uint32_t data = 0;
+ uint8_t i;
+ if (cur < len) {
+ for (i=0; i<len-cur; i++) {
+ data |= (p[cur + i] << (i*8));
+ }
+ crc_set_data(data);
+ }
+
+ crc_get_data((uint32_t *)out);
+ crc_priv->status.busy = 0;
+
+ return 0;
+}
+
+/**
+ \brief Get CRC status.
+ \param[in] handle crc handle to operate.
+ \return CRC status \ref crc_status_t
+*/
+crc_status_t csi_crc_get_status(crc_handle_t handle)
+{
+ ck_crc_priv_t *crc_priv = handle;
+ return crc_priv->status;
+}
diff --git a/bsp/ck802/libraries/common/crc/ck_crc.h b/bsp/ck802/libraries/common/crc/ck_crc.h
new file mode 100644
index 0000000000..16b389fa8c
--- /dev/null
+++ b/bsp/ck802/libraries/common/crc/ck_crc.h
@@ -0,0 +1,34 @@
+/*
+ * 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 ck_crc.h
+ * @brief header file for crc driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CK_CRC_H_
+#define _CK_CRC_H_
+
+#include "stdint.h"
+#include "soc.h"
+
+typedef struct {
+ __IOM uint32_t CRC_DATA; /* Offset: 0x000 (W/R) data register */
+ __IOM uint32_t CRC_SEL; /* Offset: 0x004 (W/R) mode select register for CRC */
+ __OM uint32_t CRC_INIT; /* Offset: 0x008 (W) initial value register */
+
+} ck_crc_reg_t;
+#endif
diff --git a/bsp/ck802/libraries/common/dmac/ck_dmac.c b/bsp/ck802/libraries/common/dmac/ck_dmac.c
new file mode 100644
index 0000000000..60cbb0c383
--- /dev/null
+++ b/bsp/ck802/libraries/common/dmac/ck_dmac.c
@@ -0,0 +1,517 @@
+/*
+ * 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 ck_dmac.c
+* @brief CSI Source File for DMAC Driver
+* @version V1.0
+* @date 02. June 2017
+******************************************************************************/
+#include <stdbool.h>
+#include "ck_dmac.h"
+#include "csi_core.h"
+#include "drv_dmac.h"
+#include "soc.h"
+
+#define ERR_DMA(errno) (CSI_DRV_ERRNO_DMA_BASE | errno)
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ dma_event_cb_t cb_event;
+ uint8_t ch_num;
+} ck_dma_priv_t;
+
+static ck_dma_priv_t dma_instance[CONFIG_DMAC_NUM];
+
+static const dma_capabilities_t dma_capabilities = {
+ .unalign_addr = 1, ///< support for unalign address transfer when memory is source
+};
+
+static volatile dma_status_e status[CK_DMA_MAXCHANNEL] = {DMA_STATE_FREE, DMA_STATE_FREE};
+static volatile uint8_t ch_opened[CK_DMA_MAXCHANNEL] = {0, 0};
+
+static int32_t ck_dma_set_channel(ck_dma_reg_t *addr, uint32_t source, uint32_t dest, uint32_t size)
+{
+ uint32_t temp = addr->CHCTRLA;
+ temp &= 0xff000fff;
+ temp |= (size << 12);
+ addr->SAR = source;
+ addr->DAR = dest ;
+ addr->CHCTRLA = temp;
+
+ return 0;
+}
+
+static int32_t ck_dma_set_transfertype(ck_dma_reg_t *addr, dma_trans_type_e transtype)
+{
+ uint32_t temp = addr->CHCTRLB;
+ temp &= 0xffffff7f;
+
+ if (transtype >= DMA_PERH2PERH) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ if (transtype == DMA_MEM2MEM) {
+ temp |= (transtype << 7);
+ } else {
+ temp |= (1 << 7);
+ }
+
+ addr->CHCTRLB = temp;
+
+ return 0;
+}
+
+static int32_t ck_dma_set_addrinc(ck_dma_reg_t *addr, enum_addr_state_e src_addrinc, enum_addr_state_e dst_addrinc)
+{
+ if ((src_addrinc != DMA_ADDR_INCREMENT && src_addrinc != DMA_ADDR_DECREMENT && src_addrinc != DMA_ADDR_NOCHANGE) ||
+ (dst_addrinc != DMA_ADDR_INCREMENT && dst_addrinc != DMA_ADDR_DECREMENT && dst_addrinc != DMA_ADDR_NOCHANGE)) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ uint32_t temp = addr->CHCTRLA;
+ temp &= 0xffffff0f;
+ temp |= (src_addrinc << 6);
+ temp |= (dst_addrinc << 4);
+ addr->CHCTRLA = temp;
+
+ return 0;
+}
+
+static int32_t ck_dma_set_transferwidth(ck_dma_reg_t *addr, dma_datawidth_e src_width, dma_datawidth_e dst_width)
+{
+ if ((src_width != DMA_DATAWIDTH_SIZE8 && src_width != DMA_DATAWIDTH_SIZE16 && src_width != DMA_DATAWIDTH_SIZE32) ||
+ (dst_width != DMA_DATAWIDTH_SIZE8 && dst_width != DMA_DATAWIDTH_SIZE16 && dst_width != DMA_DATAWIDTH_SIZE32)) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ uint32_t temp = addr->CHCTRLA;
+ temp &= 0xfffffff0;
+ temp |= (src_width - 1) << 2;
+ temp |= dst_width - 1;
+ addr->CHCTRLA = temp;
+
+ return 0;
+}
+
+static int32_t ck_dma_set_burstlength(ck_dma_reg_t *addr, uint8_t burstlength)
+{
+ uint32_t temp = addr->CHCTRLA;
+ temp &= 0xfffff0ff;
+ temp |= (burstlength << 8);
+ addr->CHCTRLA = temp;
+
+ return 0;
+
+}
+
+/**
+ \brief Set software or hardware handshaking.
+ \param[in] addr pointer to dma register.
+ \return error code
+*/
+static int32_t ck_dma_set_handshaking(ck_dma_reg_t *addr, dma_handshaking_select_e handshaking)
+{
+ uint32_t temp = addr->CHCTRLB;
+ temp &= 0xfffffeff;
+ temp |= (handshaking << 8);
+ addr->CHCTRLB = temp;
+
+ return 0;
+}
+
+static int ck_dma_assign_hdhs_interface(ck_dma_reg_t *addr, ckenum_dma_device_e device)
+{
+ if (device < 0 || device >= CKENUM_DMA_MEMORY) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ addr->CHCTRLB &= 0xffffe1ff;
+ addr->CHCTRLB |= (device << 9);
+
+ return 0;
+}
+
+
+void ck_dma_irqhandler(int32_t idx)
+{
+ ck_dma_priv_t *dma_priv = &dma_instance[idx];
+ ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base);
+
+ /*
+ * StatusInt_temp contain the information that which types of interrupr are
+ * requested.
+ */
+ int32_t count = 0;
+ uint32_t temp = 0;
+
+ for (count = 0; count < dma_priv->ch_num; count++) {
+ addr = (ck_dma_reg_t *)(dma_priv->base + count * 0x30);
+
+ temp = addr->CHINTS;
+
+ if (temp != 0) {
+ break;
+ }
+ }
+
+ /* If Tfr interrupt is requested */
+ if (temp == CK_DMA_TFR) {
+ status[count] = DMA_STATE_DONE;
+ addr->CHINTC = temp;
+
+ if (dma_priv->cb_event) {
+ dma_priv->cb_event(DMA_EVENT_TRANSFER_DONE, count);
+ }
+ }
+
+ /* If Err interrput is requested */
+ if (temp == CK_DMA_ERR) {
+ status[count] = DMA_STATE_ERROR;
+ addr->CHINTC = temp;
+
+ if (dma_priv->cb_event) {
+ dma_priv->cb_event(DMA_EVENT_TRANSFER_ERROR, count);
+ }
+ }
+}
+
+int32_t __attribute__((weak)) target_get_dmac_count(void)
+{
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_dmac(uint32_t idx, uint32_t *base, uint32_t *irq)
+{
+ return NULL;
+}
+
+/**
+ \brief get dma instance count.
+ \return dma instance count
+*/
+int32_t csi_dma_get_instance_count(void)
+{
+ return target_get_dmac_count();
+}
+
+/**
+ \brief Initialize DMA Interface. 1. Initializes the resources needed for the DMA interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_dma_get_instance_count()
+ \return pointer to dma instances
+*/
+dmac_handle_t csi_dma_initialize(int32_t idx)
+{
+
+ if (idx < 0 || idx >= CONFIG_DMAC_NUM) {
+ return NULL;
+ }
+
+ uint32_t base = 0u;
+ uint32_t irq = 0u;
+
+ int32_t real_idx = target_get_dmac(idx, &base, &irq);
+
+ if (real_idx != idx) {
+ return NULL;
+ }
+
+ ck_dma_priv_t *dma_priv = &dma_instance[idx];
+
+ dma_priv->base = base;
+ dma_priv->irq = irq;
+ dma_priv->ch_num = CK_DMA_MAXCHANNEL;
+ drv_nvic_enable_irq(dma_priv->irq);
+ uint8_t count = 0u;
+
+ for (count = 0; count < dma_priv->ch_num; count++) {
+ ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base + count * 0x30);
+ addr->CHINTM = CK_DMA_MASK;
+ addr->CHINTC = CK_DMA_INTC;
+ }
+
+ return (dmac_handle_t)dma_priv;
+}
+
+/**
+ \brief De-initialize DMA Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle damc handle to operate.
+ \return error code
+*/
+int32_t csi_dma_uninitialize(dmac_handle_t handle)
+{
+ if (handle == NULL) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ ck_dma_priv_t *dma_priv = handle;
+ ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base);
+
+ uint8_t count;
+
+ for (count = 0; count < dma_priv->ch_num; count++) {
+ addr = (ck_dma_reg_t *)(dma_priv->base + count * 0x30);
+ addr->CHINTM = CK_DMA_MASK;
+ addr->CHINTC = CK_DMA_INTC;
+ }
+
+ drv_nvic_disable_irq(dma_priv->irq);
+
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle damc handle to operate.
+ \return \ref dma_capabilities_t
+*/
+dma_capabilities_t csi_dma_get_capabilities(dmac_handle_t handle)
+{
+ return dma_capabilities;
+}
+
+/**
+ \brief get one free dma channel
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num. if -1 then allocate a free channal in this dma
+ \return -1 - no channel can be used, other - channel index
+ */
+int32_t csi_dma_alloc_channel(dmac_handle_t handle, int32_t ch)
+{
+ ck_dma_priv_t *dma_priv = handle;
+
+ if (handle == NULL || ch > dma_priv->ch_num) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ uint8_t ch_num = 0;
+ ck_dma_reg_t *addr = NULL;
+
+ if (ch == -1) { // alloc a free channal
+ for (ch_num = 0; ch_num < dma_priv->ch_num; ch_num++) {
+ addr = (ck_dma_reg_t *)(dma_priv->base + ch_num * 0x30);
+
+ if (ch_opened[ch_num] != 0x1) {
+ ch_opened[ch_num] = 1;
+ break;
+ }
+ }
+
+ if (ch_num >= dma_priv->ch_num) {
+ return -1;
+ }
+ } else { //alloc a fixed channel
+ addr = (ck_dma_reg_t *)(dma_priv->base + ch * 0x30);
+
+ if (ch_opened[ch] == 0x1) {
+ return ERR_DMA(EDRV_BUSY);
+ }
+
+ ch_opened[ch] = 1;
+ ch_num = ch;
+ }
+
+ addr->CHINTC = CK_DMA_INTC;
+ addr->CHINTM &= ~CK_DMA_MASK;
+ status[ch_num] = DMA_STATE_READY;
+
+ return ch_num;
+}
+
+/**
+ \brief release dma channel and related resources
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num.
+ \return error code
+ */
+int32_t csi_dma_release_channel(dmac_handle_t handle, int32_t ch)
+{
+ ck_dma_priv_t *dma_priv = handle;
+
+ if (handle == NULL || ch >= dma_priv->ch_num || ch < 0) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base + ch * 0x30);
+ status[ch] = DMA_STATE_FREE;
+ ch_opened[ch] = 0;
+
+ addr->CHINTC = CK_DMA_INTC;
+ addr->CHINTM = CK_DMA_MASK;
+ return 0;
+}
+
+/**
+ \brief
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num. if -1 then allocate a free channal in this dma
+ \param[in] psrcaddr dma transfer source address
+ \param[in] pstdaddr dma transfer source address
+ \param[in] length dma transfer length
+ \param[in] config dma transfer configure
+ \param[in] cb_event Pointer to \ref dma_event_cb_t
+ \return error code
+ */
+int32_t csi_dma_config(dmac_handle_t handle, int32_t ch,
+ void *psrcaddr, void *pstdaddr,
+ uint32_t length, dma_config_t *config, dma_event_cb_t cb_event)
+{
+ ck_dma_priv_t *dma_priv = handle;
+
+ if (handle == NULL || ch >= dma_priv->ch_num || config == NULL) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ if (ch == -1) { //alloc a free channel
+ ch = csi_dma_alloc_channel(handle, -1);
+
+ if (ch < 0) {
+ return ERR_DMA(EDRV_BUSY);
+ }
+ }
+
+ dma_priv->cb_event = cb_event;
+
+ ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base + ch * 0x30);
+
+ /* Initializes corresponding channel registers */
+
+ if ((length * config->src_tw) % config->dst_tw != 0) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ int32_t ret = ck_dma_set_transferwidth(addr, config->src_tw, config->dst_tw);
+
+ if (ret) {
+ return ret;
+ }
+
+ int32_t grouplen = ((length * config->src_tw / config->dst_tw) - 1) % 16;
+ ck_dma_set_burstlength(addr, grouplen);
+
+ ret = ck_dma_set_transfertype(addr, config->type);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (config->type == DMA_MEM2MEM) {
+ ck_dma_set_handshaking(addr, DMA_HANDSHAKING_SOFTWARE);
+ ret = ck_dma_set_addrinc(addr , config->src_inc, config->dst_inc);
+ } else if (config->type == DMA_MEM2PERH) {
+ ck_dma_set_handshaking(addr, DMA_HANDSHAKING_HARDWARE);
+ ret = ck_dma_set_addrinc(addr , config->src_inc, config->dst_inc);
+
+ if (ret) {
+ return ret;
+ }
+
+ ret = ck_dma_assign_hdhs_interface(addr, config->hs_if);
+
+ if (ret) {
+ return ret;
+ }
+
+ } else if (config->type == DMA_PERH2MEM) {
+ ck_dma_set_handshaking(addr, DMA_HANDSHAKING_HARDWARE);
+ ret = ck_dma_set_addrinc(addr , config->src_inc, config->dst_inc);
+
+ if (ret) {
+ return ret;
+ }
+
+ ret = ck_dma_assign_hdhs_interface(addr, config->hs_if);
+
+ if (ret) {
+ return ret;
+ }
+ }
+
+ ck_dma_set_channel(addr, (uint32_t)psrcaddr, (uint32_t)pstdaddr, length);
+ status[ch] = DMA_STATE_READY;
+
+ return 0;
+}
+
+/**
+ \brief start generate dma signal.
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num.
+ \return error code
+*/
+int32_t csi_dma_start(dmac_handle_t handle, int32_t ch)
+{
+ ck_dma_priv_t *dma_priv = handle;
+
+ if (handle == NULL || ch >= dma_priv->ch_num || ch < 0) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ status[ch] = DMA_STATE_BUSY;
+ ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base + ch * 0x30);
+ addr->CHCTRLB |= CK_DMA_INT_EN; // interrupt enable
+ addr->CHEN |= CK_DMA_CH_EN;
+
+ return 0;
+}
+
+/**
+ \brief Stop generate dma signal.
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num.
+ \return error code
+*/
+int32_t csi_dma_stop(dmac_handle_t handle, int32_t ch)
+{
+ if (handle == NULL) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ ck_dma_priv_t *dma_priv = handle;
+
+ if (ch >= dma_priv->ch_num || ch < 0) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ status[ch] = DMA_STATE_DONE;
+
+ ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base + ch * 0x30);
+ addr->CHCTRLB &= ~CK_DMA_INT_EN; // interrupt disable
+ addr->CHEN &= ~CK_DMA_CH_EN;
+ return 0;
+}
+
+/**
+ \brief Get DMA status.
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num.
+ \return DMA status \ref dma_status_t
+*/
+dma_status_e csi_dma_get_status(dmac_handle_t handle, int32_t ch)
+{
+ if (handle == NULL) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ ck_dma_priv_t *dma_priv = handle;
+
+ if (ch >= dma_priv->ch_num || ch < 0) {
+ return ERR_DMA(EDRV_PARAMETER);
+ }
+
+ return status[ch];
+}
+
diff --git a/bsp/ck802/libraries/common/dmac/ck_dmac.h b/bsp/ck802/libraries/common/dmac/ck_dmac.h
new file mode 100644
index 0000000000..e723219fef
--- /dev/null
+++ b/bsp/ck802/libraries/common/dmac/ck_dmac.h
@@ -0,0 +1,75 @@
+/*
+ * 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 ck_dmac.h
+* @brief header file for DMAC Driver
+* @version V1.0
+* @date 02. June 2017
+******************************************************************************/
+#ifndef __CK_DMA_H
+#define __CK_DMA_H
+#include <stdio.h>
+#include "soc.h"
+
+#define CK_DMA_MAXCHANNEL 2
+#define CK_DMA_INT_EN 1
+#define CK_DMA_CH_EN 1
+#define CK_DMA_TFR 0x0002
+#define CK_DMA_ERR 0x0001
+#define CK_DMA_INTC 0x03
+#define CK_DMA_MASK 0x03
+
+typedef enum {
+ DMA_ADDR_INCREMENT = 0,
+ DMA_ADDR_DECREMENT = 1,
+ DMA_ADDR_NOCHANGE = 2
+} enum_addr_state_e;
+
+typedef enum {
+ DMA_DATAWIDTH_SIZE8 = 1,
+ DMA_DATAWIDTH_SIZE16 = 2,
+ DMA_DATAWIDTH_SIZE32 = 4
+} dma_datawidth_e;
+
+typedef enum {
+ DMA_HANDSHAKING_HARDWARE = 0,
+ DMA_HANDSHAKING_SOFTWARE = 1,
+} dma_handshaking_select_e;
+
+typedef enum {
+ DMA_PRIORITY0 = 0,
+ DMA_PRIORITY1 = 1,
+ DMA_PRIOTITY2 = 2,
+ DMA_PRIOTITY3 = 3
+} dma_priority_t;
+
+typedef struct {
+ __IOM uint32_t SAR; /* offset: 0x00 (R/W) Channel Source Address Register */
+ __IOM uint32_t DAR; /* offset: 0x04 (R/W) Channel Destination Address Register */
+ __IOM uint32_t CHCTRLA; /* offset: 0x08 (R/W) Channel Control Register A */
+ __IOM uint32_t CHCTRLB; /* offset: 0x0C (R/W) Channel Control Register B */
+ __IOM uint8_t CHINTM:2; /* offset: 0x10 (R/W) Channel Interrupt Mask Register */
+ uint8_t RESERVED0[3];
+ __IM uint8_t CHINTS:2; /* offset: 0x14 (R/ ) Channel Interrupt Status Register */
+ uint8_t RESERVED1[3];
+ __IOM uint8_t CHINTC:2; /* offset: 0x18 (R/W) Channel Interrupt Clear Register */
+ uint8_t RESERVED2[3];
+ __IOM uint8_t CHSREQ:1; /* offset: 0x1C (R/W) Channel Software Request Register */
+ uint8_t RESERVED3[3];
+ __IOM uint8_t CHEN:1; /* offset: 0x20 (R/W) Channel Enable Register */
+ uint8_t RESERVED4[3];
+} ck_dma_reg_t;
+#endif /* __CK_DMA_H */
diff --git a/bsp/ck802/libraries/common/eflash/ck_eflash.c b/bsp/ck802/libraries/common/eflash/ck_eflash.c
new file mode 100644
index 0000000000..c203002aa0
--- /dev/null
+++ b/bsp/ck802/libraries/common/eflash/ck_eflash.c
@@ -0,0 +1,288 @@
+/*
+ * 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 ck_eflash.c
+ * @brief CSI Source File for Embedded Flash Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <stdio.h>
+#include "drv_eflash.h"
+#include "ck_eflash.h"
+
+
+#define ERR_EFLASH(errno) (CSI_DRV_ERRNO_EFLASH_BASE | errno)
+#define EFLASH_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_EFLASH(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+typedef struct {
+ uint32_t base;
+ eflash_info eflashinfo;
+ eflash_event_cb_t cb;
+ eflash_status_t status;
+} ck_eflash_priv_t;
+
+static ck_eflash_priv_t eflash_handle[CONFIG_EFLASH_NUM];
+/* Driver Capabilities */
+static const eflash_capabilities_t driver_capabilities = {
+ .event_ready = 1, /* event_ready */
+ .data_width = 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
+ .erase_chip = 0 /* erase_chip */
+};
+
+//
+// Functions
+//
+
+static int32_t eflash_program_word(eflash_handle_t handle, uint32_t dstaddr, uint32_t *srcbuf, uint32_t len)
+{
+ ck_eflash_priv_t *eflash_priv = handle;
+ uint32_t fbase = eflash_priv->base;
+ uint32_t i;
+
+ for (i = 0; i < len; i++) {
+ *(volatile uint32_t *)(fbase + 0x04) = dstaddr;
+ *(volatile uint32_t *)(fbase + 0x1c) = *srcbuf;
+ *(volatile uint32_t *)(fbase + 0x18) = 1;
+ srcbuf++;
+ dstaddr += 4;
+ }
+
+ return (i << 2);
+}
+
+int32_t __attribute__((weak)) target_get_eflash_count(void)
+{
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_eflash(int32_t idx, uint32_t *base, eflash_info *info)
+{
+ return NULL;
+}
+/**
+ \brief get eflash handle count.
+ \return eflash handle count
+*/
+int32_t csi_eflash_get_instance_count(void)
+{
+ return target_get_eflash_count();
+}
+
+/**
+ \brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_eflash_get_instance_count()
+ \param[in] cb_event Pointer to \ref eflash_event_cb_t
+ \return pointer to eflash handle
+*/
+eflash_handle_t csi_eflash_initialize(int32_t idx, eflash_event_cb_t cb_event)
+{
+ if (idx < 0 || idx >= CONFIG_EFLASH_NUM) {
+ return NULL;
+ }
+
+ /* obtain the eflash information */
+ uint32_t base = 0u;
+ eflash_info info;
+ int32_t real_idx = target_get_eflash(idx, &base, &info);
+
+ if (real_idx != idx) {
+ return NULL;
+ }
+
+ ck_eflash_priv_t *eflash_priv = &eflash_handle[idx];
+
+ eflash_priv->base = base;
+ eflash_priv->eflashinfo.start = info.start;
+ eflash_priv->eflashinfo.end = info.end;
+ eflash_priv->eflashinfo.sector_count = info.sector_count;
+
+ /* initialize the eflash context */
+ eflash_priv->cb = cb_event;
+ eflash_priv->status.busy = 0;
+ eflash_priv->status.error = 0U;
+ eflash_priv->eflashinfo.sector_size = EFLASH_SECTOR_SIZE;
+ eflash_priv->eflashinfo.page_size = EFLASH_PAGE_SIZE;
+ eflash_priv->eflashinfo.program_unit = EFLASH_PROGRAM_UINT;
+ eflash_priv->eflashinfo.erased_value = EFLASH_ERASED_VALUE;
+
+ return (eflash_handle_t)eflash_priv;
+}
+
+/**
+ \brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle eflash handle to operate.
+ \return error code
+*/
+int32_t csi_eflash_uninitialize(eflash_handle_t handle)
+{
+ EFLASH_NULL_PARAM_CHK(handle);
+
+ ck_eflash_priv_t *eflash_priv = handle;
+ eflash_priv->cb = NULL;
+
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] eflash handle to operate.
+ \return \ref eflash_capabilities_t
+*/
+eflash_capabilities_t csi_eflash_get_capabilities(eflash_handle_t handle)
+{
+ return driver_capabilities;
+}
+
+/**
+ \brief Read data from Flash.
+ \param[in] handle eflash handle to operate.
+ \param[in] addr Data address.
+ \param[out] data Pointer to a buffer storing the data read from Flash.
+ \param[in] cnt Number of data items to read.
+ \return number of data items read or error code
+*/
+int32_t csi_eflash_read(eflash_handle_t handle, uint32_t addr, void *data, uint32_t cnt)
+{
+ EFLASH_NULL_PARAM_CHK(handle);
+ EFLASH_NULL_PARAM_CHK(data);
+ EFLASH_NULL_PARAM_CHK(cnt);
+ if (!IS_EFLASH_ADDR(addr) || !(IS_EFLASH_ADDR(addr + cnt -1))) {
+ return ERR_EFLASH(EDRV_PARAMETER);
+ }
+
+ volatile uint8_t *src_addr = (uint8_t *)addr;
+ ck_eflash_priv_t *eflash_priv = handle;
+
+ if (eflash_priv->status.busy) {
+ return ERR_EFLASH(EDRV_BUSY);
+ }
+
+ eflash_priv->status.error = 0U;
+
+ int i;
+ for (i = 0; i < cnt; i++) {
+ *((uint8_t *)data + i) = *(src_addr + i);
+ }
+
+ return i;
+}
+
+/**
+ \brief Program data to Flash.
+ \param[in] handle eflash handle to operate.
+ \param[in] addr Data address.
+ \param[in] data Pointer to a buffer containing the data to be programmed to Flash..
+ \param[in] cnt Number of data items to program.
+ \return number of data items programmed or error code
+*/
+int32_t csi_eflash_program(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt)
+{
+ EFLASH_NULL_PARAM_CHK(handle);
+ EFLASH_NULL_PARAM_CHK(data);
+ EFLASH_NULL_PARAM_CHK(cnt);
+ if (!IS_EFLASH_ADDR(addr) || !(IS_EFLASH_ADDR(addr + cnt -1))) {
+ return ERR_EFLASH(EDRV_PARAMETER);
+ }
+
+ ck_eflash_priv_t *eflash_priv = handle;
+
+ if ((addr & 0x3) || ((uint32_t)data & 0x3) || (cnt & 0x3)) {
+ return ERR_EFLASH(EDRV_PARAMETER);
+ }
+
+ if (eflash_priv->status.busy) {
+ return ERR_EFLASH(EDRV_BUSY);
+ }
+
+ eflash_priv->status.busy = 1U;
+ eflash_priv->status.error = 0U;
+ uint32_t ret = eflash_program_word(handle, addr, (uint32_t *)data, cnt >> 2);
+ eflash_priv->status.busy = 0U;
+
+ return ret;
+}
+
+/**
+ \brief Erase Flash Sector.
+ \param[in] handle eflash handle to operate.
+ \param[in] addr Sector address
+ \return error code
+*/
+int32_t csi_eflash_erase_sector(eflash_handle_t handle, uint32_t addr)
+{
+ EFLASH_NULL_PARAM_CHK(handle);
+ if (!IS_EFLASH_ADDR(addr)) {
+ return ERR_EFLASH(EDRV_PARAMETER);
+ }
+
+ addr = addr & ~(EFLASH_SECTOR_SIZE - 1);
+ ck_eflash_priv_t *eflash_priv = handle;
+ uint32_t fbase = eflash_priv->base;
+
+ if (eflash_priv->status.busy) {
+ return ERR_EFLASH(EDRV_BUSY);
+ }
+
+ eflash_priv->status.busy = 1U;
+ eflash_priv->status.error = 0U;
+ *(volatile uint32_t *)(fbase + 0x4) = addr;
+ *(volatile uint32_t *)(fbase + 0x10) = 0x1;
+ eflash_priv->status.busy = 0U;
+
+ return 0;
+}
+
+/**
+ \brief Erase complete Flash.
+ \param[in] handle eflash handle to operate.
+ \return error code
+*/
+int32_t csi_eflash_erase_chip(eflash_handle_t handle)
+{
+ EFLASH_NULL_PARAM_CHK(handle);
+
+ return ERR_EFLASH(EDRV_UNSUPPORTED);
+}
+
+/**
+ \brief Get Flash information.
+ \param[in] handle eflash handle to operate.
+ \return Pointer to Flash information \ref eflash_info
+*/
+eflash_info *csi_eflash_get_info(eflash_handle_t handle)
+{
+ ck_eflash_priv_t *eflash_priv = handle;
+ eflash_info *eflash_info = &(eflash_priv->eflashinfo);
+
+ return eflash_info;
+}
+
+/**
+ \brief Get EFLASH status.
+ \param[in] handle eflash handle to operate.
+ \return EFLASH status \ref eflash_status_t
+*/
+eflash_status_t csi_eflash_get_status(eflash_handle_t handle)
+{
+ ck_eflash_priv_t *eflash_priv = handle;
+
+ return eflash_priv->status;
+}
diff --git a/bsp/ck802/libraries/common/eflash/ck_eflash.h b/bsp/ck802/libraries/common/eflash/ck_eflash.h
new file mode 100644
index 0000000000..b8d3ed393f
--- /dev/null
+++ b/bsp/ck802/libraries/common/eflash/ck_eflash.h
@@ -0,0 +1,38 @@
+/*
+ * 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 ck_eflash.h
+ * @brief head file for ck eflash
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CK_EFLASH_H_
+#define _CK_EFLASH_H_
+
+#include "drv_eflash.h"
+#include "soc.h"
+
+#define EFLASH_ADDR_START 0x10000000
+#define EFLASH_ADDR_END 0x1003f7ff
+#define EFLASH_SECTOR_SIZE 0x200
+#define EFLASH_ERASED_VALUE 0xff
+#define EFLASH_PROGRAM_UINT 0x4
+#define EFLASH_PAGE_SIZE 0
+#define BLOCK_SIZE 0x200
+#define IS_EFLASH_ADDR(addr) \
+ ((addr >= EFLASH_ADDR_START) && (addr <= EFLASH_ADDR_END))
+
+#endif
diff --git a/bsp/ck802/libraries/common/eth/ethernet_enc28j60.c b/bsp/ck802/libraries/common/eth/ethernet_enc28j60.c
new file mode 100644
index 0000000000..c8d7f8584d
--- /dev/null
+++ b/bsp/ck802/libraries/common/eth/ethernet_enc28j60.c
@@ -0,0 +1,1259 @@
+/*
+ * Copyright (C) 2016 YunOS Project. 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.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <syslog.h>
+#ifndef CONFIG_KERNEL_NONE
+#include <csi_kernel.h>
+#endif
+#include "ethernet_enc28j60.h"
+
+#include "pin.h"
+#include "soc.h"
+#include "drv_spi.h"
+#include "drv_gpio.h"
+#include "drv_eth.h"
+#include "drv_eth_phy.h"
+#include "drv_eth_mac.h"
+
+#include <errno.h>
+
+#define NET_HWADDR_LEN 6
+#define THIS_MODULE MODULE_DEV_ETH
+#define MAX_SPI_TRANSFER_LEN 512
+#define MAX_RECV_ERROR_CNT 50
+
+static uint8_t Enc28j60Bank;
+static uint16_t NextPacketPtr;
+gpio_pin_handle_t pin_int = NULL;
+
+typedef int (*gpio_interrupt_t)(int irqno);
+
+static spi_handle_t g_net_spi_hd = NULL;
+static gpio_pin_handle_t pgpio_pin_handle1;
+//static k_sem_handle_t g_sem_spi_tx_hd = NULL;
+//static k_sem_handle_t g_sem_spi_rx_hd = NULL;
+
+static eth_mac_priv_t s_eth_instance[CONFIG_ETH_NUM];
+static eth_phy_priv_t s_phy_instance[CONFIG_ETH_NUM];
+
+static uint8_t g_hw_addr[NET_HWADDR_LEN] = {0};
+
+static uint8_t enc28j60ReadOp(uint8_t op, uint8_t address);
+static void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data);
+static void enc28j60ReadBuffer(const uint16_t len, uint8_t *data);
+static void enc28j60WriteBuffer(uint16_t len, uint8_t *data);
+static void enc28j60SetBank(uint8_t address);
+static uint8_t enc28j60Read(uint8_t address);
+static void enc28j60Write(uint8_t address, uint8_t data);
+static uint32_t enc28j60PhyWrite(uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
+static uint32_t enc28j60Phyregread(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
+static void enc28j60Init(const uint8_t *macaddr);
+static int enc28j60Reset(int obj);
+static uint16_t enc28j60GetRxFreeSpace(void);
+static void enc28j60_int_handle(uint32_t event);
+static int enc28j60_set_interrupt(pin_t gpio_pin);
+extern void mdelay(uint32_t ms);
+
+/**
+ * interrupt handle function to post sem for handle
+ *
+ * @param irqno the irq number of network
+ *
+ */
+static void enc28j60_int_handle(uint32_t event)
+{
+ eth_mac_priv_t *eth_priv = &s_eth_instance[0];
+ uint8_t int_stat, ptkcnt, estat;
+ uint16_t freespace;
+ uint16_t status_vec_ptr;
+ uint8_t status_vec[7];
+ bool reset = 0;
+
+ csi_gpio_pin_irq_set(pin_int, GPIO_IRQ_MODE_LOW_LEVEL, 0);
+ //enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIE, EIE_INTIE);
+
+ int_stat = enc28j60Read(EIR); /* read EIR register data */;
+
+ // error flags to be handled first
+ if (int_stat & EIR_RXERIF) {
+ ptkcnt = enc28j60Read(EPKTCNT);
+ freespace = enc28j60GetRxFreeSpace();
+#ifndef CONFIG_TEST_TTCP
+
+ if ((ptkcnt == 0xFF) || (freespace < MAX_FRAMELEN)) {
+ /* do nothing, data in buffer will be read out */
+ printf("Rx buffer has %d packets and %d bytes free space\n", ptkcnt, freespace);
+ } else {
+ printf("something is wrong other than no buffer.\n");
+ }
+
+#endif
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_RXERIF);
+
+ if (ptkcnt > MAX_RECV_ERROR_CNT) {
+ reset = 1;
+ }
+ }
+
+ if (int_stat & EIR_TXERIF) {
+ estat = enc28j60Read(ESTAT);
+
+ if ((estat & ESTAT_TXABRT) || (estat & ESTAT_LATECOL)) {
+ printf("ESTAT=0x%x\n", estat);
+ status_vec_ptr = enc28j60Read(ETXNDL);
+ status_vec_ptr |= enc28j60Read(ETXNDH) << 8;
+ status_vec_ptr++;
+ enc28j60Write(ERDPTL, status_vec_ptr);
+ enc28j60Write(ERDPTH, status_vec_ptr >> 8);
+ enc28j60ReadBuffer(7, status_vec);
+ printf("status vector:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
+ status_vec[0], status_vec[1], status_vec[2], status_vec[3], status_vec[4], status_vec[5], status_vec[6]);
+ reset = 1;
+ }
+
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF);
+ }
+
+ if (reset) {
+ if (enc28j60Reset(RST_ENC28J60_ALL) == 0) {
+ printf("reset OK \n");
+ /* init enc28j60 module */
+ uint8_t macaddr[6];
+
+ csi_eth_mac_get_macaddr(NULL, (eth_mac_addr_t *)macaddr);
+
+ enc28j60Init(macaddr);
+
+ printf("enc28j60 init OK \n");
+ enc28j60_set_interrupt(PA5_A8);
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE);
+ return;
+ }
+ }
+
+ if (int_stat & EIR_PKTIF) {
+ ptkcnt = enc28j60Read(EPKTCNT); //just for debugging
+
+ //EIR_PKTIF will be cleared if all data is read out
+ eth_priv->cb_event((eth_mac_handle_t)eth_priv, CSI_ETH_MAC_EVENT_RX_FRAME);
+ }
+
+ if (int_stat & EIR_TXIF) {
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXIF);
+ //eth_priv->cb_event((eth_mac_handle_t)eth_priv, CSI_ETH_MAC_EVENT_TX_FRAME);
+ }
+
+ if (int_stat & EIR_LINKIF) {
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_LINKIF);
+ eth_priv->cb_event((eth_mac_handle_t)eth_priv, CSI_ETH_MAC_EVENT_LINK_CHANGE);
+ }
+
+ //clear all interrupt falgs. In fact, EIR_PKTIF can not be cleared
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, 0xFF & (~(EIR_PKTIF | EIR_LINKIF)));
+
+ // don't enable interrupt if events not handled
+ if (!(int_stat & (EIR_PKTIF | EIR_LINKIF))) {
+ //enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE);
+ csi_gpio_pin_irq_set(pin_int, GPIO_IRQ_MODE_LOW_LEVEL, 1);
+ }
+
+}
+
+void enc28j60_spi_transfer_callback(spi_event_e event)
+{
+ if (event == SPI_EVENT_TRANSFER_COMPLETE) {
+
+ } else if (event == SPI_EVENT_TX_COMPLETE) {
+ //csi_kernel_sem_post(g_sem_spi_tx_hd);
+ } else if (event == SPI_EVENT_RX_COMPLETE) {
+ //csi_kernel_sem_post(g_sem_spi_rx_hd);
+ } else if (event == SPI_EVENT_DATA_LOST) {
+ printf("TRANSFER_DATA_LOST\n");
+ } else {
+ printf("TRANSFER_MODE_FAULT\n");
+ }
+}
+
+void enc28j60_spi_cs_status_change(int status)
+{
+ csi_gpio_pin_write(pgpio_pin_handle1, status);
+}
+
+static int32_t enc28j60_spi_send(spi_handle_t handle, const void *data, uint32_t num)
+{
+ csi_spi_send(handle, data, num, 1);
+ // csi_kernel_sem_wait(g_sem_spi_tx_hd, -1);
+
+ return 0;
+}
+
+static int32_t enc28j60_spi_receive(spi_handle_t handle, void *data, uint32_t num)
+{
+ csi_spi_receive(handle, data, num, 1);
+ //csi_kernel_sem_wait(g_sem_spi_rx_hd, -1);
+
+ return 0;
+}
+
+/**
+ * read ctrl register
+ * @param op operation cmd
+ * @param register address
+ *
+ * @return
+ * -register data
+ */
+static uint8_t enc28j60ReadOp(uint8_t op, uint8_t address)
+{
+ uint8_t dat = 0;
+
+ ENC28J60_CSL();
+
+ dat = (op | (address & ADDR_MASK));
+
+ uint8_t rdata[1] = {0};
+
+ enc28j60_spi_send(g_net_spi_hd, &dat, 1);
+
+ enc28j60_spi_receive(g_net_spi_hd, &rdata[0], 1);
+
+ /* do dummy read if needed (for mac and mii, see datasheet page 29) */
+ if (address & 0x80) {
+ enc28j60_spi_receive(g_net_spi_hd, &rdata[0], 1);
+ }
+
+ /* release CS */
+ ENC28J60_CSH();
+ return rdata[0];
+
+}
+
+/**
+ * write ctrl cmd to register
+ * @param op operation cmd
+ * @param register address
+ * @param data the data to be set
+ *
+ * @return
+ * -NULL
+ */
+static void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data)
+{
+ char dat = 0;
+
+ ENC28J60_CSL();
+ /* issue write command */
+ dat = op | (address & ADDR_MASK);
+
+ enc28j60_spi_send(g_net_spi_hd, &dat, 1);
+
+ dat = data;
+ enc28j60_spi_send(g_net_spi_hd, &dat, 1);
+
+ ENC28J60_CSH();
+}
+
+/**
+ * read buffer data
+ * @param len the data length waint to read
+ * @param data the data buffer
+ *
+ * @return
+ * -NULL
+ */
+static void enc28j60ReadBuffer(uint16_t len, uint8_t *data)
+{
+ char ops_ctr = ENC28J60_READ_BUF_MEM;
+
+ ENC28J60_CSL();
+ /* issue read command */
+
+ enc28j60_spi_send(g_net_spi_hd, &ops_ctr, 1);
+
+ enc28j60_spi_receive(g_net_spi_hd, (char *)&data[0], len);
+
+ ENC28J60_CSH();
+}
+
+/**
+ * write data to buffer
+ * @param len the data length waint to write
+ * @param data the data buffer pointer
+ *
+ * @return
+ * -NULL
+ */
+static void enc28j60WriteBuffer(uint16_t len, uint8_t *data)
+{
+ char ops_ctr = ENC28J60_WRITE_BUF_MEM;
+
+ ENC28J60_CSL();
+ /* issue write command */
+ //drv_porting_spi_write(NULL, &ops_ctr, 1);
+
+ enc28j60_spi_send(g_net_spi_hd, &ops_ctr, 1);
+
+ enc28j60_spi_send(g_net_spi_hd, &data[0], len);
+
+ ENC28J60_CSH();
+}
+
+/**
+ * select the bank to operation
+ * @param address the bank address
+ *
+ * @return
+ * -NULL
+ */
+static void enc28j60SetBank(uint8_t address)
+{
+ /* set the bank (if needed) */
+ if ((address & BANK_MASK) != Enc28j60Bank) {
+ /* set the bank */
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1 | ECON1_BSEL0));
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK) >> 5);
+ Enc28j60Bank = (address & BANK_MASK);
+ }
+}
+
+/**
+ * read ctrl register data
+ * @param address the ctrl register address
+ *
+ * @return
+ * -ctrl register data
+ */
+static uint8_t enc28j60Read(uint8_t address)
+{
+ /* set the bank */
+ enc28j60SetBank(address);
+ /* do the read */
+ return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);
+}
+
+/**
+ * write data to ctrl register
+ * @param address the ctrl register address
+ * @param data ctrl register cmd
+ *
+ * @return
+ * - NULL
+ */
+static void enc28j60Write(uint8_t address, uint8_t data)
+{
+ /* set the bank */
+ enc28j60SetBank(address);
+ /* do the write */
+ enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);
+}
+
+/**
+ * write data to phy register
+ * @param address the phy register address
+ * @param data phy register cmd
+ *
+ * @return
+ * - NULL
+ */
+static uint32_t enc28j60PhyWrite(uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
+{
+ int retry = 0;
+
+ /* set the PHY register address */
+ enc28j60Write(MIREGADR, phy_addr);
+ /* write the PHY data */
+ enc28j60Write(MIWRL, data);
+ enc28j60Write(MIWRH, data >> 8);
+
+ /* wait until the PHY write completes */
+ while (enc28j60Read(MISTAT) & MISTAT_BUSY) {
+ retry++;
+
+ if (retry > 0xFFF) {
+ printf("write Phyreg_status error \n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * read data from phy register
+ * @param address the phy register address
+ *
+ * @return
+ * -the data of phy register
+ */
+static uint32_t enc28j60Phyregread(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
+{
+ uint8_t temp;
+ int retry = 0;
+
+ temp = enc28j60Read(MICMD);
+ /* set the PHY register address */
+ enc28j60Write(MIREGADR, phy_addr);
+
+ enc28j60Write(MICMD, temp | MICMD_MIIRD);
+
+ /* Loop to wait until the PHY register has been read through the MII */
+ while ((enc28j60Read(MISTAT) & MISTAT_BUSY)) {
+ if (retry++ > 0xFFF) {
+ printf("read Phyreg_status error \n");
+ return -1;
+ }
+ }
+
+ enc28j60Write(MICMD, temp & (~MICMD_MIIRD)); /* clear bit MICMD.MIIRD */
+
+ /* Obtain results and return */
+ *data = enc28j60Read(MIRDL);
+ *data |= (enc28j60Read(MIRDH) << 8);
+
+ return *data;
+}
+
+/**
+ * init ethernet ctrl register
+ * @param address the MAC address
+ *
+ * @return
+ * - NULL
+ */
+static void enc28j60Init(const uint8_t *macaddr)
+{
+ /* check CLKRDY bit to see if reset is complete */
+ /* The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait. */
+ NextPacketPtr = RXSTART_INIT;
+ /* Rx start */
+ enc28j60Write(ERXSTL, RXSTART_INIT & 0xFF);
+ enc28j60Write(ERXSTH, RXSTART_INIT >> 8);
+ /* set receive pointer address */
+ enc28j60Write(ERXRDPTL, RXSTART_INIT & 0xFF);
+ enc28j60Write(ERXRDPTH, RXSTART_INIT >> 8);
+ /* RX end */
+ enc28j60Write(ERXNDL, RXSTOP_INIT & 0xFF);
+ enc28j60Write(ERXNDH, RXSTOP_INIT >> 8);
+ /* TX start */
+ enc28j60Write(ETXSTL, TXSTART_INIT & 0xFF);
+ enc28j60Write(ETXSTH, TXSTART_INIT >> 8);
+ /* TX end */
+ enc28j60Write(ETXNDL, TXSTOP_INIT & 0xFF);
+ enc28j60Write(ETXNDH, TXSTOP_INIT >> 8);
+
+ /* do bank 1 stuff, packet filter:
+ For broadcast packets we allow only ARP packtets
+ All other packets should be unicast only for our mac (MAADR) */
+#if LWIP_IPV4 && LWIP_IPV6
+ enc28j60Write(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN | ERXFCON_MCEN);
+ enc28j60Write(EPMM0, 0x3f); /* ARP Pattern Match Filter */
+ enc28j60Write(EPMM1, 0x30);
+ enc28j60Write(EPMCSL, 0xf9);
+ enc28j60Write(EPMCSH, 0xf7);
+#elif LWIP_IPV6
+ enc28j60Write(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_MCEN);
+#else /* for IPv6 without ARP and BC */
+ enc28j60Write(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN);
+ enc28j60Write(EPMM0, 0x3f); /* ARP Pattern Match Filter */
+ enc28j60Write(EPMM1, 0x30);
+ enc28j60Write(EPMCSL, 0xf9);
+ enc28j60Write(EPMCSH, 0xf7);
+#endif
+ /* do bank 2 stuff */
+ /* enable MAC receive */
+ enc28j60Write(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
+ /* bring MAC out of reset */
+ enc28j60Write(MACON2, 0x00);
+ /* enable automatic padding to 60bytes and CRC operations */
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX); /* MACON3_HFRMLEN */
+ /* set inter-frame gap (non-back-to-back) */
+ enc28j60Write(MAIPGL, 0x12);
+ enc28j60Write(MAIPGH, 0x0C);
+ /* set inter-frame gap (back-to-back) */
+ enc28j60Write(MABBIPG, 0x15);
+ /* Set the maximum packet size which the controller will accept */
+ /* Do not send packets longer than MAX_FRAMELEN: */
+ enc28j60Write(MAMXFLL, MAX_FRAMELEN & 0xFF);
+ enc28j60Write(MAMXFLH, MAX_FRAMELEN >> 8);
+
+ /* do bank 3 stuff */
+ /* write MAC address */
+ /* NOTE: MAC address in ENC28J60 is byte-backward */
+ enc28j60Write(MAADR5, macaddr[0]);
+ enc28j60Write(MAADR4, macaddr[1]);
+ enc28j60Write(MAADR3, macaddr[2]);
+ enc28j60Write(MAADR2, macaddr[3]);
+ enc28j60Write(MAADR1, macaddr[4]);
+ enc28j60Write(MAADR0, macaddr[5]);
+ enc28j60PhyWrite(PHCON1, 0, PHCON1_PDPXMD);
+
+ /* no loopback of transmitted frames */
+ enc28j60PhyWrite(PHCON2, 0, PHCON2_HDLDIS);
+
+ enc28j60PhyWrite(PHIE, 0, PHIE_PLNKIE | PHIE_PGEIE);
+
+ /* switch to bank 0 */
+ enc28j60SetBank(ECON1);
+ /* enable interrutps */
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_PKTIE | EIE_LINKIE | EIE_TXIE | EIE_TXERIE | EIE_RXERIE);
+ /* enable packet reception */
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
+
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE);
+}
+
+/**
+ * set mac addr
+ * @param macaddr the macaddr for net
+ *
+ * @return
+ * - NULL
+ */
+static void enc28j60Setmacaddr(const uint8_t *macaddr)
+{
+ ENC28J60_CSH();
+ /* enable MAC receive */
+ enc28j60Write(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
+ /* bring MAC out of reset */
+ enc28j60Write(MACON2, 0x00);
+ /* enable automatic padding to 60bytes and CRC operations */
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FULDPX);
+
+ /* write MAC address */
+ /* NOTE: MAC address in ENC28J60 is byte-backward */
+ enc28j60Write(MAADR5, macaddr[0]);
+ enc28j60Write(MAADR4, macaddr[1]);
+ enc28j60Write(MAADR3, macaddr[2]);
+ enc28j60Write(MAADR2, macaddr[3]);
+ enc28j60Write(MAADR1, macaddr[4]);
+ enc28j60Write(MAADR0, macaddr[5]);
+
+}
+
+/**
+ * Hard reset enc28j60
+ * @param void
+ *
+ */
+static void enc28j60hardreset(void)
+{
+ gpio_pin_handle_t pin = NULL;
+ pin = csi_gpio_pin_initialize(PA1);
+ csi_gpio_pin_config(pin, GPIO_MODE_PULLNONE, GPIO_DIRECTION_OUTPUT);
+ csi_gpio_pin_write(pin, 0); /* LOW */
+ mdelay(3);
+ csi_gpio_pin_write(pin, 1);
+ mdelay(3);
+
+ printf("NET HARD RESET\n");
+}
+
+/**
+ * reset enc28j60
+ * @param obj the net work object
+ *
+ * @return
+ * - status
+ */
+static int enc28j60Reset(int obj)
+{
+ int retry = 0;
+
+ ENC28J60_CSH();
+
+ if (obj == RST_ENC28J60_ALL) {
+ /* first net hard reset */
+ enc28j60hardreset();
+ enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
+
+ while (!(enc28j60Read(ESTAT) & ESTAT_CLKRDY)) {
+ if (retry++ > 0xFFF) {
+ return -1;
+ }
+ }
+ } else if (obj == RST_ENC28J60_TX) {
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
+ } else if (obj == RST_ENC28J60_RX) {
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXRST);
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXRST);
+ }
+
+ return 0;
+}
+
+/**
+ * get rx free space
+ * @param void
+ *
+ * @return
+ * - status 0
+ */
+static uint16_t enc28j60GetRxFreeSpace(void)
+{
+ uint16_t free_space;
+ uint16_t erxrdpt;
+ uint16_t erxwrpt;
+
+ erxrdpt = enc28j60Read(ERXRDPTL);
+ erxrdpt |= enc28j60Read(ERXRDPTH) << 8;
+
+ erxwrpt = enc28j60Read(ERXWRPTL);
+ erxwrpt |= enc28j60Read(ERXWRPTH) << 8;
+
+ if (erxwrpt > erxrdpt) {
+ free_space = (RXSTOP_INIT - RXSTART_INIT) - (erxwrpt - erxrdpt);
+ } else if (erxwrpt == erxrdpt) {
+ free_space = (RXSTOP_INIT - RXSTART_INIT);
+ } else {
+ free_space = erxrdpt - erxwrpt - 1;
+ }
+
+ return free_space;
+}
+
+/**
+ * enc28j60 interrupt set
+ * @param interrupt_cb the interrupt callback function
+ *
+ * @return
+ * - status 0
+ */
+
+static int enc28j60_set_interrupt(pin_t gpio_pin)
+{
+ uint32_t ret = 0;
+
+ pin_int = csi_gpio_pin_initialize(gpio_pin);
+
+ ret = csi_gpio_pin_config(pin_int, GPIO_MODE_PULLUP, GPIO_DIRECTION_INPUT);
+
+ ret = csi_gpio_pin_irq_set(pin_int, GPIO_IRQ_MODE_LOW_LEVEL, 1);
+
+ return 0;
+}
+
+csi_drv_version_t csi_eth_phy_get_version(eth_phy_handle_t handle)
+{
+ csi_drv_version_t version = {0xff, 0xff};
+ uint16_t dev_version, dev_version1;
+
+ if (handle == NULL) {
+ return version;
+ }
+
+ enc28j60Phyregread(PHHID1, 0, &dev_version);
+ enc28j60Phyregread(PHHID2, 0, &dev_version1);
+
+ version.api = CSI_ETH_PHY_API_VERSION;
+ version.drv = (dev_version << 16) + dev_version1;
+
+ return version;
+}
+
+eth_phy_handle_t csi_eth_phy_initialize(csi_eth_phy_read_t fn_read, csi_eth_phy_write_t fn_write)
+{
+ eth_phy_priv_t *phy_priv;
+
+ if ((fn_read == NULL) || (fn_write == NULL)) {
+ return NULL;
+ }
+
+ csi_gpio_port_initialize(0, (gpio_event_cb_t)enc28j60_int_handle);
+
+ phy_priv = &s_phy_instance[0];
+
+ phy_priv->phy_read = fn_read ;
+ phy_priv->phy_write = fn_write;
+
+ return (eth_mac_handle_t)phy_priv;
+}
+
+int32_t csi_eth_phy_uninitialize(eth_phy_handle_t handle)
+{
+ if (handle == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int32_t csi_eth_phy_deinit(void)
+{
+ /* no loopback of transmitted frames */
+ enc28j60PhyWrite(PHCON2, 0, PHCON2_HDLDIS);
+ /* LINK AND ALL PHY Interrupt Enable */
+ enc28j60PhyWrite(PHIE, 0, PHIE_PLNKIE | PHIE_PGEIE);
+ return 0;
+}
+
+int32_t csi_eth_phy_power_control(eth_phy_handle_t handle, eth_power_state_t state)
+{
+ uint16_t power_control;
+
+ if (handle == NULL) {
+ return -1;
+ }
+
+ enc28j60Phyregread(PHCON1, 0, &power_control);
+
+ if (state == CSI_ETH_POWER_FULL) {
+ power_control &= ~(1 << 11);
+ } else if (state == CSI_ETH_POWER_OFF) {
+ power_control |= (1 << 11);
+ } else if (state == CSI_ETH_POWER_LOW) {
+
+ } else {
+ return -1;
+ }
+
+ enc28j60PhyWrite(PHCON1, 0, power_control);
+
+ return 0;
+}
+
+int32_t csi_eth_phy_set_interface(eth_phy_handle_t handle, uint32_t interface)
+{
+ if (handle == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+eth_link_info_t csi_eth_phy_get_linkinfo(eth_phy_handle_t handle)
+{
+ eth_link_info_t net_link_info = {0};
+
+ if (handle == NULL) {
+ return net_link_info;
+ }
+
+ net_link_info.duplex = 1;
+ net_link_info.speed = 1;
+
+ return net_link_info;
+}
+
+int32_t csi_eth_phy_set_mode(eth_phy_handle_t handle, uint32_t mode)
+{
+ uint32_t phy_mode = 0;
+
+ if (handle == NULL) {
+ return -1;
+ }
+
+ eth_phy_priv_t *phy_priv = (eth_phy_priv_t *)handle;
+
+ phy_priv->link_info.speed = (mode & 0x03);
+ phy_priv->link_info.duplex = (mode & 0x04);
+ phy_priv->link_info.Loopback = (mode & 0x05);
+
+ if (phy_priv->link_info.duplex) {
+ phy_mode |= PHCON1_PDPXMD;
+ } else {
+ phy_mode &= ~(PHCON1_PDPXMD);
+ }
+
+ if (phy_priv->link_info.Loopback) {
+ phy_mode |= PHCON1_PLOOPBK;
+ } else {
+ phy_mode &= ~(PHCON1_PLOOPBK);
+ }
+
+ enc28j60PhyWrite(PHCON1, 0, phy_mode);
+
+ return 0;
+}
+
+eth_link_state_t csi_eth_phy_get_linkstate(eth_phy_handle_t handle)
+{
+ uint16_t phstat1;
+ uint16_t phstat2;
+ eth_link_state_t state;
+
+ if (handle == NULL) {
+ return -1;
+ }
+
+ uint8_t status = enc28j60Read(EIR);
+
+ if (status & EIR_LINKIF) {
+ /* as tested, need to read twice */
+ enc28j60Phyregread(PHSTAT1, 0, &phstat1);
+ enc28j60Phyregread(PHSTAT1, 0, &phstat2);
+
+ phstat1 |= phstat2;
+
+ if (phstat1 & 0x0004) {
+ state = ETH_LINK_UP;
+ } else {
+ state = ETH_LINK_DOWN;
+ }
+
+ /* resets to "0" when read */
+ enc28j60Phyregread(PHIR, 0, NULL);
+
+ return state;
+ }
+
+ return -1;
+}
+
+eth_mac_handle_t csi_eth_mac_initialize(eth_event_cb_t cb)
+{
+ eth_mac_priv_t *eth_priv;
+ static int eth_mac_init = 0;
+ int ret = -1;
+
+ if (cb == NULL) {
+ printf("cb == null\n");
+ return NULL;
+ }
+
+ eth_priv = &s_eth_instance[0];
+ eth_priv->cb_event = cb;
+
+ if (eth_mac_init == 0) {
+ //init spi get spi_handle
+ g_net_spi_hd = csi_spi_initialize(SPI1_TX, SPI1_RX, SPI1_CLK, SPI1_CS, (spi_event_cb_t)enc28j60_spi_transfer_callback, NULL);
+
+ //spi_handle success goto config spi
+ if (g_net_spi_hd != NULL) {
+
+ ret = csi_spi_config(g_net_spi_hd, SYSTEM_CLOCK, 2000000, SPI_MODE_MASTER, SPI_FORMAT_CPOL0_CPHA0,
+ SPI_ORDER_MSB2LSB, SPI_SS_MASTER_SW, 7);
+
+ pgpio_pin_handle1 = csi_gpio_pin_initialize(SPI1_CS);
+ csi_gpio_pin_config(pgpio_pin_handle1, GPIO_MODE_PULLNONE, GPIO_DIRECTION_OUTPUT);
+
+ }
+
+ eth_mac_init = 1;
+ }
+
+ if ((ret == 0) || (eth_mac_init == 1)) {
+
+ if (enc28j60Reset(RST_ENC28J60_ALL) == 0) {
+ printf("reset OK \n");
+ /* init enc28j60 module */
+ uint8_t macaddr[6];
+
+ csi_eth_mac_get_macaddr(NULL, (eth_mac_addr_t *)macaddr);
+
+ enc28j60Init(macaddr);
+
+ printf("enc28j60 init OK \n");
+ enc28j60_set_interrupt(PA5_A8);
+
+ //g_sem_spi_tx_hd = csi_kernel_sem_new(1, 0);
+ //g_sem_spi_rx_hd = csi_kernel_sem_new(1, 0);
+
+ return (eth_mac_handle_t)eth_priv;
+ }
+ }
+
+ return NULL;
+}
+
+int32_t csi_eth_mac_uninitialize(eth_mac_handle_t handle)
+{
+ if (handle == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+csi_drv_version_t csi_eth_mac_get_version(eth_mac_handle_t handle)
+{
+ csi_drv_version_t mac_version = {0xff, 0xff};
+
+ if (handle == NULL) {
+ return mac_version;
+ }
+
+ mac_version.api = CSI_ETH_PHY_API_VERSION;
+ mac_version.drv = enc28j60Read(EREVID);
+
+ return mac_version;
+}
+
+int32_t csi_eth_mac_power_control(eth_mac_handle_t handle, eth_power_state_t state)
+{
+ uint8_t pw_control;
+
+ if (handle == NULL) {
+ return -1;
+ }
+
+ pw_control = enc28j60Read(ECON2);
+
+ if (state == CSI_ETH_POWER_FULL) {
+ pw_control &= ~(1 << 11);
+ } else if (state == CSI_ETH_POWER_LOW) {
+ pw_control |= (1 << 11);
+ } else if (state == CSI_ETH_POWER_OFF) {
+
+ } else {
+ return -1;
+ }
+
+ enc28j60Write(ECON2, pw_control);
+
+ return 0;
+}
+
+int32_t csi_eth_mac_get_macaddr(eth_mac_handle_t handle, eth_mac_addr_t *mac)
+{
+ if ((handle == NULL) || (mac == NULL)) {
+ return -1;
+ }
+
+ memcpy(mac, g_hw_addr, NET_HWADDR_LEN);
+ return 0;
+}
+
+int32_t csi_eth_mac_set_macaddr(eth_mac_handle_t handle, const eth_mac_addr_t *mac)
+{
+ if ((handle == NULL) || (mac == NULL)) {
+ return -1;
+ }
+
+ memcpy(g_hw_addr, mac, NET_HWADDR_LEN);
+ printf("csiMAC: %02x:%02x:%02x:%02x:%02x:%02x\n", g_hw_addr[0], g_hw_addr[1], g_hw_addr[2],
+ g_hw_addr[3], g_hw_addr[4], g_hw_addr[5]);
+
+ enc28j60Setmacaddr(g_hw_addr);
+ return 0;
+}
+
+int32_t csi_eth_mac_set_addrfilter(eth_mac_handle_t handle, const eth_mac_addr_t *addr, uint32_t num_addr)
+{
+ if ((handle == NULL) || (addr == NULL)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t csi_eth_mac_get_rx_framesize(eth_mac_handle_t handle)
+{
+ uint16_t len;
+ uint16_t rxstat;
+
+ if (handle == NULL) {
+ return -1;
+ }
+
+ /* check if a packet has been received and buffered
+ if( !(enc28j60Read(EIR) & EIR_PKTIF) ){
+ The above does not work. See Rev. B4 Silicon Errata point 6. */
+ if (enc28j60Read(EPKTCNT) == 0) {
+ return (0);
+ }
+
+ /* Set the read pointer to the start of the received packet */
+ enc28j60Write(ERDPTL, (NextPacketPtr));
+ enc28j60Write(ERDPTH, (NextPacketPtr) >> 8);
+
+ /* read the next packet pointer */
+ NextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+ NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
+
+ /* read the packet length (see datasheet page 43) */
+ len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+ len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
+ len -= 4; /* remove the CRC count */
+
+ /* limit retrieve length */
+ if (len > MAX_FRAMELEN - 1) {
+ printf("rx packet length is %d\n", len);
+ len = MAX_FRAMELEN - 1;
+ return -1;
+ }
+
+ /* read the receive status (see datasheet page 43) */
+ rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+ rxstat |= (uint16_t)enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
+
+ /* check CRC and symbol errors (see datasheet page 44, table 7-3): */
+ /* The ERXFCON.CRCEN is set by default. Normally we should not */
+ /* need to check this. */
+ if ((rxstat & 0x80) == 0) {
+ printf("rx status vector is 0x%x\n", rxstat);
+ len = 0; // invalid
+ return -1;
+ }
+
+ return len;
+}
+
+int32_t csi_eth_mac_get_rx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time)
+{
+ if ((handle == NULL)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t csi_eth_mac_get_tx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time)
+{
+ if (handle == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t csi_eth_mac_control(eth_mac_handle_t handle, uint32_t control, uint32_t arg)
+{
+ if (handle == NULL) {
+ return -1;
+ }
+
+
+ if (control == CSI_ETH_MAC_CONTROL_RX) {
+ if (arg) {
+ //enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE);
+ csi_gpio_pin_irq_set(pin_int, GPIO_IRQ_MODE_LOW_LEVEL, 1);
+
+ } else {
+ //enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIE, EIE_INTIE);
+ csi_gpio_pin_irq_set(pin_int, GPIO_IRQ_MODE_LOW_LEVEL, 0);
+ }
+
+ return 0;
+ }
+
+ return 0;
+}
+
+/**
+ * send a packet data
+ * @param address the packet data length
+ *
+ * @return
+ * - sent data length
+ */
+int32_t csi_eth_mac_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len, uint32_t flags)
+{
+ int retry = 0;
+
+ if ((handle == NULL) || (frame == NULL)) {
+ return -1;
+ }
+
+ if (len > MAX_FRAMELEN) {
+ printf("TX len %d is too large to send\n", len);
+ return 0;
+ }
+
+ while (enc28j60Read(ECON1) & ECON1_TXRTS) {
+ if (retry++ > 0xFFF) {
+ printf("data not be sent out\n");
+ return -1;
+ }
+ }
+
+ /* Set the write pointer to start of transmit buffer area */
+ enc28j60Write(EWRPTL, TXSTART_INIT & 0xFF);
+ enc28j60Write(EWRPTH, TXSTART_INIT >> 8);
+
+ /* Set the TXND pointer to correspond to the packet size given */
+ /* Status vector will be written at ETXND+1. */
+ enc28j60Write(ETXNDL, (TXSTART_INIT + len) & 0xFF);
+ enc28j60Write(ETXNDH, (TXSTART_INIT + len) >> 8);
+
+ /* write per-packet control byte (0x00 means use macon3 settings) */
+ enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
+
+ /* copy the packet into the transmit buffer */
+ enc28j60WriteBuffer(len, (uint8_t *)frame);
+
+ /* send the contents of the transmit buffer onto the network */
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
+
+ /* Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. */
+ if ((enc28j60Read(EIR) & EIR_TXERIF)) {
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
+ }
+
+ return len;
+}
+
+int32_t csi_eth_mac_read_frame(eth_mac_handle_t handle, uint8_t *frame, uint32_t len)
+{
+ uint32_t rlen;
+ uint16_t rxstat;
+
+ if ((handle == NULL) || (frame == NULL)) {
+ return -1;
+ }
+
+ /* check if a packet has been received and buffered
+ if( !(enc28j60Read(EIR) & EIR_PKTIF) ){
+ The above does not work. See Rev. B4 Silicon Errata point 6. */
+ if (enc28j60Read(EPKTCNT) == 0) {
+ return (0);
+ }
+
+ /* Set the read pointer to the start of the received packet */
+ enc28j60Write(ERDPTL, (NextPacketPtr));
+ enc28j60Write(ERDPTH, (NextPacketPtr) >> 8);
+
+ /* read the next packet pointer */
+ NextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+ NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
+
+ /* read the packet length (see datasheet page 43) */
+ rlen = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+ rlen |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
+ rlen -= 4; /* remove the CRC count */
+
+ /* limit retrieve length */
+ if (rlen > MAX_FRAMELEN - 1) {
+ printf("rx packet length is %d\n", rlen);
+ rlen = MAX_FRAMELEN - 1;
+ return -1;
+ }
+
+ /* read the receive status (see datasheet page 43) */
+ rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+ rxstat |= (uint16_t)enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
+
+ /* check CRC and symbol errors (see datasheet page 44, table 7-3): */
+ /* The ERXFCON.CRCEN is set by default. Normally we should not */
+ /* need to check this. */
+ if ((rxstat & 0x80) == 0) {
+ printf("rx status vector is 0x%x\n", rxstat);
+ rlen = 0; // invalid
+ return -1;
+ }
+
+ /* copy the packet from the receive buffer */
+ enc28j60ReadBuffer(rlen, frame);
+
+ /* Move the RX read pointer to the start of the next received packet */
+ /* This frees the memory we just read out */
+ enc28j60Write(ERXRDPTL, (NextPacketPtr));
+ enc28j60Write(ERXRDPTH, (NextPacketPtr) >> 8);
+
+ /* decrement the packet counter indicate we are done with this packet */
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_AUTOINC | ECON2_PKTDEC);
+
+ return rlen;
+
+}
+
+eth_capabilities_t csi_eth_mac_get_capabilities(eth_mac_handle_t handle)
+{
+ eth_capabilities_t capab = {0};
+
+ if (handle == NULL) {
+ return capab;
+ }
+
+ eth_mac_priv_t *mac_priv = (eth_mac_priv_t *)handle;
+
+ mac_priv->capabilities.mac_address = 1;
+
+ capab = mac_priv->capabilities;
+
+ return capab;
+}
+
+void csi_eth_mac_signal_event(eth_mac_handle_t handle, uint32_t event)
+{
+ if (handle == NULL) {
+ return;
+ }
+
+}
+
+int32_t csi_eth_mac_control_time(eth_mac_handle_t handle, uint32_t control, eth_mac_time_t *time)
+{
+ if (handle == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t csi_eth_mac_phy_read(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
+{
+ if ((handle == NULL) || (data == NULL)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t csi_eth_mac_phy_write(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
+{
+ if ((handle == NULL)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t csi_eth_mac_add_framefilter(eth_mac_handle_t handle, const eth_frame_filter_t *filter)
+{
+ if ((handle == NULL) || (filter == NULL)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t csi_eth_mac_remove_framefilter(eth_mac_handle_t handle, uint32_t filter_id)
+{
+ if (handle == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t csi_eth_mac_en_framefilter(eth_mac_handle_t handle, uint32_t filter_id, bool en)
+{
+ if (handle == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t csi_eth_mac_get_framefilter(eth_mac_handle_t handle, eth_frame_filter_list_t *list, uint32_t *count_out, uint32_t max_count)
+{
+ if ((handle == NULL) || (list == NULL)) {
+ return -1;
+ }
+
+ return 0;
+}
+
diff --git a/bsp/ck802/libraries/common/eth/ethernet_enc28j60.h b/bsp/ck802/libraries/common/eth/ethernet_enc28j60.h
new file mode 100644
index 0000000000..997f0abefc
--- /dev/null
+++ b/bsp/ck802/libraries/common/eth/ethernet_enc28j60.h
@@ -0,0 +1,427 @@
+/****************************************************************************
+ * csky/hardware/bsp/common/ethernet_enc28j60/ethernet_enc28j60.h
+ *
+ * Copyright (C) 2016 The YunOS Open Source Project
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef _ETHERNET_ENC28J60_H__
+#define _ETHERNET_ENC28J60_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/* ****** ETH ****** */
+#define ETH_HEADER_LEN 14
+/* values of certain bytes: */
+#define ETHTYPE_ARP_H_V 0x08
+#define ETHTYPE_ARP_L_V 0x06
+#define ETHTYPE_IP_H_V 0x08
+#define ETHTYPE_IP_L_V 0x00
+/* byte positions in the ethernet frame:
+ Ethernet type field (2bytes): */
+#define ETH_TYPE_H_P 12
+#define ETH_TYPE_L_P 13
+
+#define ETH_DST_MAC 0
+#define ETH_SRC_MAC 6
+
+
+/* ******* ARP ******* */
+#define ETH_ARP_OPCODE_REPLY_H_V 0x0
+#define ETH_ARP_OPCODE_REPLY_L_V 0x02
+
+#define ETHTYPE_ARP_L_V 0x06
+/* arp.dst.ip */
+#define ETH_ARP_DST_IP_P 0x26
+/* arp.opcode */
+#define ETH_ARP_OPCODE_H_P 0x14
+#define ETH_ARP_OPCODE_L_P 0x15
+/* arp.src.mac */
+#define ETH_ARP_SRC_MAC_P 0x16
+#define ETH_ARP_SRC_IP_P 0x1c
+#define ETH_ARP_DST_MAC_P 0x20
+#define ETH_ARP_DST_IP_P 0x26
+
+/* ******* IP ******* */
+#define IP_HEADER_LEN 20
+/* ip.src */
+#define IP_SRC_P 0x1a
+#define IP_DST_P 0x1e
+#define IP_HEADER_LEN_VER_P 0xe
+#define IP_CHECKSUM_P 0x18
+#define IP_TTL_P 0x16
+#define IP_FLAGS_P 0x14
+#define IP_P 0xe
+#define IP_TOTLEN_H_P 0x10
+#define IP_TOTLEN_L_P 0x11
+
+#define IP_PROTO_P 0x17
+
+#define IP_PROTO_ICMP_V 1
+#define IP_PROTO_TCP_V 6
+/* 17=0x11 */
+#define IP_PROTO_UDP_V 17
+/* ******* ICMP ******* */
+#define ICMP_TYPE_ECHOREPLY_V 0
+#define ICMP_TYPE_ECHOREQUEST_V 8
+
+#define ICMP_TYPE_P 0x22
+#define ICMP_CHECKSUM_P 0x24
+
+/* ******* UDP ******* */
+#define UDP_HEADER_LEN 8
+
+#define UDP_SRC_PORT_H_P 0x22
+#define UDP_SRC_PORT_L_P 0x23
+#define UDP_DST_PORT_H_P 0x24
+#define UDP_DST_PORT_L_P 0x25
+
+#define UDP_LEN_H_P 0x26
+#define UDP_LEN_L_P 0x27
+#define UDP_CHECKSUM_H_P 0x28
+#define UDP_CHECKSUM_L_P 0x29
+#define UDP_DATA_P 0x2a
+
+/* ******* TCP ******* */
+#define TCP_SRC_PORT_H_P 0x22
+#define TCP_SRC_PORT_L_P 0x23
+#define TCP_DST_PORT_H_P 0x24
+#define TCP_DST_PORT_L_P 0x25
+/* the tcp seq number is 4 bytes 0x26-0x29 */
+#define TCP_SEQ_H_P 0x26
+#define TCP_SEQACK_H_P 0x2a
+/* flags: SYN=2 */
+#define TCP_FLAGS_P 0x2f
+#define TCP_FLAGS_SYN_V 2
+#define TCP_FLAGS_FIN_V 1
+#define TCP_FLAGS_PUSH_V 8
+#define TCP_FLAGS_SYNACK_V 0x12
+#define TCP_FLAGS_ACK_V 0x10
+#define TCP_FLAGS_PSHACK_V 0x18
+/* plain len without the options: */
+#define TCP_HEADER_LEN_PLAIN 20
+#define TCP_HEADER_LEN_P 0x2e
+#define TCP_CHECKSUM_H_P 0x32
+#define TCP_CHECKSUM_L_P 0x33
+#define TCP_OPTIONS_P 0x36
+
+
+/* ENC28J60 Control Registers
+ Control register definitions are a combination of address,
+ bank number, and Ethernet/MAC/PHY indicator bits.
+ - Register address (bits 0-4)
+ - Bank number (bits 5-6)
+ - MAC/PHY indicator (bit 7) */
+#define ADDR_MASK 0x1F
+#define BANK_MASK 0x60
+#define SPRD_MASK 0x80
+/* All-bank registers */
+#define EIE 0x1B
+#define EIR 0x1C
+#define ESTAT 0x1D
+#define ECON2 0x1E
+#define ECON1 0x1F
+/* Bank 0 registers */
+#define ERDPTL (0x00|0x00)
+#define ERDPTH (0x01|0x00)
+#define EWRPTL (0x02|0x00)
+#define EWRPTH (0x03|0x00)
+#define ETXSTL (0x04|0x00)
+#define ETXSTH (0x05|0x00)
+#define ETXNDL (0x06|0x00)
+#define ETXNDH (0x07|0x00)
+#define ERXSTL (0x08|0x00)
+#define ERXSTH (0x09|0x00)
+#define ERXNDL (0x0A|0x00)
+#define ERXNDH (0x0B|0x00)
+#define ERXRDPTL (0x0C|0x00)
+#define ERXRDPTH (0x0D|0x00)
+#define ERXWRPTL (0x0E|0x00)
+#define ERXWRPTH (0x0F|0x00)
+#define EDMASTL (0x10|0x00)
+#define EDMASTH (0x11|0x00)
+#define EDMANDL (0x12|0x00)
+#define EDMANDH (0x13|0x00)
+#define EDMADSTL (0x14|0x00)
+#define EDMADSTH (0x15|0x00)
+#define EDMACSL (0x16|0x00)
+#define EDMACSH (0x17|0x00)
+/* Bank 1 registers */
+#define EHT0 (0x00|0x20)
+#define EHT1 (0x01|0x20)
+#define EHT2 (0x02|0x20)
+#define EHT3 (0x03|0x20)
+#define EHT4 (0x04|0x20)
+#define EHT5 (0x05|0x20)
+#define EHT6 (0x06|0x20)
+#define EHT7 (0x07|0x20)
+#define EPMM0 (0x08|0x20)
+#define EPMM1 (0x09|0x20)
+#define EPMM2 (0x0A|0x20)
+#define EPMM3 (0x0B|0x20)
+#define EPMM4 (0x0C|0x20)
+#define EPMM5 (0x0D|0x20)
+#define EPMM6 (0x0E|0x20)
+#define EPMM7 (0x0F|0x20)
+#define EPMCSL (0x10|0x20)
+#define EPMCSH (0x11|0x20)
+#define EPMOL (0x14|0x20)
+#define EPMOH (0x15|0x20)
+#define EWOLIE (0x16|0x20)
+#define EWOLIR (0x17|0x20)
+#define ERXFCON (0x18|0x20)
+#define EPKTCNT (0x19|0x20)
+/* Bank 2 registers */
+#define MACON1 (0x00|0x40|0x80)
+#define MACON2 (0x01|0x40|0x80)
+#define MACON3 (0x02|0x40|0x80)
+#define MACON4 (0x03|0x40|0x80)
+#define MABBIPG (0x04|0x40|0x80)
+#define MAIPGL (0x06|0x40|0x80)
+#define MAIPGH (0x07|0x40|0x80)
+#define MACLCON1 (0x08|0x40|0x80)
+#define MACLCON2 (0x09|0x40|0x80)
+#define MAMXFLL (0x0A|0x40|0x80)
+#define MAMXFLH (0x0B|0x40|0x80)
+#define MAPHSUP (0x0D|0x40|0x80)
+#define MICON (0x11|0x40|0x80)
+#define MICMD (0x12|0x40|0x80)
+#define MIREGADR (0x14|0x40|0x80)
+#define MIWRL (0x16|0x40|0x80)
+#define MIWRH (0x17|0x40|0x80)
+#define MIRDL (0x18|0x40|0x80)
+#define MIRDH (0x19|0x40|0x80)
+/* Bank 3 registers */
+#define MAADR1 (0x00|0x60|0x80)
+#define MAADR0 (0x01|0x60|0x80)
+#define MAADR3 (0x02|0x60|0x80)
+#define MAADR2 (0x03|0x60|0x80)
+#define MAADR5 (0x04|0x60|0x80)
+#define MAADR4 (0x05|0x60|0x80)
+#define EBSTSD (0x06|0x60)
+#define EBSTCON (0x07|0x60)
+#define EBSTCSL (0x08|0x60)
+#define EBSTCSH (0x09|0x60)
+#define MISTAT (0x0A|0x60|0x80)
+#define EREVID (0x12|0x60)
+#define ECOCON (0x15|0x60)
+#define EFLOCON (0x17|0x60)
+#define EPAUSL (0x18|0x60)
+#define EPAUSH (0x19|0x60)
+/* PHY registers */
+#define PHCON1 0x00
+#define PHSTAT1 0x01
+#define PHHID1 0x02
+#define PHHID2 0x03
+#define PHCON2 0x10
+#define PHSTAT2 0x11
+#define PHIE 0x12
+#define PHIR 0x13
+#define PHLCON 0x14
+
+/* ENC28J60 ERXFCON Register Bit Definitions */
+#define ERXFCON_UCEN 0x80
+#define ERXFCON_ANDOR 0x40
+#define ERXFCON_CRCEN 0x20
+#define ERXFCON_PMEN 0x10
+#define ERXFCON_MPEN 0x08
+#define ERXFCON_HTEN 0x04
+#define ERXFCON_MCEN 0x02
+#define ERXFCON_BCEN 0x01
+/* ENC28J60 EIE Register Bit Definitions */
+#define EIE_INTIE 0x80
+#define EIE_PKTIE 0x40
+#define EIE_DMAIE 0x20
+#define EIE_LINKIE 0x10
+#define EIE_TXIE 0x08
+#define EIE_WOLIE 0x04
+#define EIE_TXERIE 0x02
+#define EIE_RXERIE 0x01
+#define EIE_ALLCLOSE 0xff
+
+/* ENC28J60 EIR Register Bit Definitions */
+#define EIR_PKTIF 0x40
+#define EIR_DMAIF 0x20
+#define EIR_LINKIF 0x10
+#define EIR_TXIF 0x08
+#define EIR_WOLIF 0x04
+#define EIR_TXERIF 0x02
+#define EIR_RXERIF 0x01
+#define EIR_ALLINTS 0x7b /* All interrupts */
+
+/* ENC28J60 ESTAT Register Bit Definitions */
+#define ESTAT_INT 0x80
+#define ESTAT_LATECOL 0x10
+#define ESTAT_RXBUSY 0x04
+#define ESTAT_TXABRT 0x02
+#define ESTAT_CLKRDY 0x01
+/* ENC28J60 ECON2 Register Bit Definitions */
+#define ECON2_AUTOINC 0x80
+#define ECON2_PKTDEC 0x40
+#define ECON2_PWRSV 0x20
+#define ECON2_VRPS 0x08
+/* ENC28J60 ECON1 Register Bit Definitions */
+#define ECON1_TXRST 0x80
+#define ECON1_RXRST 0x40
+#define ECON1_DMAST 0x20
+#define ECON1_CSUMEN 0x10
+#define ECON1_TXRTS 0x08
+#define ECON1_RXEN 0x04
+#define ECON1_BSEL1 0x02
+#define ECON1_BSEL0 0x01
+/* ENC28J60 MACON1 Register Bit Definitions */
+#define MACON1_LOOPBK 0x10
+#define MACON1_TXPAUS 0x08
+#define MACON1_RXPAUS 0x04
+#define MACON1_PASSALL 0x02
+#define MACON1_MARXEN 0x01
+/* ENC28J60 MACON2 Register Bit Definitions */
+#define MACON2_MARST 0x80
+#define MACON2_RNDRST 0x40
+#define MACON2_MARXRST 0x08
+#define MACON2_RFUNRST 0x04
+#define MACON2_MATXRST 0x02
+#define MACON2_TFUNRST 0x01
+/* ENC28J60 MACON3 Register Bit Definitions */
+#define MACON3_PADCFG2 0x80
+#define MACON3_PADCFG1 0x40
+#define MACON3_PADCFG0 0x20
+#define MACON3_TXCRCEN 0x10
+#define MACON3_PHDRLEN 0x08
+#define MACON3_HFRMLEN 0x04
+#define MACON3_FRMLNEN 0x02
+#define MACON3_FULDPX 0x01
+/* ENC28J60 MICMD Register Bit Definitions */
+#define MICMD_MIISCAN 0x02
+#define MICMD_MIIRD 0x01
+/* ENC28J60 MISTAT Register Bit Definitions */
+#define MISTAT_NVALID 0x04
+#define MISTAT_SCAN 0x02
+#define MISTAT_BUSY 0x01
+/* ENC28J60 PHY PHCON1 Register Bit Definitions */
+#define PHCON1_PRST 0x8000
+#define PHCON1_PLOOPBK 0x4000
+#define PHCON1_PPWRSV 0x0800
+#define PHCON1_PDPXMD 0x0100
+/* ENC28J60 PHY PHSTAT1 Register Bit Definitions */
+#define PHSTAT1_PFDPX 0x1000
+#define PHSTAT1_PHDPX 0x0800
+#define PHSTAT1_LLSTAT 0x0004
+#define PHSTAT1_JBSTAT 0x0002
+/* ENC28J60 PHY PHCON2 Register Bit Definitions */
+#define PHCON2_FRCLINK 0x4000
+#define PHCON2_TXDIS 0x2000
+#define PHCON2_JABBER 0x0400
+#define PHCON2_HDLDIS 0x0100
+/* ENC28J60 PHY PHIE Register Bit Definitions */
+#define PHIE_PLNKIE 0x0010
+#define PHIE_PGEIE 0x0002
+
+/* ENC28J60 Packet Control Byte Bit Definitions */
+#define PKTCTRL_PHUGEEN 0x08
+#define PKTCTRL_PPADEN 0x04
+#define PKTCTRL_PCRCEN 0x02
+#define PKTCTRL_POVERRIDE 0x01
+
+/* SPI operation codes */
+#define ENC28J60_READ_CTRL_REG 0x00
+#define ENC28J60_READ_BUF_MEM 0x3A
+#define ENC28J60_WRITE_CTRL_REG 0x40
+#define ENC28J60_WRITE_BUF_MEM 0x7A
+#define ENC28J60_BIT_FIELD_SET 0x80
+#define ENC28J60_BIT_FIELD_CLR 0xA0
+#define ENC28J60_SOFT_RESET 0xFF
+
+/* The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata
+ buffer boundaries applied to internal 8K ram
+ the entire available packet buffer space is allocated
+
+ start with recbuf at 0/ */
+#define RXSTART_INIT 0x0
+/* receive buffer end */
+#define RXSTOP_INIT (0x1FFF-0x0600-1)
+/* start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (~1500 bytes) */
+#define TXSTART_INIT (0x1FFF-0x0600)
+/* stp TX buffer at end of mem */
+#define TXSTOP_INIT 0x1FFF
+
+/* max frame length which the conroller will accept: */
+#define MAX_FRAMELEN 1518 /* (note: maximum ethernet frame length would be 1518) */
+
+void enc28j60_spi_cs_status_change(int status);
+
+#if 1//defined CONFIG_PHOBOS_GENERAL
+#define PA5_A8 15
+#define PA1 12
+
+#define ENC28J60_CSL() enc28j60_spi_cs_status_change(0); //yunos_bsp_gpio_set_value(20, GPIO_VALUE_LOW); /* SPI_CS_LOW */
+
+#define ENC28J60_CSH() enc28j60_spi_cs_status_change(1); //yunos_bsp_gpio_set_value(20, GPIO_VALUE_HIGH); /* SPI_CS_HIGH */
+
+#else
+#define PA5_A8 47
+#define ENC28J60_CSL() enc28j60_spi_cs_status_change(0); //yunos_bsp_gpio_set_value(44, GPIO_VALUE_LOW); /* SPI_CS_LOW */
+
+#define ENC28J60_CSH() enc28j60_spi_cs_status_change(1); //yunos_bsp_gpio_set_value(44, GPIO_VALUE_HIGH); /* SPI_CS_HIGH */
+#endif
+
+typedef struct _spi_net_ops_t {
+ int (*init)(const uint8_t *macaddr);
+ int (*recv)(uint8_t *, uint16_t);
+ int (*send)(uint8_t *, uint16_t);
+ int (*reset)(void);
+ int (*irq_enable)(int);
+ int (*set_macaddr)(const uint8_t *macaddr);
+ int (*get_link_status)(void);
+} net_ops_t;
+
+enum enc28j60_reset {
+ RST_ENC28J60_ALL,
+ RST_ENC28J60_TX,
+ RST_ENC28J60_RX
+};
+
+int yunos_bsp_enc28j60_init(const uint8_t *macaddr);
+int yunos_bsp_enc28j60_reset(void);
+int yunos_bsp_enc28j60_get_link_status(void);
+int yunos_bsp_enc28j60_set_irq_enable(int enable);
+int yunos_bsp_enc28j60_get_interrupt_status(void);
+int yunos_bsp_enc28j60_set_interrupt_status(int status);
+//int yunos_bsp_enc28j60_set_interrupt(gpio_interrupt_t interrupt_cb);
+int yunos_bsp_enc28j60_get_pkt_cnt(void);
+int yunos_bsp_enc28j60_net_init(void);
+int yunos_bsp_enc28j60_set_macaddr(const uint8_t *macaddr);
+net_ops_t *yunos_bsp_spi_net_get_ctrl_ops(void);
+int yunos_bsp_enc28j60_handle_int_error(int status);
+
+int yunos_bsp_enc28j60_send_start(uint16_t len);
+void yunos_bsp_enc28j60_send_data(uint8_t *packet, uint16_t len);
+void yunos_bsp_enc28j60_send_end(void);
+
+int yunos_bsp_enc28j60_recv_start(uint16_t maxlen);
+int yunos_bsp_enc28j60_recv_data(uint8_t *packet, uint16_t len);
+void yunos_bsp_enc28j60_recv_end(void);
+
+void yunos_bsp_enc28j60_hard_reset(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ETHERNET_ENC28J60_H__ */
diff --git a/bsp/ck802/libraries/common/gpio/dw_gpio.c b/bsp/ck802/libraries/common/gpio/dw_gpio.c
new file mode 100644
index 0000000000..278fa1f3da
--- /dev/null
+++ b/bsp/ck802/libraries/common/gpio/dw_gpio.c
@@ -0,0 +1,528 @@
+/*
+ * 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 dw_gpio.c
+ * @brief CSI Source File for GPIO Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <stdbool.h>
+#include <stdio.h>
+#include "csi_core.h"
+#include "drv_gpio.h"
+#include "dw_gpio.h"
+
+
+#define ERR_GPIO(errno) (CSI_DRV_ERRNO_GPIO_BASE | errno)
+#define GPIO_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_GPIO(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+typedef struct {
+ uint32_t base; ///< handle register base
+ uint32_t irq; ///< irq of this handle
+ uint32_t pin_num; ///< pin number of this handle
+ uint32_t cb; ///< callback function
+ 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 {
+ gpio_port_handle_t handle;
+ uint8_t idx;
+ pin_t pin_name;
+} dw_gpio_pin_priv_t;
+
+static dw_gpio_priv_t gpio_handle[CONFIG_GPIO_NUM];
+static dw_gpio_pin_priv_t gpio_pin_handle[CONFIG_GPIO_PIN_NUM];
+
+/* Driver Capabilities */
+static const gpio_capabilities_t driver_capabilities = {
+ .interrupt_mode = 1, /* intrrupt mode */
+ .pull_mode = 1 /* pull mode */
+};
+//
+// Functions
+//
+
+static dw_gpio_reg_t *gpio_reg = NULL;
+static dw_gpio_control_reg_t *gpio_control_reg = NULL;
+
+
+static int32_t gpio_set_direction(
+ void *port,
+ gpio_direction_e direction
+)
+{
+ dw_gpio_priv_t *gpio_priv = port;
+
+ 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(EDRV_PARAMETER);
+ }
+
+ 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.
+ */
+
+int32_t gpio_read(uint32_t *value)
+{
+ *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;
+ 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;
+ 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(EDRV_UNSUPPORTED);
+
+ default:
+ return ERR_GPIO(EDRV_PARAMETER);
+ }
+
+ return 0;
+}
+
+/*
+ * Clear one or more interrupts of PortA.
+ * Parameters:
+ * pinno:
+ * return: SUCCESS.
+ */
+
+static void gpio_irq_clear(uint32_t idx)
+{
+ 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;
+ 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;
+
+ uint32_t val = gpio_control_reg->INTEN;
+ val &= ~(1 << offset);
+ gpio_control_reg->INTEN = val;
+}
+
+void dw_gpio_irqhandler(int idx)
+{
+ dw_gpio_priv_t *gpio_priv = &gpio_handle[idx];
+ uint32_t value = gpio_control_reg->INTSTATUS;
+ uint8_t i;
+
+ /* find the interrput pin */
+ for (i = 0; i < 32; i++) {
+ if (value == (1 << i)) {
+ break;
+ }
+ }
+
+ uint32_t offset = i;
+ uint32_t pin_idx = offset;
+
+ for (i = 0; i < idx; i++) {
+ pin_idx += gpio_handle[i].pin_num;
+ }
+
+ gpio_pin_handle_t pin = (gpio_pin_handle_t) &gpio_pin_handle[pin_idx];
+
+ /* execute the callback function */
+ if ((gpio_event_cb_t)(gpio_priv->cb)) {
+ ((gpio_event_cb_t)(gpio_priv->cb))(pin);
+ }
+ gpio_irq_clear(value); //clear the gpio interrupt
+}
+
+int32_t __attribute__((weak)) target_gpio_port_init(port_name_t port, uint32_t *base, uint32_t *irq, uint32_t *pin_num)
+{
+ return -1;
+}
+
+/**
+ \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.
+ \param[in] cb_event Pointer to \ref gpio_event_cb_t
+ \return gpio_port_handle
+*/
+gpio_port_handle_t csi_gpio_port_initialize(port_name_t port, gpio_event_cb_t cb_event)
+{
+ uint32_t i;
+ dw_gpio_priv_t *gpio_priv;
+
+ for (i = 0; i <= port; i++) {
+ /* obtain the gpio port information */
+ uint32_t base = 0u;
+ uint32_t pin_num;
+ uint32_t irq;
+ uint32_t idx = target_gpio_port_init(i, &base, &irq, &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;
+ }
+
+ gpio_reg = (dw_gpio_reg_t *)(gpio_priv->base);
+ gpio_control_reg = (dw_gpio_control_reg_t *)(gpio_priv->base + 0x30);
+
+ gpio_priv->cb = (uint32_t)cb_event;
+
+ drv_nvic_enable_irq(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;
+
+ gpio_priv->cb = NULL;
+
+ drv_nvic_disable_irq(gpio_priv->irq);
+
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle instance to operate.
+ \return \ref gpio_capabilities_t
+*/
+gpio_capabilities_t csi_gpio_get_io_capabilities(gpio_port_handle_t handle)
+{
+ return driver_capabilities;
+}
+
+/**
+ \brief config multiple pin within one handle
+ \param[in] handle gpio port handle to operate.
+ \param[in] mask the bitmask to identify which bits in the handle should be included (0 - ignore)
+ \param[in] mode \ref gpio_mode_e
+ \param[in] dir \ref gpio_direction_e
+ \return error code
+*/
+int32_t csi_gpio_port_config(gpio_port_handle_t handle, uint32_t mask, gpio_mode_e mode, gpio_direction_e dir)
+{
+ if (mask < 0) {
+ return ERR_GPIO(EDRV_PARAMETER);
+ }
+ GPIO_NULL_PARAM_CHK(handle);
+
+ dw_gpio_priv_t *gpio_priv = handle;
+ /*config the gpio mode direction mask bits */
+ gpio_priv->mode = mode;
+ gpio_priv->dir = dir;
+ gpio_priv->mask = mask;
+ uint32_t ret = gpio_set_direction(gpio_priv, dir);
+
+ return ret;
+}
+
+/**
+ \brief Write value to the handle(write value to multiple pins on one handle at the same time)
+ \param[in] handle gpio port handle to operate.
+ \param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
+ \param[in] value the value to be set
+ \return error code
+*/
+int32_t csi_gpio_port_write(gpio_port_handle_t handle, uint32_t mask, uint32_t value)
+{
+ if (mask < 0 || value < 0) {
+ return ERR_GPIO(EDRV_PARAMETER);
+ }
+ GPIO_NULL_PARAM_CHK(handle);
+
+ uint32_t port_value = mask & value;
+
+ dw_gpio_priv_t *gpio_priv = handle;
+ gpio_priv->value = port_value;
+ gpio_write(gpio_priv, mask);
+
+ return 0;
+
+}
+
+/**
+ \brief Read the current value on the handle(read value of multiple pins on one handle at the same time)
+ \param[in] handle gpio port handle to operate.
+ \param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
+ \param[out] value an integer with each bit corresponding to an associated handle pin setting
+ \return error code
+*/
+int32_t csi_gpio_port_read(gpio_port_handle_t handle, uint32_t mask, uint32_t *value)
+{
+ if (mask < 0) {
+ return ERR_GPIO(EDRV_PARAMETER);
+ }
+ GPIO_NULL_PARAM_CHK(handle);
+ GPIO_NULL_PARAM_CHK(value);
+
+ uint32_t port_value = 0;
+
+ gpio_read(&port_value);
+ *value = (mask & port_value);
+
+ return 0;
+
+}
+
+int32_t __attribute__((weak)) target_gpio_pin_init(pin_t gpio_pin, uint32_t *port_idx)
+{
+ return -1;
+}
+
+/**
+ \brief Initialize GPIO handle.
+ \param[in] gpio_pin Pointer to the pin_t.
+ \return gpio_pin_handle
+*/
+gpio_pin_handle_t csi_gpio_pin_initialize(pin_t gpio_pin)
+{
+ /* obtain the gpio pin information */
+ uint32_t port_idx;
+ uint32_t pin_idx = target_gpio_pin_init(gpio_pin, &port_idx);
+
+ dw_gpio_pin_priv_t *gpio_pin_priv = &(gpio_pin_handle[pin_idx]);
+ gpio_pin_priv->handle = (gpio_port_handle_t)&gpio_handle[port_idx];
+
+ uint32_t idx = pin_idx;
+ uint32_t i;
+
+ for (i = 0; i < port_idx; i++) {
+ idx = pin_idx - (gpio_handle[i].pin_num);
+ }
+
+ gpio_pin_priv->idx = idx;
+
+ return (gpio_pin_handle_t)gpio_pin_priv;
+}
+
+/**
+ \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 pin,
+ gpio_mode_e mode,
+ gpio_direction_e dir)
+{
+ GPIO_NULL_PARAM_CHK(pin);
+
+ /* config the gpio pin mode direction mask bits */
+ dw_gpio_pin_priv_t *gpio_pin_priv = pin;
+ dw_gpio_priv_t *gpio_priv = gpio_pin_priv->handle;
+
+ 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] pin 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 pin, bool value)
+{
+ GPIO_NULL_PARAM_CHK(pin);
+ if (value < 0) {
+ return ERR_GPIO(EDRV_PARAMETER);
+ }
+
+ dw_gpio_pin_priv_t *gpio_pin_priv = pin;
+ dw_gpio_priv_t *gpio_priv = gpio_pin_priv->handle;
+ uint8_t offset = gpio_pin_priv->idx;
+ uint32_t port_value = value << offset;
+
+ gpio_priv->value = port_value;
+ gpio_write(gpio_priv, (1 << offset));
+
+ return 0;
+
+}
+
+/**
+ \brief Get the value of selected GPIO pin.
+ \param[in] pin 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 pin, bool *value)
+{
+ GPIO_NULL_PARAM_CHK(pin);
+ if (value <= 0) {
+ return ERR_GPIO(EDRV_PARAMETER);
+ }
+
+ dw_gpio_pin_priv_t *gpio_pin_priv = pin;
+ uint32_t port_value;
+ uint8_t offset = gpio_pin_priv->idx;
+
+ gpio_read(&port_value);
+ *value = (port_value & (1 << offset)) >> offset;
+
+ return 0;
+}
+
+/**
+ \brief set GPIO interrupt mode.
+ \param[in] pin 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_irq_set(gpio_pin_handle_t pin, gpio_irq_mode_e mode, bool enable)
+{
+ GPIO_NULL_PARAM_CHK(pin);
+
+ uint32_t ret = 0;
+
+ if (enable) {
+ ret = gpio_set_irq_mode(pin, mode);
+
+ if (ret) {
+ return ret;
+ }
+ gpio_irq_enable(pin);
+
+ } else {
+ gpio_irq_disable(pin);
+
+ }
+
+ return ret;
+
+}
+
diff --git a/bsp/ck802/libraries/common/gpio/dw_gpio.h b/bsp/ck802/libraries/common/gpio/dw_gpio.h
new file mode 100644
index 0000000000..0cbd818ab1
--- /dev/null
+++ b/bsp/ck802/libraries/common/gpio/dw_gpio.h
@@ -0,0 +1,54 @@
+/*
+ * 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 dw_gpio.h
+ * @brief header file for GPIO Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _DW_GPIO_H_
+#define _DW_GPIO_H_
+
+#include "drv_gpio.h"
+#include "soc.h"
+
+
+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;
+
+#endif
+
diff --git a/bsp/ck802/libraries/common/iic/dw_iic.c b/bsp/ck802/libraries/common/iic/dw_iic.c
new file mode 100644
index 0000000000..ab1a788e89
--- /dev/null
+++ b/bsp/ck802/libraries/common/iic/dw_iic.c
@@ -0,0 +1,646 @@
+/*
+ * 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 dw_iic.c
+ * @brief CSI Source File for IIC Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include "csi_core.h"
+#include "drv_iic.h"
+#include "dw_iic.h"
+#include "soc.h"
+#include "string.h"
+
+#define ERR_IIC(errno) (CSI_DRV_ERRNO_I2C_BASE | errno)
+
+#define IIC_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_IIC(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ iic_event_cb_t cb_event;
+ void *cb_arg;
+ uint32_t rx_total_num;
+ uint32_t tx_total_num;
+ void *rx_buf;
+ void *tx_buf;
+ volatile uint32_t rx_cnt;
+ volatile uint32_t tx_cnt;
+ uint32_t status; ///< status of iic transfer
+} dw_iic_priv_t;
+
+static dw_iic_priv_t iic_instance[CONFIG_IIC_NUM];
+
+static const iic_capabilities_t iic_capabilities = {
+ .address_10_bit = 0 /* supports 10-bit addressing */
+};
+
+static inline void dw_iic_disable(dw_iic_reg_t *addr)
+{
+ /* First clear ACTIVITY, then Disable IIC */
+ addr->IC_CLR_ACTIVITY;
+ addr->IC_ENABLE = DW_IIC_DISABLE;
+
+}
+
+static inline void dw_iic_enable(dw_iic_reg_t *addr)
+{
+ addr->IC_ENABLE = DW_IIC_ENABLE;
+
+}
+
+static inline void dw_iic_set_transfer_speed(dw_iic_reg_t *addr, DWENUM_IIC_SPEED speed)
+{
+ uint16_t temp = addr->IC_CON;
+ temp &= ~((1 << 1) + (1 << 2));
+ temp |= speed << 1;
+ addr->IC_CON = temp;
+}
+
+static inline void dw_iic_set_target_address(dw_iic_reg_t *addr, uint16_t address)
+{
+ uint16_t temp = addr->IC_TAR;
+ temp &= 0xfc00;
+ temp |= address;
+ addr->IC_TAR = temp;
+}
+static inline void dw_iic_set_addr_mode(dw_iic_reg_t *addr, iic_address_mode_e addr_mode)
+{
+ uint16_t temp = addr->IC_TAR;
+ temp &= 0xefff;
+ temp |= addr_mode << 12;
+ addr->IC_TAR = temp;
+}
+
+static void dw_i2c_int_clear(dw_iic_reg_t *addr, DWENUM_IIC_INTERRUPT_TYPE type)
+{
+ uint32_t temp = 0;
+
+ switch (type) {
+ case DW_IIC_RX_UNDER:
+ temp = addr->IC_CLR_RX_UNDER;
+ break;
+
+ case DW_IIC_RX_OVER:
+ temp = addr->IC_CLR_RX_OVER;
+ break;
+
+ case DW_IIC_TX_OVER:
+ temp = addr->IC_CLR_TX_OVER;
+ break;
+
+ case DW_IIC_RD_REQ:
+ temp = addr->IC_CLR_RD_REQ;
+ break;
+
+ case DW_IIC_TX_ABRT:
+ temp = addr->IC_CLR_TX_ABRT;
+ break;
+
+ case DW_IIC_RX_DONE:
+ temp = addr->IC_CLR_RX_DONE;
+ break;
+
+ case DW_IIC_ACTIVITY:
+ temp = addr->IC_CLR_ACTIVITY;
+ break;
+
+ case DW_IIC_STOP_DET:
+ temp = addr->IC_CLR_STOP_DET;
+ break;
+
+ case DW_IIC_START_DET:
+ temp = addr->IC_CLR_START_DET;
+ break;
+
+ case DW_IIC_GEN_CALL:
+ temp = addr->IC_CLR_GEN_CALL;
+ break;
+
+ default:
+ temp = addr->IC_CLR_INTR;
+ }
+}
+
+/**
+ \brief interrupt service function for transmit FIFO empty interrupt.
+ \param[in] iic_priv pointer to iic private.
+*/
+static void dw_iic_intr_tx_empty(dw_iic_priv_t *iic_priv)
+{
+ dw_iic_reg_t *addr = (dw_iic_reg_t *)(iic_priv->base);
+
+ if (addr->IC_INTR_STAT & (1 << DW_IIC_TX_EMPTY)) {
+
+ uint32_t remain_txfifo = iic_priv->tx_total_num - iic_priv->tx_cnt;
+ uint8_t emptyfifo = (remain_txfifo > (DW_IIC_FIFO_MAX_LV - addr->IC_TXFLR)) ? DW_IIC_FIFO_MAX_LV - addr->IC_TXFLR : remain_txfifo;
+ uint32_t i = 0u;
+
+ for (i = 0; i < emptyfifo; i++) {
+ addr->IC_DATA_CMD = *((uint8_t *)(iic_priv->tx_buf)++);
+ }
+
+ iic_priv->tx_cnt += emptyfifo;
+
+ if (iic_priv->tx_cnt == iic_priv->tx_total_num) {
+ addr->IC_INTR_MASK &= ~(1 << DW_IIC_TX_EMPTY);
+ }
+ }
+
+ if (addr->IC_INTR_STAT & (1 << DW_IIC_TX_OVER)) {
+ dw_i2c_int_clear(addr, DW_IIC_TX_OVER);
+ iic_priv->status = IIC_STATE_ERROR;
+ dw_iic_disable(addr);
+
+ if (iic_priv->cb_event) {
+ iic_priv->cb_event(I2C_EVENT_BUS_ERROR, iic_priv->cb_arg);
+ }
+ }
+
+ if (addr->IC_INTR_STAT & (1 << DW_IIC_TX_ABRT)) {
+ dw_i2c_int_clear(addr, DW_IIC_TX_ABRT);
+ iic_priv->status = IIC_STATE_ERROR;
+ dw_iic_disable(addr);
+
+ if (iic_priv->cb_event) {
+ iic_priv->cb_event(I2C_EVENT_BUS_ERROR, iic_priv->cb_arg);
+ }
+
+ }
+
+ if (addr->IC_INTR_STAT & (1 << DW_IIC_STOP_DET)) {
+ iic_priv->status = IIC_STATE_DONE;
+ dw_i2c_int_clear(addr, DW_IIC_STOP_DET);
+
+ if (iic_priv->cb_event) {
+ dw_iic_disable(addr);
+ addr->IC_CLR_INTR;
+ iic_priv->cb_event(I2C_EVENT_TRANSFER_DONE, iic_priv->cb_arg);
+ }
+ }
+
+}
+/**
+ \brief interrupt service function for receive FIFO full interrupt .
+ \param[in] iic_priv pointer to iic private.
+*/
+static void dw_iic_intr_rx_full(dw_iic_priv_t *iic_priv)
+{
+ dw_iic_reg_t *addr = (dw_iic_reg_t *)(iic_priv->base);
+
+ if (addr->IC_INTR_STAT & (1 << DW_IIC_RX_FULL)) {
+ uint8_t emptyfifo = addr->IC_RXFLR;
+ uint32_t i = 0u;
+
+ for (i = 0; i < emptyfifo ; i++) {
+ *((uint8_t *)(iic_priv->rx_buf++)) = ((addr->IC_DATA_CMD) & 0xff);
+ }
+
+ iic_priv->rx_cnt += emptyfifo;
+
+ if (iic_priv->rx_cnt != iic_priv->rx_total_num) {
+ addr->IC_DATA_CMD = 1 << 8;
+ }
+ }
+
+ if (addr->IC_INTR_STAT & (1 << DW_IIC_RX_OVER)) {
+ dw_i2c_int_clear(addr, DW_IIC_RX_OVER);
+ iic_priv->status = IIC_STATE_ERROR;
+ dw_iic_disable(addr);
+
+ if (iic_priv->cb_event) {
+ iic_priv->cb_event(I2C_EVENT_BUS_ERROR, iic_priv->cb_arg);
+ }
+ }
+
+ if (addr->IC_INTR_STAT & (1 << DW_IIC_RX_FULL)) {
+ dw_i2c_int_clear(addr, DW_IIC_RX_FULL);
+ iic_priv->status = IIC_STATE_ERROR;
+ dw_iic_disable(addr);
+
+ if (iic_priv->cb_event) {
+ iic_priv->cb_event(I2C_EVENT_BUS_ERROR, iic_priv->cb_arg);
+ }
+
+ }
+
+ if (addr->IC_INTR_STAT & (1 << DW_IIC_STOP_DET)) {
+ dw_i2c_int_clear(addr, DW_IIC_STOP_DET);
+
+ if (iic_priv->rx_cnt == iic_priv->rx_total_num) {
+ iic_priv->status = IIC_STATE_DONE;
+ dw_iic_disable(addr);
+ addr->IC_CLR_INTR;
+
+ if (iic_priv->cb_event) {
+ iic_priv->cb_event(I2C_EVENT_TRANSFER_DONE, iic_priv->cb_arg);
+ }
+ }
+ }
+
+}
+void dw_iic_irqhandler(int32_t idx)
+{
+ dw_iic_priv_t *iic_priv = &iic_instance[idx];
+ dw_iic_reg_t *addr = (dw_iic_reg_t *)(iic_priv->base);
+
+ if (addr->IC_INTR_STAT & (1 << DW_IIC_TX_ABRT)) {
+ /* If arbitration fault, it indicates either a slave device not
+ * responding as expected, or other master which is not supported
+ * by this SW.
+ */
+ dw_i2c_int_clear(addr, DW_IIC_TX_ABRT);
+ iic_priv->status = IIC_STATE_DONE;
+
+ if (iic_priv->cb_event) {
+ dw_iic_disable(addr);
+ iic_priv->cb_event(I2C_EVENT_BUS_ERROR, iic_priv->cb_arg);
+ return;
+ }
+ }
+
+ switch (iic_priv->status) {
+ /* send data to slave */
+ case IIC_STATE_DATASEND: {
+ dw_iic_intr_tx_empty(iic_priv);
+ break;
+ }
+
+ /* wait for data from slave */
+ case IIC_STATE_WFDATA: {
+ dw_iic_intr_rx_full(iic_priv);
+ break;
+ }
+
+ /* unexpected state,SW fault */
+ default: {
+ dw_iic_disable(addr);
+
+ if (iic_priv->cb_event) {
+ iic_priv->cb_event(I2C_EVENT_BUS_ERROR, iic_priv->cb_arg);
+ }
+ }
+ }
+}
+
+int32_t __attribute__((weak)) target_iic_init(pin_t scl, pin_t sda, uint32_t *base, uint32_t *irq)
+{
+ return -1;
+}
+
+/**
+ \brief Initialize IIC Interface. 1. Initializes the resources needed for the IIC interface 2.registers event callback function
+ \param[in] handle iic handle to operate.
+ \param[in] cb_event Pointer to \ref iic_event_cb_t
+ \return error code
+*/
+iic_handle_t csi_iic_initialize(pin_t scl, pin_t sda, iic_event_cb_t cb_event, void *cb_arg)
+{
+ uint32_t base = 0u;
+ uint32_t irq = 0u;
+
+ int32_t idx = target_iic_init(scl, sda, &base, &irq);
+
+ if (idx < 0 || idx >= CONFIG_IIC_NUM) {
+ return NULL;
+ }
+
+ dw_iic_priv_t *iic_priv = &iic_instance[idx];
+ iic_priv->base = base;
+ iic_priv->irq = irq;
+
+
+ iic_priv->cb_event = cb_event;
+ iic_priv->cb_arg = cb_arg;
+ iic_priv->rx_total_num = 0;
+ iic_priv->tx_total_num = 0;
+ iic_priv->rx_buf = NULL;
+ iic_priv->tx_buf = NULL;
+ iic_priv->rx_cnt = 0;
+ iic_priv->tx_cnt = 0;
+ iic_priv->status = 0;
+
+ dw_iic_reg_t *addr = (dw_iic_reg_t *)(iic_priv->base);
+
+ /* mask all interrupts */
+ addr->IC_INTR_MASK = 0x00;
+ addr->IC_CON = DW_IIC_CON_DEFAUL;
+ addr->IC_INTR_MASK |= 1 << DW_IIC_TX_ABRT;
+ addr->IC_INTR_MASK |= 1 << DW_IIC_TX_OVER;
+ addr->IC_INTR_MASK |= 1 << DW_IIC_RX_OVER;
+ addr->IC_INTR_MASK |= 1 << DW_IIC_RX_FULL;
+ addr->IC_INTR_MASK |= 1 << DW_IIC_STOP_DET;
+
+ drv_nvic_enable_irq(iic_priv->irq);
+
+ return iic_priv;
+}
+
+/**
+ \brief De-initialize IIC Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle iic handle to operate.
+ \return error code
+*/
+int32_t csi_iic_uninitialize(iic_handle_t handle)
+{
+ IIC_NULL_PARAM_CHK(handle);
+
+ /* First clear ACTIVITY, then Disable IIC */
+ dw_iic_priv_t *iic_priv = handle;
+ dw_iic_reg_t *addr = (dw_iic_reg_t *)(iic_priv->base);
+
+ addr->IC_CLR_ACTIVITY;
+ addr->IC_INTR_MASK = 0x00;
+ addr->IC_ENABLE = DW_IIC_DISABLE;
+
+ iic_priv->cb_event = NULL;
+ iic_priv->rx_total_num = 0;
+ iic_priv->tx_total_num = 0;
+ iic_priv->rx_buf = NULL;
+ iic_priv->tx_buf = NULL;
+ iic_priv->rx_cnt = 0;
+ iic_priv->tx_cnt = 0;
+ iic_priv->status = 0;
+
+ drv_nvic_disable_irq(iic_priv->irq);
+
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \return \ref iic_capabilities_t
+*/
+iic_capabilities_t csi_iic_get_capabilities(iic_handle_t handle)
+{
+ return iic_capabilities;
+}
+
+/**
+ \brief config iic.
+ \param[in] handle iic handle to operate.
+ \param[in] mode \ref iic_mode_e.if negative, then this attribute not changed
+ \param[in] speed \ref iic_speed_e.if negative, then this attribute not changed
+ \param[in] addr_mode \ref iic_address_mode_e.if negative, then this attribute not changed
+ \param[in] slave_addr slave address.if negative, then this attribute not changed
+ \return error code
+*/
+int32_t csi_iic_config(iic_handle_t handle,
+ iic_mode_e mode,
+ iic_speed_e speed,
+ iic_address_mode_e addr_mode,
+ int32_t slave_addr)
+{
+ IIC_NULL_PARAM_CHK(handle);
+
+ if (mode >= 0) {
+ switch (mode) {
+ case IIC_MODE_MASTER:
+ break;
+
+ case IIC_MODE_SLAVE:
+ return ERR_IIC(EDRV_UNSUPPORTED);
+ break;
+
+ default:
+ return ERR_IIC(EDRV_PARAMETER);
+ }
+ }
+
+ dw_iic_reg_t *addr = (dw_iic_reg_t *)(((dw_iic_priv_t *)handle)->base);
+
+ if (speed >= 0) {
+ switch (speed) {
+ case I2C_BUS_SPEED_STANDARD:
+ dw_iic_set_transfer_speed(addr, DW_IIC_STANDARDSPEED);
+ break;
+
+ case I2C_BUS_SPEED_FAST:
+ dw_iic_set_transfer_speed(addr, DW_IIC_FASTSPEED);
+ break;
+
+ case I2C_BUS_SPEED_FAST_PLUS:
+ return ERR_IIC(EDRV_UNSUPPORTED);
+
+ case I2C_BUS_SPEED_HIGH:
+ dw_iic_set_transfer_speed(addr, DW_IIC_HIGHSPEED);
+ break;
+
+ default:
+ return ERR_IIC(EDRV_PARAMETER);
+ }
+ }
+
+ if (addr_mode >= 0) {
+ switch (addr_mode) {
+ case I2C_ADDRESS_10BIT:
+ case I2C_ADDRESS_7BIT:
+ dw_iic_set_addr_mode(addr, addr_mode);
+ break;
+
+ default:
+ return ERR_IIC(EDRV_PARAMETER);
+ }
+ }
+
+ if (slave_addr >= 0) {
+ dw_iic_set_target_address(addr, slave_addr);
+ }
+
+ return 0;
+}
+
+/**
+ \brief Start transmitting data as I2C Master.
+ \param[in] handle iic handle to operate.
+ \param[in] data Pointer to buffer with data to transmit to I2C Slave
+ \param[in] num Number of data items to send
+ \param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
+ \return error code
+*/
+int32_t csi_iic_master_send(iic_handle_t handle, const void *data, uint32_t num, bool xfer_pending)
+{
+ IIC_NULL_PARAM_CHK(handle);
+
+ if (data == NULL || num == 0) {
+ return ERR_IIC(EDRV_PARAMETER);
+ }
+
+ dw_iic_priv_t *iic_priv = handle;
+ dw_iic_reg_t *addr = (dw_iic_reg_t *)(iic_priv->base);
+
+ iic_priv->tx_buf = (uint8_t *)data;
+ iic_priv->tx_total_num = num;
+ iic_priv->tx_cnt = 0;
+ iic_priv->status = IIC_STATE_DATASEND;
+
+ dw_iic_disable(addr);
+ addr->IC_CLR_INTR;
+
+ uint32_t length = (num > DW_IIC_FIFO_MAX_LV) ? DW_IIC_FIFO_MAX_LV : num;
+ addr->IC_TX_TL = DW_IIC_TXFIFO_LV;
+
+ dw_iic_enable(addr);
+ uint32_t i = 0u;
+
+ for (i = 0; i < length; i++) {
+ addr->IC_DATA_CMD = *((uint8_t *)(iic_priv->tx_buf)++);
+ }
+
+ iic_priv->tx_cnt += length;
+
+ /* open corresponding interrupts */
+ addr->IC_INTR_MASK |= 1 << DW_IIC_TX_EMPTY;
+
+ return 0;
+
+}
+
+/**
+ \fn int32_t csi_iic_master_receive (iic_handle_t handle,const void *data, uint32_t num, bool xfer_pending)
+ \brief Start receiving data as I2C Master.
+ \param[in] handle iic handle to operate.
+ \param[out] data Pointer to buffer for data to receive from IIC receiver
+ \param[in] num Number of data items to receive
+ \param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
+ \return error code
+*/
+int32_t csi_iic_master_receive(iic_handle_t handle, const void *data, uint32_t num, bool xfer_pending)
+{
+ IIC_NULL_PARAM_CHK(handle);
+
+ if (data == NULL || num == 0) {
+ return ERR_IIC(EDRV_PARAMETER);
+ }
+
+ dw_iic_priv_t *iic_priv = handle;
+
+ iic_priv->rx_buf = (uint8_t *)data;
+ iic_priv->rx_total_num = num;
+ iic_priv->rx_cnt = 0;
+ iic_priv->status = IIC_STATE_WFDATA;
+
+ dw_iic_reg_t *addr = (dw_iic_reg_t *)(iic_priv->base);
+ dw_iic_disable(addr);
+
+ int32_t tmp = addr->IC_CLR_INTR;
+ addr->IC_RX_TL = DW_IIC_FIFO_MAX_LV; /* Sets receive FIFO threshold */
+
+ tmp = addr->IC_CLR_INTR;
+ addr->IC_RX_TL = DW_IIC_RXFIFO_LV; /* Sets receive FIFO threshold */
+ dw_iic_enable(addr);
+ addr->IC_DATA_CMD = 1 << 8;
+
+ return 0;
+
+}
+
+/**
+ \brief Start transmitting data as I2C Slave.
+ \param[in] handle iic handle to operate.
+ \param[in] data Pointer to buffer with data to transmit to I2C Master
+ \param[in] num Number of data items to send
+ \return error code
+*/
+int32_t csi_iic_slave_send(iic_handle_t handle, const void *data, uint32_t num)
+{
+ return ERR_IIC(EDRV_UNSUPPORTED);
+}
+
+/**
+ \fn int32_t csi_iic_slave_receive (iic_handle_t handle, const void *data, uint32_t num)
+ \brief Start receiving data as I2C Slave.
+ \param[in] handle iic handle to operate.
+ \param[out] data Pointer to buffer for data to receive from I2C Master
+ \param[in] num Number of data items to receive
+ \return error code
+*/
+int32_t csi_iic_slave_receive(iic_handle_t handle, const void *data, uint32_t num)
+{
+ return ERR_IIC(EDRV_UNSUPPORTED);
+}
+
+/**
+ \brief abort transfer.
+ \param[in] handle iic handle to operate.
+ \return error code
+*/
+int32_t csi_iic_abort_transfer(iic_handle_t handle)
+{
+ IIC_NULL_PARAM_CHK(handle);
+
+ dw_iic_priv_t *iic_priv = handle;
+ dw_iic_reg_t *addr = (dw_iic_reg_t *)(iic_priv->base);
+
+ dw_iic_disable(addr);
+ iic_priv->rx_cnt = 0;
+ iic_priv->tx_cnt = 0;
+ iic_priv->rx_buf = NULL;
+ iic_priv->tx_buf = NULL;
+ return 0;
+}
+
+
+/**
+ \brief Get IIC status.
+ \param[in] handle iic handle to operate.
+ \return IIC status \ref iic_status_t
+*/
+iic_status_t csi_iic_get_status(iic_handle_t handle)
+{
+ iic_status_t iic_status = {0};
+
+ if (handle == NULL) {
+ return iic_status;
+ }
+
+ dw_iic_priv_t *iic_priv = handle;
+ dw_iic_reg_t *addr = (dw_iic_reg_t *)(iic_priv->base);
+
+ int32_t tmp = addr->IC_STATUS;
+
+ if (tmp & 0x1) {
+ iic_status.busy = 1;
+
+ if (tmp & 0x40) {
+ iic_status.mode = 0;
+ } else {
+ iic_status.mode = 1;
+ }
+ }
+
+ if (iic_priv->status == IIC_STATE_WFDATA) {
+ iic_status.direction = 1;
+ }
+
+ if (addr->IC_RAW_INTR_STAT & 0x800) {
+ iic_status.general_call = 1;
+ }
+
+ if (iic_priv->status == IIC_STATE_ERROR) {
+ iic_status.bus_error = 1;
+ }
+
+ return iic_status;
+}
+
diff --git a/bsp/ck802/libraries/common/iic/dw_iic.h b/bsp/ck802/libraries/common/iic/dw_iic.h
new file mode 100644
index 0000000000..8ce20e818a
--- /dev/null
+++ b/bsp/ck802/libraries/common/iic/dw_iic.h
@@ -0,0 +1,123 @@
+/*
+ * 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 dw_iic.h
+ * @brief header File for IIC Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef __DW_IIC_H
+#define __DW_IIC_H
+#include "soc.h"
+
+/*
+ * Define the speed of I2C
+ */
+typedef enum {
+ DW_IIC_STANDARDSPEED = 1,
+ DW_IIC_FASTSPEED = 2,
+ DW_IIC_HIGHSPEED = 3
+} DWENUM_IIC_SPEED;
+
+enum i2c_state_e {
+ IIC_STATE_NONE = 0, /* Send start + (first part of) address. */
+ IIC_STATE_DATASEND, /* Send data. */
+ IIC_STATE_WFDATA, /* Wait for data. */
+ IIC_STATE_WFSTOPSENT, /* Wait for STOP to have been transmitted. */
+ IIC_STATE_DONE, /* Transfer completed successfully. */
+ IIC_STATE_ERROR /* Transfer error. */
+};
+/*
+ * Define the interrupt type of I2C
+ */
+typedef enum {
+ DW_IIC_RX_UNDER = 0,
+ DW_IIC_RX_OVER = 1,
+ DW_IIC_RX_FULL = 2,
+ DW_IIC_TX_OVER = 3,
+ DW_IIC_TX_EMPTY = 4,
+ DW_IIC_RD_REQ = 5,
+ DW_IIC_TX_ABRT = 6,
+ DW_IIC_RX_DONE = 7,
+ DW_IIC_ACTIVITY = 8,
+ DW_IIC_STOP_DET = 9,
+ DW_IIC_START_DET = 10,
+ DW_IIC_GEN_CALL = 11
+} DWENUM_IIC_INTERRUPT_TYPE;
+
+/*
+ * I2C register bit definitions
+ */
+#define DW_IIC_DISABLE 0
+#define DW_IIC_ENABLE 1
+#define DW_IIC_FIFO_MAX_LV 0x8
+#define DW_IIC_TXFIFO_LV 0x2
+#define DW_IIC_RXFIFO_LV 0x0
+
+#define DW_IIC_RXFIFO_FULL (0x1 << 4)
+#define DW_IIC_RXFIFO_NOT_EMPTY (0x1 << 3)
+#define DW_IIC_TXFIFO_EMPTY (0x1 << 2)
+#define DW_IIC_TXFIFO_NOT_FULL (0x1 << 1)
+#define DW_IIC_STATUS_ACTIVITY 0x1
+
+#define DW_IIC_CON_DEFAUL 0x23
+
+typedef struct {
+ __IOM uint32_t IC_CON; /* Offset: 0x000 (R/W) Receive buffer register */
+ __IOM uint32_t IC_TAR; /* Offset: 0x004 (R/W) Transmission hold register */
+ __IOM uint32_t IC_SAR; /* Offset: 0x008 (R/W) Clock frequency division low section register */
+ __IOM uint32_t IC_HS_MADDR; /* Offset: 0x00c (R/W) Clock frequency division high section register */
+ __IOM uint32_t IC_DATA_CMD; /* Offset: 0x010 (R/W) Interrupt enable register */
+ __IOM uint32_t IC_SS_SCL_HCNT; /* Offset: 0x014 (R/W) Interrupt indicia register */
+ __IOM uint32_t IC_SS_SCL_LCNT; /* Offset: 0x018 (R/W) Transmission control register */
+ __IOM uint32_t IC_FS_SCL_HCNT; /* Offset: 0x01c (R/W) Modem control register */
+ __IOM uint32_t IC_FS_SCL_LCNT; /* Offset: 0x020 (R/W) Transmission state register */
+ __IOM uint32_t IC_HS_SCL_HCNT; /* Offset: 0x024 (R/W) Transmission state register */
+ __IOM uint32_t IC_HS_SCL_LCNT; /* Offset: 0x028 (R/W) Transmission state register */
+ __IOM uint32_t IC_INTR_STAT; /* Offset: 0x02c (R) Transmission state register */
+ __IOM uint32_t IC_INTR_MASK; /* Offset: 0x030 (R/W) Transmission state register */
+ __IOM uint32_t IC_RAW_INTR_STAT; /* Offset: 0x034 (R) Transmission state register */
+ __IOM uint32_t IC_RX_TL; /* Offset: 0x038 (R/W) Transmission state register */
+ __IOM uint32_t IC_TX_TL; /* Offset: 0x03c (R/W) Transmission state register */
+ __IOM uint32_t IC_CLR_INTR; /* Offset: 0x040 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_RX_UNDER; /* Offset: 0x044 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_RX_OVER; /* Offset: 0x048 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_TX_OVER; /* Offset: 0x04c (R) Transmission state register */
+ __IOM uint32_t IC_CLR_RD_REQ; /* Offset: 0x050 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_TX_ABRT; /* Offset: 0x054 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_RX_DONE; /* Offset: 0x058 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_ACTIVITY; /* Offset: 0x05c (R) Transmission state register */
+ __IOM uint32_t IC_CLR_STOP_DET; /* Offset: 0x060 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_START_DET; /* Offset: 0x064 (R) Transmission state register */
+ __IOM uint32_t IC_CLR_GEN_CALL; /* Offset: 0x068 (R) Transmission state register */
+ __IOM uint32_t IC_ENABLE; /* Offset: 0x06c (R/W) Transmission state register */
+ __IOM uint32_t IC_STATUS; /* Offset: 0x070 (R) Transmission state register */
+ __IOM uint32_t IC_TXFLR; /* Offset: 0x074 (R) Transmission state register */
+ __IOM uint32_t IC_RXFLR; /* Offset: 0x078 (R) Transmission state register */
+ uint32_t RESERVED; /* Offset: 0x014 (R/ ) Transmission state register */
+ __IOM uint32_t IC_TX_ABRT_SOURCE; /* Offset: 0x080 (R/W) Transmission state register */
+ __IOM uint32_t IC_SAR1; /* Offset: 0x084 (R/W) Transmission state register */
+ __IOM uint32_t IC_DMA_CR; /* Offset: 0x088 (R/W) Transmission state register */
+ __IOM uint32_t IC_DMA_TDLR; /* Offset: 0x08c (R/W) Transmission state register */
+ __IOM uint32_t IC_DMA_RDLR; /* Offset: 0x090 (R/W) Transmission state register */
+ __IOM uint32_t IC_SAR2; /* Offset: 0x094 (R/W) Transmission state register */
+ __IOM uint32_t IC_SAR3; /* Offset: 0x098 (R/W) Transmission state register */
+ __IOM uint32_t IC_MULTI_SLAVE; /* Offset: 0x09c (R/W) Transmission state register */
+ __IOM uint32_t IC_GEN_CALL_EN; /* Offset: 0x0a0 (R/W) Transmission state register */
+} dw_iic_reg_t;
+
+#endif /* __DW_IIC_H */
diff --git a/bsp/ck802/libraries/common/pwm/ck_pwm.c b/bsp/ck802/libraries/common/pwm/ck_pwm.c
new file mode 100644
index 0000000000..10f2ed7646
--- /dev/null
+++ b/bsp/ck802/libraries/common/pwm/ck_pwm.c
@@ -0,0 +1,315 @@
+/*
+ * 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 ck_pwm.c
+ * @brief CSI Source File for PWM Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include "ck_pwm.h"
+#include "drv_pwm.h"
+#include "soc.h"
+
+#define ERR_PWM(errno) (CSI_DRV_ERRNO_PWM_BASE | errno)
+
+#define PWM_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_PWM(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ uint32_t ch_num;
+} ck_pwm_priv_t;
+
+static ck_pwm_priv_t pwm_instance[CONFIG_PWM_NUM];
+
+int32_t __attribute__((weak)) target_pwm_init(pin_t pwm_pin, uint32_t *ch_num, uint32_t *base, uint32_t *irq)
+{
+ return -1;
+}
+
+/**
+ \brief Initialize PWM Interface. 1. Initializes the resources needed for the PWM interface 2.registers event callback function
+ \param[in] pwm pin of gpio
+ \return handle pwm handle to operate.
+*/
+pwm_handle_t drv_pwm_initialize(pin_t pwm_pin)
+{
+ uint32_t base = 0u;
+ uint32_t irq = 0u;
+ uint32_t ch_num = 0u;
+
+ int32_t idx = target_pwm_init(pwm_pin, &ch_num, &base, &irq);
+
+ if (idx < 0 || idx >= CONFIG_PWM_NUM) {
+ return NULL;
+ }
+
+ ck_pwm_priv_t *pwm_priv = &pwm_instance[idx];
+
+ pwm_priv->base = base;
+ pwm_priv->irq = irq;
+ pwm_priv->ch_num = ch_num;
+
+ return pwm_priv;
+}
+
+/**
+ \brief De-initialize PWM Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle pwm handle to operate.
+ \return \ref execution_status
+*/
+int32_t drv_pwm_uninitialize(pwm_handle_t handle)
+{
+ PWM_NULL_PARAM_CHK(handle);
+
+ return 0;
+}
+
+/**
+ \brief config pwm mode.
+ \param[in] handle pwm handle to operate.
+ \param[in] sysclk configured system clock.
+ \param[in] period_us the PWM period in us
+ \param[in] duty the PMW duty. ( 0 - 10000 represents 0% - 100% ,other values are invalid)
+ \return \ref execution_status
+*/
+int32_t drv_pwm_config(pwm_handle_t handle, uint32_t sysclk, uint32_t period_us, uint32_t duty)
+{
+ if (handle == NULL || duty > 10000) {
+ return ERR_PWM(EDRV_PARAMETER);
+ }
+
+ ck_pwm_priv_t *pwm_priv = handle;
+ uint32_t chn = pwm_priv->ch_num;
+
+ uint32_t counter = (sysclk / 1000000 * period_us);
+
+ if (counter >= 0xffff) {
+ return ERR_PWM(EDRV_PARAMETER);
+ }
+
+ uint32_t data_width;
+
+ data_width = (uint32_t)((counter * duty / 10000));
+
+ ck_pwm_reg_t *addr = (ck_pwm_reg_t *)(pwm_priv->base);
+ uint32_t ctl_tmp = addr->PWMCTL;
+ uint32_t temp;
+
+ if (chn == CKENUM_PWM_CH0 || chn == CKENUM_PWM_CH1) {
+ ctl_tmp &= 0xfffffffe;
+ addr->PWMCTL = ctl_tmp | (uint32_t)CKENUM_PWM_COUNT_UP;
+
+ temp = addr->PWM01LOAD;
+ temp &= 0xffff0000;
+ addr->PWM01LOAD = temp | counter;
+
+ temp = addr->PWM0CMP;
+
+ if (chn == CKENUM_PWM_CH0) {
+ temp &= 0xffff0000;
+ addr->PWM0CMP = temp | data_width;
+ } else {
+ temp &= 0x0000ffff;
+ addr->PWM0CMP = temp | data_width << 16;
+ }
+ }
+
+ if (chn == CKENUM_PWM_CH2 || chn == CKENUM_PWM_CH3) {
+ ctl_tmp &= 0xfffffffd;
+ addr->PWMCTL = ctl_tmp | (uint32_t)CKENUM_PWM_COUNT_UP << 1;
+
+ temp = addr->PWM01LOAD;
+ temp &= 0x0000ffff;
+ addr->PWM01LOAD = temp | counter << 16 ;
+
+ temp = addr->PWM1CMP;
+
+ if (chn == CKENUM_PWM_CH2) {
+ temp &= 0xffff0000;
+ addr->PWM1CMP = temp | data_width;
+ } else {
+ temp &= 0x0000ffff;
+ addr->PWM1CMP = temp | data_width << 16;
+ }
+ }
+
+ if (chn == CKENUM_PWM_CH4 || chn == CKENUM_PWM_CH5) {
+ ctl_tmp &= 0xfffffffb;
+ addr->PWMCTL = ctl_tmp | (uint32_t)CKENUM_PWM_COUNT_UP << 2;
+
+ temp = addr->PWM23LOAD;
+ temp &= 0xffff0000;
+ addr->PWM23LOAD = temp | counter;
+
+ temp = addr->PWM2CMP;
+
+ if (chn == CKENUM_PWM_CH4) {
+ temp &= 0xffff0000;
+ addr->PWM2CMP = temp | data_width;
+ } else {
+ temp &= 0x0000ffff;
+ addr->PWM2CMP = temp | data_width << 16;
+ }
+ }
+
+ if (chn == CKENUM_PWM_CH6 || chn == CKENUM_PWM_CH7) {
+ ctl_tmp &= 0xfffffff7;
+ addr->PWMCTL = ctl_tmp | (uint32_t)CKENUM_PWM_COUNT_UP << 3;
+
+ temp = addr->PWM23LOAD;
+ temp &= 0x0000ffff;
+ addr->PWM23LOAD = temp | counter << 16 ;
+
+ temp = addr->PWM3CMP;
+
+ if (chn == CKENUM_PWM_CH6) {
+ temp &= 0xffff0000;
+ addr->PWM3CMP = temp | data_width;
+ } else {
+ temp &= 0x0000ffff;
+ addr->PWM3CMP = temp | data_width << 16;
+ }
+ }
+
+ if (chn == CKENUM_PWM_CH8 || chn == CKENUM_PWM_CH9) {
+ ctl_tmp &= 0xffffffef;
+ addr->PWMCTL = ctl_tmp | (uint32_t)CKENUM_PWM_COUNT_UP << 4;
+
+ temp = addr->PWM45LOAD;
+ temp &= 0xffff0000;
+ addr->PWM45LOAD = temp | counter ;
+
+ temp = addr->PWM4CMP;
+
+ if (chn == CKENUM_PWM_CH8) {
+ temp &= 0xffff0000;
+ addr->PWM4CMP = temp | data_width;
+ } else {
+ temp &= 0x0000ffff;
+ addr->PWM4CMP = temp | data_width << 16;
+ }
+ }
+
+ if (chn == CKENUM_PWM_CH10 || chn == CKENUM_PWM_CH11) {
+ ctl_tmp &= 0xffffffdf;
+ addr->PWMCTL = ctl_tmp | (uint32_t)CKENUM_PWM_COUNT_UP << 5;
+
+ temp = addr->PWM45LOAD;
+ temp &= 0x0000ffff;
+ addr->PWM45LOAD = temp | counter << 16 ;
+
+ temp = addr->PWM5CMP;
+
+ if (chn == CKENUM_PWM_CH10) {
+ temp &= 0xffff0000;
+ addr->PWM5CMP = temp | data_width;
+ } else {
+ temp &= 0x0000ffff;
+ addr->PWM5CMP = temp | data_width << 16;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ \brief start generate pwm signal.
+ \param[in] handle pwm handle to operate.
+ \param[in] pwm channel number.
+ \return \ref execution_status
+*/
+int32_t drv_pwm_start(pwm_handle_t handle)
+{
+ PWM_NULL_PARAM_CHK(handle);
+
+ ck_pwm_priv_t *pwm_priv = handle;
+ ck_pwm_reg_t *addr = (ck_pwm_reg_t *)(pwm_priv->base);
+ uint32_t chn = pwm_priv->ch_num;
+
+ if (chn == CKENUM_PWM_CH0 || chn == CKENUM_PWM_CH1) {
+ addr->PWMCFG |= 0x00000003; /* PWM0 output enable */
+ }
+
+ if (chn == CKENUM_PWM_CH2 || chn == CKENUM_PWM_CH3) {
+ addr->PWMCFG |= 0x0000000C; /* PWM1 output enable */
+ }
+
+ if (chn == CKENUM_PWM_CH4 || chn == CKENUM_PWM_CH5) {
+ addr->PWMCFG |= 0x00000030; /* PWM2 output enable */
+ }
+
+ if (chn == CKENUM_PWM_CH6 || chn == CKENUM_PWM_CH7) {
+ addr->PWMCFG |= 0x000000C0; /* PWM3 output enable */
+ }
+
+ if (chn == CKENUM_PWM_CH8 || chn == CKENUM_PWM_CH9) {
+ addr->PWMCFG |= 0x00000300; /* PWM4 output enable */
+ }
+
+ if (chn == CKENUM_PWM_CH10 || chn == CKENUM_PWM_CH11) {
+ addr->PWMCFG |= 0x00000C00; /* PWM5 output enable */
+ }
+
+ return 0;
+}
+
+/**
+ \brief Stop generate pwm signal.
+ \param[in] handle pwm handle to operate.
+ \return \ref execution_status
+*/
+int32_t drv_pwm_stop(pwm_handle_t handle)
+{
+ PWM_NULL_PARAM_CHK(handle);
+
+ ck_pwm_priv_t *pwm_priv = handle;
+ ck_pwm_reg_t *addr = (ck_pwm_reg_t *)(pwm_priv->base);
+ uint32_t chn = pwm_priv->ch_num;
+
+ if (chn == CKENUM_PWM_CH0 || chn == CKENUM_PWM_CH1) {
+ addr->PWMCFG &= ~0x00000003; /* PWM0 output disable */
+ }
+
+ if (chn == CKENUM_PWM_CH2 || chn == CKENUM_PWM_CH3) {
+ addr->PWMCFG &= ~0x0000000C; /* PWM1 output disable */
+ }
+
+ if (chn == CKENUM_PWM_CH4 || chn == CKENUM_PWM_CH5) {
+ addr->PWMCFG &= ~0x00000030; /* PWM2 output disable */
+ }
+
+ if (chn == CKENUM_PWM_CH6 || chn == CKENUM_PWM_CH7) {
+ addr->PWMCFG &= ~0x000000C0; /* PWM3 output disable */
+ }
+
+ if (chn == CKENUM_PWM_CH8 || chn == CKENUM_PWM_CH9) {
+ addr->PWMCFG &= ~0x00000300; /* PWM4 output disable */
+ }
+
+ if (chn == CKENUM_PWM_CH10 || chn == CKENUM_PWM_CH11) {
+ addr->PWMCFG &= ~0x00000C00; /* PWM5 output disable */
+ }
+
+ return 0;
+}
+
diff --git a/bsp/ck802/libraries/common/pwm/ck_pwm.h b/bsp/ck802/libraries/common/pwm/ck_pwm.h
new file mode 100644
index 0000000000..e60a659572
--- /dev/null
+++ b/bsp/ck802/libraries/common/pwm/ck_pwm.h
@@ -0,0 +1,101 @@
+/*
+ * 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 ck_pwm.h
+ * @brief header file for pwm driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef __CK_PWM_H
+#define __CK_PWM_H
+#include <stdio.h>
+#include "soc.h"
+
+typedef enum {
+ CKENUM_PWM_CH0 = 0,
+ CKENUM_PWM_CH1 = 1,
+ CKENUM_PWM_CH2 = 2,
+ CKENUM_PWM_CH3 = 3,
+ CKENUM_PWM_CH4 = 4,
+ CKENUM_PWM_CH5 = 5,
+ CKENUM_PWM_CH6 = 6,
+ CKENUM_PWM_CH7 = 7,
+ CKENUM_PWM_CH8 = 8,
+ CKENUM_PWM_CH9 = 9,
+ CKENUM_PWM_CH10 = 10,
+ CKENUM_PWM_CH11 = 11
+} CKENUM_PWM_CHANNEL;
+
+typedef enum {
+ CKENUM_PWM_COUNT_UP = 0,
+ CKENUM_PWM_COUNT_UP_DOWN = 1
+} CKENUM_PWM_COUNTER_MODE;
+
+typedef struct {
+ __IOM uint32_t PWMCFG; /* Offset: 0x000 (R/W) PWM configure register */
+ __IOM uint32_t PWMINVERTTRIG; /* Offset: 0x004 (R/W) PWM signal is inverted register */
+ __IOM uint32_t PWM01TRIG; /* Offset: 0x008 (R/W) contain the trigger generate compare value */
+ __IOM uint32_t PWM23TRIG; /* Offset: 0x00C (R/W) contain the trigger generate compare value */
+ __IOM uint32_t PWM45TRIG; /* Offset: 0x010 (N/A) contain the trigger generate compare value */
+ __IOM uint32_t PWMINTEN1; /* Offset: 0x014 (R/W) interrupt enable */
+ __IM uint32_t PWMINTEN2; /* Offset: 0x018 (N/A) interrupt enable */
+ __IOM uint32_t PWMRIS1; /* Offset: 0x01C (R/ ) raw interrupt status */
+ __IOM uint32_t PWMRIS2; /* Offset: 0x020 (N/A) raw interrupt status */
+ __IOM uint32_t PWMIC1; /* Offset: 0x024 (R/W) interrupt clear */
+ __IOM uint32_t PWMIC2; /* Offset: 0x028 (R/W) interrupt clear */
+ __IOM uint32_t PWMIS1; /* Offset: 0x02C (R/W) interrupt status */
+ __IOM uint32_t PWMIS2; /* Offset: 0x030 (R/W) interrupt status */
+ __IOM uint32_t PWMCTL; /* Offset: 0x034 (R/W) configure the pwm generation blocks */
+ __IOM uint32_t PWM01LOAD; /* Offset: 0x038 (R/W) contain the load value of the PWM count */
+ __IOM uint32_t PWM23LOAD; /* Offset: 0x03C (R/W) contain the load value of the PWM count */
+ __IOM uint32_t PWM45LOAD; /* Offset: 0x040 (N/A) contain the load value of the PWM count */
+ __IM uint32_t PWM01COUNT; /* Offset: 0x044 (R/ ) contain the current value of the PWM count */
+ __IM uint32_t PWM23COUNT; /* Offset: 0x048 (R/ ) contain the current value of the PWM count */
+ __IOM uint32_t PWM45COUNT; /* Offset: 0x04C (N/A) contain the current value of the PWM count */
+ __IOM uint32_t PWM0CMP; /* Offset: 0x050 (R/W) contain a value to be compared against the counter */
+ __IOM uint32_t PWM1CMP; /* Offset: 0x054 (R/W) contain a value to be compared against the counter */
+ __IOM uint32_t PWM2CMP; /* Offset: 0x058 (R/W) contain a value to be compared against the counter */
+ __IOM uint32_t PWM3CMP; /* Offset: 0x05C (N/A) contain a value to be compared against the counter */
+ __IOM uint32_t PWM4CMP; /* Offset: 0x060 (N/A) contain a value to be compared against the counter */
+ __IOM uint32_t PWM5CMP; /* Offset: 0x064 (N/A) contain a value to be compared against the counter */
+ __IOM uint32_t PWM01DB; /* Offset: 0x068 (R/W) contain the number of clock ticks to delay */
+ __IOM uint32_t PWM23DB; /* Offset: 0x06C (R/W) contain the number of clock ticks to delayr */
+ __IOM uint32_t PWM45DB; /* Offset: 0x070 (N/A) contain the number of clock ticks to delay */
+ __IOM uint32_t CAPCTL; /* Offset: 0x074 (R/W) input capture control */
+ __IOM uint32_t CAPINTEN; /* Offset: 0x078 (R/W) input capture interrupt enable */
+ __IM uint32_t CAPRIS; /* Offset: 0x07C (R/ ) input capture raw interrupt status */
+ __IOM uint32_t CAPIC; /* Offset: 0x080 (R/W) input capture interrupt clear */
+ __IM uint32_t CAPIS; /* Offset: 0x084 (R/ ) input capture interrupt status */
+ __IM uint32_t CAP01T; /* Offset: 0x088 (R/ ) input capture count value */
+ __IM uint32_t CAP23T; /* Offset: 0x08C (R/ ) input capture count value */
+ __IOM uint32_t CAP45T; /* Offset: 0x090 (N/A) input capture count value */
+ __IOM uint32_t CAP01MATCH; /* Offset: 0x094 (R/W) input capture match value */
+ __IOM uint32_t CAP23MATCH; /* Offset: 0x098 (R/W) input capture match value */
+ __IOM uint32_t CAP45MATCH; /* Offset: 0x09C (N/A) input capture match value */
+ __IOM uint32_t TIMINTEN; /* Offset: 0x0A0 (R/W) time interrupt enable */
+ __IM uint32_t TIMRIS; /* Offset: 0x0A4 (R/ ) time raw interrupt stats */
+ __IOM uint32_t TIMIC; /* Offset: 0x0A8 (R/W) time interrupt clear */
+ __IM uint32_t TIMIS; /* Offset: 0x0AC (R/ ) time interrupt status */
+ __IOM uint32_t TIM01LOAD; /* Offset: 0x0B0 (R/W) time load value */
+ __IOM uint32_t TIM23LOAD; /* Offset: 0x0B4 (R/W) time load value */
+ __IOM uint32_t TIM45LOAD; /* Offset: 0x0B8 (N/A) time load value */
+ __IOM uint32_t TIM01COUNT; /* Offset: 0x0BC (R/W) time current count time */
+ __IOM uint32_t TIM23COUNT; /* Offset: 0x0C0 (R/W) time current count time */
+ __IOM uint32_t TIM45COUNT; /* Offset: 0x0C4 (R/W) time current count time */
+} ck_pwm_reg_t;
+
+#endif /* __CK_PWM_H */
+
diff --git a/bsp/ck802/libraries/common/rsa/ck_rsa.c b/bsp/ck802/libraries/common/rsa/ck_rsa.c
new file mode 100644
index 0000000000..2d1774a1dc
--- /dev/null
+++ b/bsp/ck802/libraries/common/rsa/ck_rsa.c
@@ -0,0 +1,1256 @@
+/*
+ * 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 ck_rsa.c
+ * @brief CSI Source File for RSA Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include "drv_rsa.h"
+#include "ck_rsa.h"
+
+#define ERR_RSA(errno) (CSI_DRV_ERRNO_RSA_BASE | errno)
+#define RSA_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_RSA(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ rsa_event_cb_t cb;
+ rsa_data_bits_e data_bit;
+ rsa_endian_mode_e endian;
+ rsa_padding_t padding;
+ rsa_status_t status;
+} ck_rsa_priv_t;
+
+static ck_rsa_priv_t rsa_handle[CONFIG_RSA_NUM];
+
+extern uint8_t modulus[];
+static ck_rsa_reg_t *rsa_reg = NULL;
+static uint32_t g_acc[RSA_KEY_WORD];
+/* Driver Capabilities */
+static const rsa_capabilities_t driver_capabilities = {
+ .bits_192 = 1, /* 192bits modular mode */
+ .bits_256 = 1, /* 256bits modular mode */
+ .bits_512 = 1, /* 512bits modular mode */
+ .bits_1024 = 1, /* 1024bits modular mode */
+ .bits_2048 = 1 /* 2048bits modular mode */
+};
+
+//
+// Functions
+//
+
+static uint32_t sw_exptmod_2_2m(const uint32_t *modulus, uint32_t words, uint32_t *tmp_c);
+static uint32_t get_valid_bits(const uint32_t *addr, uint32_t wordsize);
+
+static uint32_t g_acc[RSA_KEY_WORD];
+
+static inline void rsa_clear_int(void)
+{
+ rsa_reg->rsa_isr = 0xffff;
+ rsa_reg->rsa_imr = 0x0000;
+}
+
+static inline void rsa_setm_width(uint32_t width)
+{
+ rsa_reg->rsa_mwid = width;
+}
+
+static inline void rsa_setd_width(uint32_t width)
+{
+ rsa_reg->rsa_ckid = width;
+}
+
+static inline void rsa_setb_width(uint32_t width)
+{
+ rsa_reg->rsa_bwid = width;
+}
+
+static inline void rsa_cal_q(void)
+{
+ rsa_reg->rsa_ctrl = RAS_CALCULATE_Q;
+}
+
+static inline void rsa_opr_start(void)
+{
+ rsa_reg->rsa_ctrl = RSA_ENABLE_MODULE;
+}
+
+static inline void rsa_opr_reset(void)
+{
+ rsa_reg->rsa_ctrl = RSA_ENDIAN_MODE;
+ rsa_reg->rsa_rst |= RSA_RESET;
+
+ while (rsa_reg->rsa_rst);
+}
+
+static inline uint32_t rsa_loop_cnt(void)
+{
+ return rsa_reg->rsa_lp_cnt;
+}
+
+static inline uint32_t rsa_cal_q_done(void)
+{
+ return (rsa_reg->rsa_isr >> RSA_CAL_Q_DONE_OFFSET) & 0x1;
+}
+
+static inline uint32_t rsa_opr_done(void)
+{
+ return (rsa_reg->rsa_isr) & 0x1;
+}
+
+static inline uint32_t rsa_raise_exception(void)
+{
+ return (rsa_reg->rsa_isr) & 0x1E;
+}
+
+static inline uint32_t rsa_loadm(uint32_t *data, uint32_t length)
+{
+ uint32_t i;
+ uint32_t baseaddr = (uint32_t)&rsa_reg->rsa_rfm;
+
+ for (i = 0; i < length; i++) {
+ *(volatile uint32_t *)baseaddr = data[i];
+ baseaddr = baseaddr + 4;
+ }
+
+ return 0;
+}
+
+static void rsa_loadd(uint32_t *data, uint32_t length)
+{
+ uint32_t i;
+ uint32_t baseaddr = (uint32_t)&rsa_reg->rsa_rfd;
+
+ for (i = 0; i < length; i++) {
+ *(volatile uint32_t *)baseaddr = data[i];
+ baseaddr = baseaddr + 4;
+ }
+}
+
+static void rsa_loadc(uint32_t *data, uint32_t length)
+{
+ uint32_t i;
+ uint32_t baseaddr = (uint32_t)&rsa_reg->rsa_rfc;
+
+ for (i = 1; i < length + 1; i++) {
+ *(volatile uint32_t *)baseaddr = data[i - 1];
+ baseaddr = baseaddr + 4;
+ }
+}
+
+static void rsa_loadb(uint32_t *data, uint32_t length)
+{
+ uint32_t i;
+ uint32_t baseaddr = (uint32_t)&rsa_reg->rsa_rfb;
+
+ for (i = 0; i < length; i++) {
+ *(volatile uint32_t *)baseaddr = data[i];
+ baseaddr = baseaddr + 4;
+ }
+}
+
+static void rsa_read_r(uint32_t data[], uint32_t length)
+{
+ uint32_t i;
+ uint32_t baseaddr = (uint32_t)&rsa_reg->rsa_rfr;
+
+ for (i = 0; i < length; i++) {
+ data[i] = *(uint32_t *)baseaddr;
+ baseaddr = baseaddr + 4;
+ }
+}
+
+static uint32_t rsa_exptmod_1024(const uint32_t *modulus, const uint32_t *exponent,
+ const uint32_t *base, uint32_t *out)
+{
+#ifndef RSA_USING_MALLOC
+#ifndef RSA_USING_ID2KEY
+ uint32_t tmp_c[RSA_KEY_WORD];
+#endif
+ uint32_t ret = 0;
+
+ if ((NULL == exponent) || (NULL == base) || (NULL == out)) {
+ return 1;
+ }
+
+#ifndef RSA_USING_ID2KEY
+ ret = sw_exptmod_2_2m(modulus, RSA_KEY_WORD, tmp_c);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+#endif
+
+ /* reset for safe */
+ rsa_opr_reset();
+ /* clear and disable int */
+ rsa_clear_int();
+ /* set m */
+ rsa_setm_width(RSA_KEY_WORD >> 1);
+ rsa_loadm((uint32_t *)modulus, RSA_KEY_WORD);
+ /* set d */
+ rsa_setd_width(get_valid_bits(exponent, RSA_KEY_WORD) - 1);
+ rsa_loadd((uint32_t *)exponent, RSA_KEY_WORD);
+ /* set b */
+ rsa_setb_width(RSA_KEY_WORD >> 1);
+ rsa_loadb((uint32_t *)base, RSA_KEY_WORD);
+ /* set c */
+#ifndef RSA_USING_ID2KEY
+ rsa_loadc(tmp_c, RSA_KEY_WORD);
+#else
+ rsa_loadc(g_acc, RSA_KEY_WORD);
+#endif
+
+ rsa_cal_q();
+
+ while (!rsa_cal_q_done() && (!rsa_raise_exception()));
+
+ if (!rsa_raise_exception()) {
+ rsa_opr_start();
+
+ while ((!rsa_opr_done()) && (rsa_loop_cnt() < MAX_RSA_LP_CNT) && (!rsa_raise_exception()));
+
+ if ((rsa_loop_cnt() >= MAX_RSA_LP_CNT)
+ || rsa_raise_exception()) {
+ ret = 1;
+ } else {
+ rsa_read_r(out, RSA_KEY_WORD);
+ }
+ } else {
+ ret = 1;
+ }
+
+ rsa_opr_reset();
+
+ return ret;
+#else
+ uint32_t ret;
+ uint32_t *tmp_c = (uint32_t *)tee_malloc(RSA_KEY_BYTE);
+
+ if (tmp_c == NULL) {
+ return -1;
+ }
+
+ if ((NULL == modulus) || (NULL == exponent) || (NULL == base) || (NULL == out)) {
+ return -1;
+ }
+
+#if 0
+ ret = sw_exptmod_2_2m(modulus, RSA_KEY_WORD, tmp_c);
+
+ if (ret != 0) {
+ tee_free(tmp_c);
+ return ret;
+ }
+
+#else
+ memcpy(tmp_c, g_acc, RSA_KEY_BYTE);
+#endif
+ /* reset for safe */
+ rsa_opr_reset();
+ /* clear and disable int */
+ rsa_clear_int();
+ /* set m */
+ rsa_setm_width(RSA_KEY_WORD >> 1);
+ rsa_loadm((uint32_t *)modulus, RSA_KEY_WORD);
+ /* set d */
+ rsa_setd_width(get_valid_bits(exponent, RSA_KEY_WORD) - 1);
+ rsa_loadd((uint32_t *)exponent, RSA_KEY_WORD);
+ /* set b */
+ rsa_setb_width(RSA_KEY_WORD >> 1);
+ rsa_loadb((uint32_t *)base, RSA_KEY_WORD);
+ /* set c */
+ rsa_loadc(tmp_c, RSA_KEY_WORD);
+
+ rsa_cal_q();
+
+ while (!rsa_cal_q_done() && (!rsa_raise_exception()));
+
+ if (!rsa_raise_exception()) {
+ rsa_opr_start();
+
+ while ((!rsa_opr_done()) && (rsa_loop_cnt() < MAX_RSA_LP_CNT) && (!rsa_raise_exception()));
+
+ if ((rsa_loop_cnt() >= MAX_RSA_LP_CNT)
+ || rsa_raise_exception()) {
+ ret = 1;
+ } else {
+ rsa_read_r(out, RSA_KEY_WORD);
+ }
+ } else {
+ ret = 1;
+ }
+
+ rsa_opr_reset();
+ tee_free(tmp_c);
+
+ return ret;
+#endif
+}
+
+static uint32_t get_valid_bits(const uint32_t *addr, uint32_t wordsize)
+{
+ uint32_t i = 0;
+ uint32_t j = 0;
+
+ for (i = wordsize; i > 0; i--) {
+ if (addr[i - 1]) {
+ break;
+ }
+ }
+
+ for (j = RSA_KEY_WORD; j > 0; j--) {
+ if (addr[i - 1] & (0x1 << (j - 1))) {
+ break;
+ }
+ }
+
+ return ((i - 1) << 5) + j;
+}
+
+static uint32_t get_first_nonzero_words(uint32_t *a, uint32_t max_words)
+{
+ uint32_t i = 0;
+
+ for (i = max_words; i > 0; i--) {
+ if (a[i - 1]) {
+ return i;
+ }
+ }
+
+ return 0;
+}
+
+static uint32_t word_array_left_shift(uint32_t *a, uint32_t words,
+ uint32_t shift_bits, uint32_t *r)
+{
+ uint32_t i = 0;
+ uint32_t w = shift_bits >> 5;
+ uint32_t b = shift_bits - (w << 5);
+
+ for (i = 0; i < w; i++) {
+ r[i] = 0;
+ }
+
+ uint32_t tmp = 0;
+
+ for (i = 0; i < words; i++) {
+ r[w + i] = (tmp | ((a[i] << b) & (~((0x1 << b) - 1))));
+ tmp = ((a[i] >> (RSA_KEY_WORD - b)) & ((0x1 << b) - 1));
+ }
+
+ r[w + i] = tmp;
+
+ return 0;
+}
+
+/* r = a - b */
+static uint32_t _word_array_sub(uint32_t *a, uint32_t a_words,
+ uint32_t *b, uint32_t b_words,
+ uint32_t *r)
+{
+ uint32_t i;
+ uint64_t tmp = 0;
+ uint32_t borrow = 0;
+
+ for (i = 0; i < b_words; i++) {
+ tmp = UINT32_TO_UINT64(a[i]) - UINT32_TO_UINT64(b[i]) - UINT32_TO_UINT64(borrow);
+ r[i] = UINT64L_TO_UINT32(tmp);
+ borrow = ((UINT64H_TO_UINT32(tmp) == 0) ? (0) : (0xffffffff - UINT64H_TO_UINT32(tmp) + 1));
+ }
+
+ for (i = b_words; i < a_words; i++) {
+ tmp = UINT32_TO_UINT64(a[i]) - UINT32_TO_UINT64(borrow);
+ r[i] = UINT64L_TO_UINT32(tmp);
+ borrow = ((UINT64H_TO_UINT32(tmp) == 0) ? (0) : (0xffffffff - UINT64H_TO_UINT32(tmp) + 1));
+ }
+
+ if (borrow) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static uint32_t word_array_mod(uint32_t *a, uint32_t a_words,
+ uint32_t *b, uint32_t b_words,
+ uint32_t *r)
+{
+#ifndef RSA_USING_MALLOC
+ uint32_t ret;
+ bignum_t tmpa;
+ bignum_t tmpb;
+
+ memset(&tmpa, 0, sizeof(tmpa));
+ memset(&tmpb, 0, sizeof(tmpa));
+
+ uint32_t b_valid_bits = get_valid_bits(b, b_words);
+
+ memcpy(tmpa.pdata, a, (a_words << 2));
+
+ do {
+ uint32_t tmpa_words = get_first_nonzero_words(tmpa.pdata, a_words);
+ uint32_t tmpa_valid_bits = get_valid_bits(tmpa.pdata, tmpa_words);
+
+ if (tmpa_valid_bits > b_valid_bits + 1) {
+ memset(tmpb.pdata, 0, (a_words << 2));
+ word_array_left_shift(b, b_words, tmpa_valid_bits - b_valid_bits - 1,
+ tmpb.pdata);
+ uint32_t tmpb_words = get_first_nonzero_words(tmpb.pdata, a_words);
+ ret = _word_array_sub(tmpa.pdata, tmpa_words, tmpb.pdata, tmpb_words, tmpa.pdata);
+ } else if (tmpa_words == b_words) {
+ memcpy(r, tmpa.pdata, (tmpa_words << 2));
+ ret = _word_array_sub(r, tmpa_words, b, b_words, tmpa.pdata);
+ } else {
+ ret = _word_array_sub(tmpa.pdata, tmpa_words, b, b_words, tmpa.pdata);
+ }
+ } while (ret == 0);
+
+ return 0;
+
+#else
+ uint32_t ret;
+ bignum_t *tmpa = tee_malloc(sizeof(bignum_t));
+ bignum_t *tmpb = tee_malloc(sizeof(bignum_t));
+
+ if ((tmpa == NULL) || (tmpb == NULL)) {
+ return -1;
+ }
+
+ uint32_t b_valid_bits = get_valid_bits(b, b_words);
+
+ memcpy(tmpa->pdata, a, (a_words << 2));
+
+ do {
+ uint32_t tmpa_words = get_first_nonzero_words(tmpa->pdata, a_words);
+ uint32_t tmpa_valid_bits = get_valid_bits(tmpa->pdata, tmpa_words);
+
+ if (tmpa_valid_bits > b_valid_bits + 1) {
+ memset(tmpb->pdata, 0, (a_words << 2));
+ word_array_left_shift(b, b_words, tmpa_valid_bits - b_valid_bits - 1,
+ tmpb->pdata);
+ uint32_t tmpb_words = get_first_nonzero_words(tmpb->pdata, a_words);
+ ret = _word_array_sub(tmpa->pdata, tmpa_words, tmpb->pdata, tmpb_words, tmpa->pdata);
+ } else if (tmpa_words == b_words) {
+ memcpy(r, tmpa->pdata, (tmpa_words << 2));
+ ret = _word_array_sub(r, tmpa_words, b, b_words, tmpa->pdata);
+ } else {
+ ret = _word_array_sub(tmpa->pdata, tmpa_words, b, b_words, tmpa->pdata);
+ }
+ } while (ret == 0);
+
+ tee_free(tmpa);
+ tee_free(tmpb);
+ return 0;
+
+#endif
+}
+
+static uint32_t sw_exptmod_2_2m(const uint32_t *modulus, uint32_t words, uint32_t *tmp_c)
+{
+#ifndef RSA_USING_MALLOC
+ bignum_t tmp;
+
+ memset(&tmp, 0, sizeof(bignum_t));
+
+ uint32_t m_valid_bits = (words << 5);
+
+ uint32_t data1 = 0x1;
+ word_array_left_shift(&data1, 1, (m_valid_bits << 1), tmp.pdata);
+ tmp.words = get_first_nonzero_words(tmp.pdata, words * 2 + 1);
+
+ uint32_t ret = word_array_mod(tmp.pdata, tmp.words,
+ (uint32_t *)modulus, words, tmp_c);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ return 0;
+#else
+
+ bignum_t *tmp = tee_malloc(sizeof(bignum_t));
+
+ if (tmp == NULL) {
+ return -1;
+ }
+
+ uint32_t m_valid_bits = (words << 5);
+
+ uint32_t data1 = 0x1;
+ word_array_left_shift(&data1, 1, (m_valid_bits << 1), tmp->pdata);
+ tmp->words = get_first_nonzero_words(tmp->pdata, words * 2 + 1);
+
+ uint32_t ret = word_array_mod(tmp->pdata, tmp->words,
+ (uint32_t *)modulus, words, tmp_c);
+
+ if (ret != 0) {
+ tee_free(tmp);
+ return ret;
+ }
+
+ tee_free(tmp);
+ return 0;
+#endif
+}
+
+static void convert_byte_array(uint8_t *in, uint8_t *out, uint32_t len)
+{
+ uint32_t idx, round = len >> 1;
+
+ for (idx = 0; idx < round; idx++) {
+ uint8_t tmp = *(in + idx);
+ *(out + idx) = *(in + len - 1 - idx);
+ *(out + len - 1 - idx) = tmp;
+ }
+
+ if (len & 0x1) {
+ *(out + round) = *(in + round);
+ }
+}
+
+static void convert_buf_to_bndata(const uint8_t *src, uint32_t src_bytes,
+ uint32_t *dst, uint32_t dst_words)
+{
+ memset(dst, 0, dst_words << 2);
+ convert_byte_array((uint8_t *)src, (uint8_t *)dst, src_bytes);
+}
+
+static void convert_bndata_to_buf(const uint32_t *src, uint32_t src_words,
+ uint8_t *dst, uint32_t dst_bytes)
+{
+ memset(dst, 0, dst_bytes);
+ convert_byte_array((uint8_t *)src, (uint8_t *)dst, dst_bytes);
+}
+
+static const uint8_t der_sha1_t[] = {
+ 0x30, 0x21,
+ 0x30, 0x09,
+ 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
+ 0x05, 0x00,
+ 0x04, 0x14
+};
+
+static const uint8_t der_md5_t[] = {
+ 0x30, 0x20, /* type Sequence, length 0x20 (32) */
+ 0x30, 0x0c, /* type Sequence, length 0x09 */
+ 0x06, 0x08, /* type OID, length 0x05 */
+ 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
+ 0x05, 0x00, /* NULL */
+ 0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */
+};
+
+static uint32_t RSA_padding_add_PKCS1_sha1_emsa_1024(const uint8_t *dgst,
+ uint8_t *out,
+ uint32_t *outlen,
+ uint32_t type)
+
+{
+ uint8_t *der;
+ uint32_t der_len;
+ uint32_t hashlen;
+
+ if (type == MD5_PADDING) {
+ der = (uint8_t *)der_md5_t;
+ der_len = sizeof(der_md5_t);
+ hashlen = MD5_HASH_SZ;
+ } else if (type == SHA1_PADDING) {
+ der = (uint8_t *)der_sha1_t;
+ der_len = sizeof(der_sha1_t);
+ hashlen = SHA1_HASH_SZ;
+ } else {
+ der = (uint8_t *)der_md5_t;
+ der_len = sizeof(der_md5_t);
+ hashlen = MD5_HASH_SZ;
+ }
+
+ uint32_t modulus_len = 1024 >> 3;
+
+ if (*outlen < modulus_len) {
+ *outlen = modulus_len;
+ return -1;
+ }
+
+
+ uint8_t *p = (uint8_t *)out;
+
+ *(p++) = 0x00;
+ *(p++) = 0x01;
+
+ /* pad out with 0xff data */
+ uint32_t pslen = modulus_len - 3 - der_len - hashlen;
+
+ uint32_t i;
+ for (i = 0; i < pslen; i++) {
+ p[i] = 0xff; /* PS */
+ }
+
+ p += pslen;
+ *(p++) = 0x0;
+
+ for (i = 0; i < der_len; i++) {
+ p[i] = der[i];
+ }
+
+ p += der_len;
+
+ for (i = 0; i < hashlen; i++) {
+ p[i] = dgst[i];
+ }
+
+ *outlen = modulus_len;
+ return 0;
+}
+
+static uint32_t RSA_padding_check_PKCS1_type_emsa(const uint8_t *dgst,
+ const uint8_t *in,
+ const uint32_t inlen,
+ uint8_t *is_valid,
+ uint32_t type)
+{
+ uint8_t *der;
+ uint32_t der_len;
+ uint32_t hashlen;
+
+ if (type == MD5_PADDING) {
+ der = (uint8_t *)der_md5_t;
+ der_len = sizeof(der_md5_t);
+ hashlen = MD5_HASH_SZ;
+ } else if (type == SHA1_PADDING) {
+ der = (uint8_t *)der_sha1_t;
+ der_len = sizeof(der_sha1_t);
+ hashlen = SHA1_HASH_SZ;
+ } else {
+ der = (uint8_t *)der_md5_t;
+ der_len = sizeof(der_md5_t);
+ hashlen = MD5_HASH_SZ;
+ }
+
+ uint32_t modulus_len = RSA_KEY_LEN >> 3;
+
+ if (inlen != modulus_len) {
+ return -1;
+ }
+
+ *is_valid = 0;
+
+ uint32_t pslen = modulus_len - 3 - der_len - hashlen;
+ const uint8_t *p = in;
+ p++;
+
+ uint32_t ret;
+ if (*(p) != 0x01) {
+ ret = -1;
+ goto _verify_fail;
+ }
+
+ p++;
+
+ /* scan PS */
+ uint32_t i;
+ for (i = 0; i < pslen; i++) {
+ if (*(p + i) != 0xff) {
+ ret = -1;
+ goto _verify_fail;
+ }
+ }
+
+ p += pslen;
+
+ if ((*p) != 0x00) {
+ ret = -1;
+ goto _verify_fail;
+ }
+
+ p++;
+
+ /* scan t */
+ for (i = 0; i < der_len; i++) {
+ if (*(p + i) != der[i]) {
+ ret = -1;
+ goto _verify_fail;
+ }
+ }
+
+ p += der_len;
+
+ for (i = 0; i < hashlen; i++) {
+ if (*(p + i) != dgst[i]) {
+ ret = -1;
+ goto _verify_fail;
+ }
+ }
+
+ *is_valid = 1;
+ ret = 0;
+
+_verify_fail:
+
+ return ret;
+}
+
+static uint32_t RSA_ES_padding_add_PKCS1_emsa_1024(const uint8_t *dgst,
+ uint32_t dgstlen,
+ uint8_t *out,
+ uint32_t *outlen,
+ uint32_t padding)
+
+{
+ uint32_t modulus_len = RSA_KEY_LEN >> 3;
+
+ if (*outlen < modulus_len) {
+ *outlen = modulus_len;
+ return 1;
+ }
+
+ uint8_t *p = (uint8_t *)out;
+
+ *(p++) = 0x00;
+ *(p++) = 0x02;
+
+ /* pad out with 0xff data */
+ uint32_t pslen = modulus_len - 3 - dgstlen;
+
+ uint32_t i;
+ for (i = 0; i < pslen; i++) {
+ p[i] = 0xff; /* PS */
+ }
+
+ p += pslen;
+ *(p++) = 0x0;
+
+ for (i = 0; i < dgstlen; i++) {
+ p[i] = dgst[i];
+ }
+
+ *outlen = modulus_len;
+
+ return 0;
+}
+
+static uint32_t RSA_ES_padding_check_PKCS1_type_emsa(uint8_t *out, uint32_t *out_size,
+ uint8_t *src, uint32_t src_size, uint32_t padding)
+{
+
+ uint32_t modulus_len = RSA_KEY_LEN >> 3;
+
+ if (src_size < modulus_len) {
+ return 1;
+ }
+
+ uint8_t *p = (uint8_t *)src;
+ uint8_t *p_src = p;
+ *(p++) = 0x00;
+
+ if (padding == PKCS1_PADDING) {
+ if (*(p++) != 0x02) {
+ return 1;
+ }
+ } else {
+ if (*(p++) != 0x01) {
+ return 1;
+ }
+ }
+
+ uint32_t pslen = src_size - 2;
+
+ while (pslen--) {
+ if (*(p++) == 0x0) {
+ break;
+ }
+ }
+
+ if (padding == PKCS1_PADDING) {
+ *out_size = pslen;
+ } else {
+ *out_size = modulus_len;
+ }
+
+ uint32_t i;
+ for (i = 0; i < *out_size; i++) {
+
+ if (padding == PKCS1_PADDING) {
+ out[i] = p[i];
+ } else {
+ out[i] = p_src[i];
+ }
+ }
+
+ return 0;
+}
+
+int rsa_encrypt(uint8_t *n, uint8_t *e,
+ uint8_t *src, uint32_t src_size,
+ uint8_t *out, uint32_t *out_size,
+ uint32_t padding)
+{
+ uint32_t ret;
+ uint32_t tmp_n[RSA_KEY_WORD];
+ uint32_t tmp_e[RSA_KEY_WORD];
+ uint32_t tmp_src_padded[RSA_KEY_WORD];
+ uint32_t tmp_out[RSA_KEY_WORD];
+
+ uint32_t keywords = RSA_KEY_WORD;
+ uint32_t keybytes = RSA_KEY_BYTE;
+
+ convert_buf_to_bndata(n, keybytes, tmp_n, keywords);
+ convert_buf_to_bndata(e, keybytes, tmp_e, keywords);
+
+ uint32_t tmp_src_padded_len = keybytes;
+
+ if (padding == PKCS1_PADDING) {
+ ret = RSA_ES_padding_add_PKCS1_emsa_1024((const uint8_t *)src, src_size,
+ (uint8_t *)tmp_src_padded,
+ &tmp_src_padded_len, padding);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ convert_byte_array((uint8_t *)tmp_src_padded, (uint8_t *)tmp_src_padded, tmp_src_padded_len);
+ } else {
+ convert_byte_array((uint8_t *)src, (uint8_t *)tmp_src_padded, tmp_src_padded_len);
+ }
+
+ ret = rsa_exptmod_1024(tmp_n, tmp_e, tmp_src_padded, tmp_out);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ convert_bndata_to_buf(tmp_out, keywords, out, keybytes);
+ *out_size = keybytes;
+
+ return ret;
+}
+
+int rsa_decrypt(uint8_t *n, uint8_t *d,
+ uint8_t *src, uint32_t src_size,
+ uint8_t *out, uint32_t *out_size,
+ uint32_t padding)
+{
+ uint32_t ret;
+ uint32_t tmp_n[RSA_KEY_WORD];
+ uint32_t tmp_d[RSA_KEY_WORD];
+ uint32_t tmp_dst_padded[RSA_KEY_WORD];
+ uint32_t tmp_sig[RSA_KEY_WORD];
+
+ uint32_t keywords = RSA_KEY_WORD;
+ uint32_t keybytes = RSA_KEY_BYTE;
+
+ convert_buf_to_bndata(n, keybytes, tmp_n, keywords);
+ convert_buf_to_bndata(d, keybytes, tmp_d, keywords);
+ convert_buf_to_bndata(src, src_size, tmp_sig, keywords);
+
+ ret = rsa_exptmod_1024(tmp_n, tmp_d, tmp_sig, tmp_dst_padded);
+ \
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ convert_byte_array((uint8_t *)tmp_dst_padded,
+ (uint8_t *)tmp_dst_padded, keybytes);
+
+ ret = RSA_ES_padding_check_PKCS1_type_emsa(out, out_size,
+ (uint8_t *)tmp_dst_padded,
+ keybytes, padding);
+
+ return ret;
+}
+
+int rsa_sign(uint8_t *n, uint8_t *d,
+ uint8_t *src, uint32_t src_size,
+ uint8_t *signature, uint32_t *sig_size, uint32_t type)
+{
+ uint32_t ret;
+ uint32_t tmp_n[RSA_KEY_WORD];
+ uint32_t tmp_d[RSA_KEY_WORD];
+ uint32_t tmp_src_padded[RSA_KEY_WORD];
+ uint32_t tmp_sig[RSA_KEY_WORD];
+
+ uint32_t keywords = RSA_KEY_WORD;
+ uint32_t keybytes = RSA_KEY_BYTE;
+
+ convert_buf_to_bndata(n, keybytes, tmp_n, keywords);
+ convert_buf_to_bndata(d, keybytes, tmp_d, keywords);
+
+ uint32_t tmp_src_padded_len = keybytes;
+ ret = RSA_padding_add_PKCS1_sha1_emsa_1024((const uint8_t *)src,
+ (uint8_t *)tmp_src_padded,
+ &tmp_src_padded_len, type);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ convert_byte_array((uint8_t *)tmp_src_padded, (uint8_t *)tmp_src_padded, keybytes);
+
+ ret = rsa_exptmod_1024(tmp_n, tmp_d, tmp_src_padded, tmp_sig);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ convert_bndata_to_buf(tmp_sig, keywords, signature, keybytes);
+ *sig_size = RSA_KEY_BYTE;
+
+ return 0;
+}
+
+int rsa_verify(uint8_t *n, uint8_t *e,
+ uint8_t *src, uint32_t src_size,
+ uint8_t *signature, uint32_t sig_size,
+ uint8_t *result, uint32_t type)
+{
+ uint32_t ret;
+ uint32_t tmp_n[RSA_KEY_WORD];
+ uint32_t tmp_e[RSA_KEY_WORD];
+ uint32_t tmp_dst_padded[RSA_KEY_WORD];
+ uint32_t tmp_sig[RSA_KEY_WORD];
+
+ *result = 0;
+
+ uint32_t keywords = RSA_KEY_WORD;
+ uint32_t keybytes = RSA_KEY_BYTE;
+
+ convert_buf_to_bndata(n, keybytes, tmp_n, keywords);
+ convert_buf_to_bndata(e, keybytes, tmp_e, keywords);
+ convert_buf_to_bndata(signature, sig_size, tmp_sig, keywords);
+
+ ret = rsa_exptmod_1024(tmp_n, tmp_e, tmp_sig, tmp_dst_padded);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ convert_byte_array((uint8_t *)tmp_dst_padded,
+ (uint8_t *)tmp_dst_padded, keybytes);
+ ret = RSA_padding_check_PKCS1_type_emsa(src,
+ (const uint8_t *)tmp_dst_padded,
+ keybytes,
+ result,
+ type);
+
+ return ret;
+}
+
+int rsa_sw_exptmod_2_2m(uint8_t *modulus)
+{
+ uint32_t tmp_n[RSA_KEY_WORD];
+
+ uint32_t keywords = RSA_KEY_WORD;
+ uint32_t keybytes = RSA_KEY_BYTE;
+
+ convert_buf_to_bndata(modulus, keybytes, tmp_n, keywords);
+
+ sw_exptmod_2_2m(tmp_n, RSA_KEY_WORD, g_acc);
+
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_rsa_count(void)
+{
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_rsa(int32_t idx, uint32_t *base, uint32_t *irq)
+{
+ return NULL;
+}
+
+/**
+ \brief get rsa handle count.
+ \return rsa handle count
+*/
+int32_t csi_rsa_get_instance_count(void)
+{
+ return target_get_rsa_count();
+}
+
+/**
+ \brief Initialize RSA Interface. 1. Initializes the resources needed for the RSA interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_rsa_get_instance_count()
+ \param[in] cb_event Pointer to \ref rsa_event_cb_t
+ \return pointer to rsa handle
+*/
+rsa_handle_t csi_rsa_initialize(int32_t idx, rsa_event_cb_t cb_event)
+{
+ if (idx < 0 || idx >= CONFIG_RSA_NUM) {
+ return NULL;
+ }
+
+ /* obtain the rsa information */
+ uint32_t base = 0u;
+ uint32_t irq;
+ int32_t real_idx = target_get_rsa(idx, &base, &irq);
+
+ if (real_idx != idx) {
+ return NULL;
+ }
+
+ ck_rsa_priv_t *rsa_priv = &rsa_handle[idx];
+
+ rsa_priv->base = base;
+ rsa_priv->irq = irq;
+
+ /* initialize the rsa context */
+ rsa_priv->cb = cb_event;
+ rsa_priv->data_bit = RSA_DATA_BITS_1024;
+ rsa_priv->endian = RSA_ENDIAN_MODE_LITTLE;
+ rsa_priv->padding.padding_type = RSA_PADDING_MODE_PKCS1;
+ rsa_priv->padding.hash_type = RSA_HASH_TYPE_SHA1;
+ rsa_priv->status.busy = 0;
+
+ return (rsa_handle_t)rsa_priv;
+}
+
+/**
+ \brief De-initialize RSA Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle rsa handle to operate.
+ \return error code
+*/
+int32_t csi_rsa_uninitialize(rsa_handle_t handle)
+{
+ RSA_NULL_PARAM_CHK(handle);
+
+ ck_rsa_priv_t *rsa_priv = handle;
+ rsa_priv->cb = NULL;
+
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle rsa handle to operate.
+ \return \ref rsa_capabilities_t
+*/
+rsa_capabilities_t csi_rsa_get_capabilities(rsa_handle_t handle)
+{
+ return driver_capabilities;
+}
+
+/**
+ \brief config rsa mode.
+ \param[in] handle rsa handle to operate.
+ \param[in] data_bits \ref rsa_data_bits_e
+ \param[in] endian \ref rsa_endian_mode_e
+ \return error code
+*/
+int32_t csi_rsa_config(rsa_handle_t handle,
+ rsa_data_bits_e data_bits,
+ rsa_endian_mode_e endian
+ )
+{
+ RSA_NULL_PARAM_CHK(handle);
+
+ ck_rsa_priv_t *rsa_priv = handle;
+ rsa_reg = (ck_rsa_reg_t *)(rsa_priv->base);
+
+ /* config the data bits */
+ switch (data_bits) {
+ case RSA_DATA_BITS_192:
+ case RSA_DATA_BITS_256:
+ case RSA_DATA_BITS_512:
+ case RSA_DATA_BITS_2048:
+ return ERR_RSA(EDRV_UNSUPPORTED);
+
+ case RSA_DATA_BITS_1024:
+ rsa_priv->data_bit = data_bits;
+ break;
+
+ default:
+ return ERR_RSA(EDRV_PARAMETER);
+ }
+
+ /* config the endian mode */
+ if (endian == RSA_ENDIAN_MODE_LITTLE) {
+ rsa_priv->endian = endian;
+ } else if (endian == RSA_ENDIAN_MODE_BIG) {
+ return ERR_RSA(EDRV_UNSUPPORTED);
+ } else {
+ return ERR_RSA(EDRV_PARAMETER);
+ }
+
+ return 0;
+}
+
+/**
+ \brief encrypt
+ \param[in] handle rsa handle to operate.
+ \param[in] n Pointer to the public modulus
+ \param[in] e Pointer to the public exponent
+ \param[in] src Pointer to the source data.
+ \param[in] src_size the source data len
+ \param[out] out Pointer to the result buffer
+ \param[out] out_size the result size
+ \param[in] padding \ref rsa_padding_t
+ \return error code
+*/
+int32_t csi_rsa_encrypt(rsa_handle_t handle, void *n, void *e, void *src, int32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding)
+{
+ RSA_NULL_PARAM_CHK(handle);
+ RSA_NULL_PARAM_CHK(n);
+ RSA_NULL_PARAM_CHK(e);
+ RSA_NULL_PARAM_CHK(src);
+ RSA_NULL_PARAM_CHK(out);
+ RSA_NULL_PARAM_CHK(out_size);
+ if (src_size <= 0 || (padding.padding_type != RSA_PADDING_MODE_PKCS1 && padding.padding_type != RSA_PADDING_MODE_NO)) {
+ return ERR_RSA(EDRV_PARAMETER);
+ }
+
+ ck_rsa_priv_t *rsa_priv = handle;
+ rsa_priv->status.busy = 1U;
+ rsa_encrypt((uint8_t *)n, (uint8_t *)e, (uint8_t *)src, (uint32_t)src_size, (uint8_t *)out, (uint32_t *)out_size, (uint32_t)(padding.padding_type));
+ rsa_priv->status.busy = 0U;
+
+ if (rsa_priv->cb) {
+ rsa_priv->cb(RSA_EVENT_ENCRYPT_COMPLETE);
+ }
+
+ return 0;
+}
+
+/**
+ \brief decrypt
+ \param[in] handle rsa handle to operate.
+ \param[in] n Pointer to the public modulus
+ \param[in] d Pointer to the privte exponent
+ \param[in] src Pointer to the source data.
+ \param[in] src_size the source data len
+ \param[out] out Pointer to the result buffer
+ \param[out] out_size the result size
+ \param[in] padding \ref rsa_padding_t
+ \return error code
+*/
+int32_t csi_rsa_decrypt(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding)
+{
+ RSA_NULL_PARAM_CHK(handle);
+ RSA_NULL_PARAM_CHK(n);
+ RSA_NULL_PARAM_CHK(d);
+ RSA_NULL_PARAM_CHK(src);
+ RSA_NULL_PARAM_CHK(out);
+ RSA_NULL_PARAM_CHK(out_size);
+ if (src_size <= 0 || (padding.padding_type != RSA_PADDING_MODE_PKCS1 && padding.padding_type != RSA_PADDING_MODE_NO)) {
+ return ERR_RSA(EDRV_PARAMETER);
+ }
+
+ ck_rsa_priv_t *rsa_priv = handle;
+ rsa_priv->status.busy = 1U;
+ rsa_decrypt((uint8_t *)n, (uint8_t *)d, (uint8_t *)src, (uint32_t)src_size, (uint8_t *)out, (uint32_t *)out_size, (uint32_t)(padding.padding_type));
+ rsa_priv->status.busy = 0U;
+
+ if (rsa_priv->cb) {
+ rsa_priv->cb(RSA_EVENT_DECRYPT_COMPLETE);
+ }
+
+ return 0;
+}
+
+/**
+ \brief rsa sign
+ \param[in] handle rsa handle to operate.
+ \param[in] n Pointer to the public modulus
+ \param[in] d Pointer to the privte exponent
+ \param[in] src Pointer to the source data.
+ \param[in] src_size the source data len
+ \param[out] signature Pointer to the signature
+ \param[out] sig_size the signature size
+ \param[in] padding \ref rsa_padding_t
+ \return error code
+*/
+int32_t csi_rsa_sign(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *signature, void *sig_size, rsa_padding_t padding)
+{
+ RSA_NULL_PARAM_CHK(handle);
+ RSA_NULL_PARAM_CHK(n);
+ RSA_NULL_PARAM_CHK(d);
+ RSA_NULL_PARAM_CHK(src);
+ RSA_NULL_PARAM_CHK(signature);
+ RSA_NULL_PARAM_CHK(sig_size);
+ if (src_size <= 0 || (padding.hash_type != RSA_HASH_TYPE_MD5 && padding.hash_type != RSA_HASH_TYPE_SHA1)) {
+ return ERR_RSA(EDRV_PARAMETER);
+ }
+
+ ck_rsa_priv_t *rsa_priv = handle;
+ rsa_priv->status.busy = 1U;
+ rsa_sign((uint8_t *)n, (uint8_t *)d, (uint8_t *)src, (uint32_t)src_size, (uint8_t *)signature, (uint32_t *)sig_size, (uint32_t)(padding.hash_type));
+ rsa_priv->status.busy = 0U;
+
+ if (rsa_priv->cb) {
+ rsa_priv->cb(RSA_EVENT_SIGN_COMPLETE);
+ }
+
+ return 0;
+}
+
+/**
+ \brief rsa verify
+ \param[in] handle rsa handle to operate.
+ \param[in] n Pointer to the public modulus
+ \param[in] e Pointer to the public exponent
+ \param[in] src Pointer to the source data.
+ \param[in] src_size the source data len
+ \param[in] signature Pointer to the signature
+ \param[in] sig_size the signature size
+ \param[out] result Pointer to the result
+ \param[in] padding \ref rsa_padding_t
+ \return error code
+*/
+int32_t csi_rsa_verify(rsa_handle_t handle, void *n, void *e, void *src, uint32_t src_size, void *signature, uint32_t sig_size, void *result, rsa_padding_t padding)
+{
+ RSA_NULL_PARAM_CHK(handle);
+ RSA_NULL_PARAM_CHK(n);
+ RSA_NULL_PARAM_CHK(e);
+ RSA_NULL_PARAM_CHK(src);
+ RSA_NULL_PARAM_CHK(signature);
+ RSA_NULL_PARAM_CHK(result);
+ if (src_size <= 0 || sig_size <= 0 || (padding.hash_type != RSA_HASH_TYPE_MD5 && padding.hash_type != RSA_HASH_TYPE_SHA1)) {
+ return ERR_RSA(EDRV_PARAMETER);
+ }
+
+ ck_rsa_priv_t *rsa_priv = handle;
+ rsa_priv->status.busy = 1U;
+ rsa_verify((uint8_t *)n, (uint8_t *)e, (uint8_t *)src, (uint32_t)src_size, (uint8_t *)signature, sig_size, (uint8_t *)result, (uint32_t)(padding.hash_type));
+ rsa_priv->status.busy = 0U;
+
+ if (rsa_priv->cb) {
+ rsa_priv->cb(RSA_EVENT_VERIFY_COMPLETE);
+ }
+
+ return 0;
+}
+
+/**
+ \brief Get RSA status.
+ \param[in] handle rsa handle to operate.
+ \return RSA status \ref rsa_status_t
+*/
+rsa_status_t csi_rsa_get_status(rsa_handle_t handle)
+{
+ ck_rsa_priv_t *rsa_priv = handle;
+ return rsa_priv->status;
+}
diff --git a/bsp/ck802/libraries/common/rsa/ck_rsa.h b/bsp/ck802/libraries/common/rsa/ck_rsa.h
new file mode 100644
index 0000000000..31afd4d76e
--- /dev/null
+++ b/bsp/ck802/libraries/common/rsa/ck_rsa.h
@@ -0,0 +1,86 @@
+/*
+ * 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 ck_rsa.h
+ * @brief header file for rsa driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CK_RSA_H_
+#define _CK_RSA_H_
+
+#include <stdio.h>
+#include "drv_rsa.h"
+#include "soc.h"
+
+#define RSA_KEY_LEN 1024
+#define RSA_KEY_BYTE (RSA_KEY_LEN >> 3)
+#define RSA_KEY_WORD (RSA_KEY_LEN >> 5)
+
+#define BN_MAX_BITS ((RSA_KEY_LEN << 1) + 32)
+#define BN_MAX_BYTES ((BN_MAX_BITS + 7) >> 3)
+#define BN_MAX_WORDS ((BN_MAX_BYTES + 3) >> 2)
+
+#define MAX_RSA_LP_CNT 10000
+
+#define UINT32_TO_UINT64(data) ((uint64_t)(((uint64_t)(data)) & 0x00000000ffffffffU))
+#define UINT64L_TO_UINT32(data) ((uint32_t)(((uint64_t)(data)) & 0x00000000ffffffffU))
+#define UINT64H_TO_UINT32(data) ((uint32_t)((((uint64_t)(data)) >> 32) & 0x00000000ffffffffU))
+
+#define PKCS1_PADDING 0x01
+#define NO_PADDING 0x02
+
+#define MD5_PADDING 0x00
+#define SHA1_PADDING 0x01
+
+#define MD5_HASH_SZ 16
+#define SHA1_HASH_SZ 20
+
+#define RAS_CALCULATE_Q 0x6
+#define RSA_ENABLE_MODULE 0x3
+#define RSA_ENDIAN_MODE 0x8
+#define RSA_RESET 0x1
+#define RSA_CAL_Q_DONE_OFFSET 0x5
+
+typedef struct bignum {
+ uint32_t pdata[BN_MAX_WORDS];
+ uint32_t words;
+} bignum_t;
+
+typedef struct {
+ __IOM uint32_t rsa_mwid; /* Offset: 0x000 (R/W) Width of M register */
+ __IOM uint32_t rsa_ckid; /* Offset: 0x004 (R/W) Width of D register */
+ __IOM uint32_t rsa_bwid; /* Offset: 0x008 (R/W) Width of B register */
+ __IOM uint32_t rsa_ctrl; /* Offset: 0x00c (R/W) RSA control register */
+ __OM uint32_t rsa_rst; /* Offset: 0x010 (W) RSA reset register */
+ __IM uint32_t rsa_lp_cnt; /* Offset: 0x014 (R) Loop counter for inquiry register*/
+ __IM uint32_t rsa_q0; /* Offset: 0x018 (R) High-radix MM algorithm assistant register,part 1*/
+ __IM uint32_t rsa_q1; /* Offset: 0x01c (R) High-radix MM algorithm assistant register,part 2*/
+ __IOM uint32_t rsa_isr; /* Offset: 0x020 (W/R) Interrupt raw status register */
+ __IOM uint32_t rsa_imr; /* Offset: 0x024 (W/R) Interrupt mask register */
+ __IOM uint32_t rev1[54]; /* Reserve regiser */
+ __IOM uint32_t rsa_rfm; /* Offset: 0x100 (W/R) Register file for modulus M */
+ __IOM uint32_t rev2[63]; /* Reserve regiser */
+ __IOM uint32_t rsa_rfd; /* Offset: 0x200 (W/R) Register file for exponent D */
+ __IOM uint32_t rev3[63]; /* Reserve regiser */
+ __IOM uint32_t rsa_rfc; /* Offset: 0x300 (W/R) Register file for hard C */
+ __IOM uint32_t rev4[63]; /* Reserve regiser */
+ __IOM uint32_t rsa_rfb; /* Offset: 0x400 (W/R) Register file for data B */
+ __IOM uint32_t rev5[63]; /* Reserve regiser */
+ __IM uint32_t rsa_rfr; /* Offset: 0x500 (R) Register file for storing the result */
+} ck_rsa_reg_t;
+
+#endif
diff --git a/bsp/ck802/libraries/common/rtc/ck_rtc.c b/bsp/ck802/libraries/common/rtc/ck_rtc.c
new file mode 100644
index 0000000000..fd772f5ac7
--- /dev/null
+++ b/bsp/ck802/libraries/common/rtc/ck_rtc.c
@@ -0,0 +1,703 @@
+/*
+ * 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 ck_rtc.c
+ * @brief CSI Source File for RTC Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <stdbool.h>
+#include "ck_rtc.h"
+#include "csi_core.h"
+#include "drv_rtc.h"
+#include "soc.h"
+
+#define ERR_RTC(errno) (CSI_DRV_ERRNO_RTC_BASE | errno)
+
+#define RTC_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_RTC(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ rtc_event_cb_t cb_event;
+ struct tm rtc_base;
+} ck_rtc_priv_t;
+
+extern void mdelay(uint32_t ms);
+
+static ck_rtc_priv_t rtc_instance[CONFIG_RTC_NUM];
+static uint8_t leap_year[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+static uint8_t noleap_year[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+static const uint16_t g_noleap_daysbeforemonth[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
+static const uint16_t g_leap_daysbeforemonth[13] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
+
+static const rtc_capabilities_t rtc_capabilities = {
+ .interrupt_mode = 1, /* supports Interrupt mode */
+ .wrap_mode = 0 /* supports wrap mode */
+};
+
+static inline int clock_isleapyear(int year)
+{
+ return (year % 400) ? ((year % 100) ? ((year % 4) ? 0 : 1) : 0) : 1;
+}
+
+static inline int32_t ck_rtc_enable(ck_rtc_reg_t *addr)
+{
+ uint32_t value;
+
+ value = addr->RTC_CCR;
+ value |= 1 << 2;
+ addr->RTC_CCR = value;
+ return 0;
+}
+
+static inline int32_t ck_rtc_disable(ck_rtc_reg_t *addr)
+{
+ uint32_t value;
+
+ value = addr->RTC_CCR;
+ value &= ~(1 << 2);
+ addr->RTC_CCR = value;
+ return 0;
+}
+
+static int ck_rtc_settime(ck_rtc_reg_t *addr, uint32_t settime)
+{
+ if (settime < 0) {
+ return ERR_RTC(EDRV_PARAMETER);
+ }
+
+ uint64_t time = settime;
+ time = time * 20000000 / 16384;
+ time = time / 1000;
+
+ addr->RTC_CLR = (uint32_t)time;
+ return 0;
+}
+
+static time_t ck_rtc_readtime(ck_rtc_reg_t *addr)
+{
+ uint64_t time = addr->RTC_CCVR ;
+ time = time * 16384 / 20000000;
+ time = time * 1000;
+ return (time_t)time;
+}
+
+static int clock_daysbeforemonth(int month, bool leapyear)
+{
+ int retval = g_noleap_daysbeforemonth[month];
+
+ if (month >= 2 && leapyear) {
+ retval++;
+ }
+
+ return retval;
+}
+
+static time_t clock_calendar2utc(int year, int month, int day)
+{
+ time_t days;
+
+ /* Years since epoch in units of days (ignoring leap years). */
+
+ days = (year - 1970) * 365;
+
+ /* Add in the extra days for the leap years prior to the current year. */
+
+ days += (year - 1969) >> 2;
+
+ /* Add in the days up to the beginning of this month. */
+
+ days += (time_t)clock_daysbeforemonth(month, clock_isleapyear(year));
+
+ /* Add in the days since the beginning of this month (days are 1-based). */
+
+ days += day - 1;
+
+ /* Then convert the seconds and add in hours, minutes, and seconds */
+
+ return days;
+}
+
+
+time_t _mktime(struct tm *tp)
+{
+ time_t ret;
+ time_t jdn;
+
+ /* Get the EPOCH-relative julian date from the calendar year,
+ * month, and date
+ */
+
+ jdn = clock_calendar2utc(tp->tm_year + 1900, tp->tm_mon, tp->tm_mday);
+
+ /* Return the seconds into the julian day. */
+
+ ret = ((jdn * 24 + tp->tm_hour) * 60 + tp->tm_min) * 60 + tp->tm_sec;
+
+ return ret;
+}
+static void clock_utc2calendar(time_t days, int *year, int *month,
+ int *day)
+{
+
+ /* There is one leap year every four years, so we can get close with the
+ * following:
+ */
+
+ int value = days / (4 * 365 + 1); /* Number of 4-years periods since the epoch */
+ days -= value * (4 * 365 + 1); /* Remaining days */
+ value <<= 2; /* Years since the epoch */
+
+ /* Then we will brute force the next 0-3 years */
+ bool leapyear;
+ int tmp;
+
+ for (; ;) {
+ /* Is this year a leap year (we'll need this later too) */
+
+ leapyear = clock_isleapyear(value + 1970);
+
+ /* Get the number of days in the year */
+
+ tmp = (leapyear ? 366 : 365);
+
+ /* Do we have that many days? */
+
+ if (days >= tmp) {
+ /* Yes.. bump up the year */
+
+ value++;
+ days -= tmp;
+ } else {
+ /* Nope... then go handle months */
+
+ break;
+ }
+ }
+
+ /* At this point, value has the year and days has number days into this year */
+
+ *year = 1970 + value;
+
+ /* Handle the month (zero based) */
+ int min = 0;
+ int max = 11;
+
+ do {
+ /* Get the midpoint */
+
+ value = (min + max) >> 1;
+
+ /* Get the number of days that occurred before the beginning of the month
+ * following the midpoint.
+ */
+
+ tmp = clock_daysbeforemonth(value + 1, leapyear);
+
+ /* Does the number of days before this month that equal or exceed the
+ * number of days we have remaining?
+ */
+
+ if (tmp > days) {
+ /* Yes.. then the month we want is somewhere from 'min' and to the
+ * midpoint, 'value'. Could it be the midpoint?
+ */
+
+ tmp = clock_daysbeforemonth(value, leapyear);
+
+ if (tmp > days) {
+ /* No... The one we want is somewhere between min and value-1 */
+
+ max = value - 1;
+ } else {
+ /* Yes.. 'value' contains the month that we want */
+
+ break;
+ }
+ } else {
+ /* No... The one we want is somwhere between value+1 and max */
+
+ min = value + 1;
+ }
+
+ /* If we break out of the loop because min == max, then we want value
+ * to be equal to min == max.
+ */
+
+ value = min;
+ } while (min < max);
+
+ /* The selected month number is in value. Subtract the number of days in the
+ * selected month
+ */
+
+ days -= clock_daysbeforemonth(value, leapyear);
+
+ /* At this point, value has the month into this year (zero based) and days has
+ * number of days into this month (zero based)
+ */
+
+ *month = value + 1; /* 1-based */
+ *day = days + 1; /* 1-based */
+}
+
+
+struct tm *gmtime_r(const time_t *timer, struct tm *result)
+{
+ time_t epoch;
+ time_t jdn;
+ int year;
+ int month;
+ int day;
+ int hour;
+ int min;
+ int sec;
+
+ /* Get the seconds since the EPOCH */
+
+ epoch = *timer;
+
+ /* Convert to days, hours, minutes, and seconds since the EPOCH */
+
+ jdn = epoch / SEC_PER_DAY;
+ epoch -= SEC_PER_DAY * jdn;
+
+ hour = epoch / SEC_PER_HOUR;
+ epoch -= SEC_PER_HOUR * hour;
+
+ min = epoch / SEC_PER_MIN;
+ epoch -= SEC_PER_MIN * min;
+
+ sec = epoch;
+
+ /* Convert the days since the EPOCH to calendar day */
+
+ clock_utc2calendar(jdn, &year, &month, &day);
+
+
+ /* Then return the struct tm contents */
+
+ result->tm_year = (int)year - 1900; /* Relative to 1900 */
+ result->tm_mon = (int)month - 1; /* zero-based */
+ result->tm_mday = (int)day; /* one-based */
+ result->tm_hour = (int)hour;
+ result->tm_min = (int)min;
+ result->tm_sec = (int)sec;
+ return result;
+}
+static int ck_rtc_setmarchtime(ck_rtc_reg_t *addr, int64_t settime)
+{
+ int64_t time = settime;
+
+ if (settime < 0 || time >= 0x8000000000000000) {
+ return ERR_RTC(EDRV_PARAMETER);
+ }
+
+ time = time * 20000 / 16384;
+ time += addr->RTC_CCVR;
+
+ addr->RTC_CMR = (uint32_t)time;
+ return 0;
+}
+
+static int32_t ck_rtc_int_enable(ck_rtc_reg_t *addr)
+{
+ int value = addr->RTC_CCR;
+ value |= 1 << 0;
+ addr->RTC_CCR = value;
+ return 0;
+}
+
+static int32_t ck_rtc_int_disable(ck_rtc_reg_t *addr)
+{
+ uint32_t value = addr->RTC_CCR;
+ value &= ~(1 << 0);
+ addr->RTC_CCR = value;
+ ck_rtc_setmarchtime(addr, ck_rtc_readtime(addr));
+ return 0;
+}
+
+void ck_rtc_irqhandler(int32_t idx)
+{
+ ck_rtc_priv_t *rtc_priv = &rtc_instance[idx];
+ ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
+
+ addr->RTC_EOI;
+
+ if (rtc_priv->cb_event) {
+ rtc_priv->cb_event(RTC_EVENT_TIMER_INTRERRUPT);
+ }
+
+}
+
+int32_t __attribute__((weak)) target_get_rtc_count(void)
+{
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_rtc(uint32_t idx, uint32_t *base, uint32_t *irq)
+{
+ return NULL;
+}
+
+/**
+ \brief get rtc instance count.
+ \return rtc instance count
+*/
+int32_t csi_rtc_get_instance_count(void)
+{
+ return target_get_rtc_count();
+}
+
+/**
+ \brief Initialize RTC Interface. 1. Initializes the resources needed for the RTC interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_rtc_get_instance_count()
+ \param[in] cb_event Pointer to \ref rtc_event_cb_t
+ \return pointer to rtc instance
+*/
+rtc_handle_t csi_rtc_initialize(int32_t idx, rtc_event_cb_t cb_event)
+{
+ if (idx < 0 || idx >= CONFIG_RTC_NUM) {
+ return NULL;
+ }
+
+ int32_t real_idx;
+ uint32_t base = 0u;
+ uint32_t irq;
+
+ real_idx = target_get_rtc(idx, &base, &irq);
+
+ if (real_idx != idx) {
+ return NULL;
+ }
+
+ ck_rtc_priv_t *rtc_priv;
+
+ rtc_priv = &rtc_instance[idx];
+ rtc_priv->base = base;
+ rtc_priv->irq = irq;
+
+ ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
+
+ rtc_priv->cb_event = cb_event;
+ addr->RTC_CCR = 0;
+ drv_nvic_enable_irq(rtc_priv->irq);
+
+ return (rtc_handle_t)rtc_priv;
+}
+
+/**
+ \brief De-initialize RTC Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle rtc handle to operate.
+ \return \ref execution_status
+*/
+int32_t csi_rtc_uninitialize(rtc_handle_t handle)
+{
+ RTC_NULL_PARAM_CHK(handle);
+
+ ck_rtc_priv_t *rtc_priv = handle;
+
+ rtc_priv->cb_event = NULL;
+ drv_nvic_disable_irq(rtc_priv->irq);
+
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle rtc handle to operate.
+ \return \ref rtc_capabilities_t
+*/
+rtc_capabilities_t csi_rtc_get_capabilities(rtc_handle_t handle)
+{
+ return rtc_capabilities;
+}
+
+/**
+ \brief Set RTC timer.
+ \param[in] handle rtc handle to operate.
+ \param[in] rtctime \ref struct tm
+ \return \ref execution_status
+*/
+int32_t csi_rtc_set_time(rtc_handle_t handle, const struct tm *rtctime)
+{
+ RTC_NULL_PARAM_CHK(handle);
+ RTC_NULL_PARAM_CHK(rtctime);
+
+ ck_rtc_priv_t *rtc_priv = handle;
+ ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
+
+
+ if (rtctime->tm_year < 70 || rtctime->tm_year >= 200) {
+ goto error_time;
+ }
+
+ int32_t leap = 1;
+
+ leap = clock_isleapyear(rtctime->tm_year + 1900);
+
+ if (rtctime->tm_sec < 0 || rtctime->tm_sec >= 60) {
+ goto error_time;
+ }
+
+ if (rtctime->tm_min < 0 || rtctime->tm_min >= 60) {
+ goto error_time;
+ }
+
+ if (rtctime->tm_hour < 0 || rtctime->tm_hour >= 24) {
+ goto error_time;
+ }
+
+ if (rtctime->tm_mon < 0 || rtctime->tm_mon >= 12) {
+ goto error_time;
+ }
+
+ if (leap) {
+ if (rtctime->tm_mday < 1 || rtctime->tm_mday > leap_year[rtctime->tm_mon]) {
+ goto error_time;
+ }
+ } else {
+ if (rtctime->tm_mday < 1 || rtctime->tm_mday > noleap_year[rtctime->tm_mon]) {
+ goto error_time;
+ }
+ }
+
+ rtc_priv->rtc_base.tm_sec = rtctime->tm_sec;
+ rtc_priv->rtc_base.tm_min = rtctime->tm_min;
+ rtc_priv->rtc_base.tm_hour = rtctime->tm_hour;
+ rtc_priv->rtc_base.tm_mday = rtctime->tm_mday;
+ rtc_priv->rtc_base.tm_mon = rtctime->tm_mon;
+ rtc_priv->rtc_base.tm_year = rtctime->tm_year;
+
+ ck_rtc_settime(addr, 0);
+ return 0;
+
+error_time:
+ return ERR_RTC(EDRV_RTC_TIME);
+
+}
+
+/**
+ \brief Get RTC timer.
+ \param[in] handle rtc handle to operate.
+ \param[in] rtctime \ref struct tm
+ \return \ref execution_status
+*/
+int32_t csi_rtc_get_time(rtc_handle_t handle, struct tm *rtctime)
+{
+ RTC_NULL_PARAM_CHK(handle);
+
+ ck_rtc_priv_t *rtc_priv = handle;
+ ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
+ time_t time = ck_rtc_readtime(addr);
+ time = time / 1000;
+ time += _mktime(&(rtc_priv->rtc_base));
+ gmtime_r(&time, rtctime);
+
+ return 0;
+
+}
+
+/**
+ \brief Start RTC timer.
+ \param[in] handle rtc handle to operate.
+ \return \ref execution_status
+*/
+int32_t csi_rtc_start(rtc_handle_t handle)
+{
+ RTC_NULL_PARAM_CHK(handle);
+
+ ck_rtc_priv_t *rtc_priv = handle;
+ ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
+
+ ck_rtc_enable(addr);
+ return 0;
+}
+
+/**
+ \brief Stop RTC timer.
+ \param[in] handle rtc handle to operate.
+ \return \ref execution_status
+*/
+int32_t csi_rtc_stop(rtc_handle_t handle)
+{
+ RTC_NULL_PARAM_CHK(handle);
+
+ ck_rtc_priv_t *rtc_priv = handle;
+ ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
+
+ ck_rtc_disable(addr);
+ return 0;
+}
+
+/**
+ \brief Get RTC status.
+ \param[in] handle rtc handle to operate.
+ \return RTC status \ref rtc_status_t
+*/
+rtc_status_t csi_rtc_get_status(rtc_handle_t handle)
+{
+ rtc_status_t rtc_status = {0};
+
+ if (handle == NULL) {
+ return rtc_status;
+ }
+
+ ck_rtc_priv_t *rtc_priv = handle;
+ ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
+
+ if (addr->RTC_RSTAT & 0x1) {
+ rtc_status.active = 1;
+ }
+
+ return rtc_status;
+}
+
+/**
+ \brief config RTC timer.
+ \param[in] handle rtc handle to operate.
+ \param[in] rtctime time to wake up
+ \return error code
+*/
+int32_t csi_rtc_timer_config(rtc_handle_t handle, const struct tm *rtctime)
+{
+ RTC_NULL_PARAM_CHK(handle);
+
+ ck_rtc_priv_t *rtc_priv = handle;
+ ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
+
+ if (rtctime->tm_year < 70 || rtctime->tm_year >= 200) {
+ goto error_time;
+ }
+
+ int32_t leap = clock_isleapyear(rtctime->tm_year + 1900);
+
+ if (rtctime->tm_sec < 0 || rtctime->tm_sec >= 60) {
+ goto error_time;
+ }
+
+ if (rtctime->tm_min < 0 || rtctime->tm_min >= 60) {
+ goto error_time;
+ }
+
+ if (rtctime->tm_hour < 0 || rtctime->tm_hour >= 24) {
+ goto error_time;
+ }
+
+ if (rtctime->tm_mon < 0 || rtctime->tm_mon >= 12) {
+ goto error_time;
+ }
+
+ if (leap) {
+ if (rtctime->tm_mday < 1 || rtctime->tm_mday > leap_year[rtctime->tm_mon]) {
+ goto error_time;
+ }
+ } else {
+ if (rtctime->tm_mday < 1 || rtctime->tm_mday > noleap_year[rtctime->tm_mon]) {
+ goto error_time;
+ }
+ }
+
+ /* after setting RTC counter load register(RTC_CLT), loading to RTC_CCVR need two rtc clocks.
+ * two rtc clocks about 3ms. setting 10ms to ensure operation is completed.
+ */
+ mdelay(10);
+ struct tm current_time;
+ int32_t ret = csi_rtc_get_time(handle, &current_time);
+
+ if (ret < 0) {
+ return ERR_RTC(EDRV_PARAMETER);
+ }
+
+ int64_t settime = 0;
+ settime += ((int64_t)(rtctime->tm_year) - (int64_t)(rtc_priv->rtc_base.tm_year)) * (365 + (int64_t)leap) * 24 * 3600 * 1000;
+
+ if (settime < 0) {
+ goto error_time;
+ }
+
+ if (leap) {
+ settime += (int64_t)(g_leap_daysbeforemonth[rtctime->tm_mon + 1] + rtctime->tm_mday - g_leap_daysbeforemonth[current_time.tm_mon + 1] - current_time.tm_mday) * 24 * 3600 * 1000;
+
+ if (settime < 0) {
+ goto error_time;
+ }
+
+ } else {
+ settime += (int64_t)(g_noleap_daysbeforemonth[rtctime->tm_mon + 1] + rtctime->tm_mday - g_noleap_daysbeforemonth[current_time.tm_mon + 1] - current_time.tm_mday) * 24 * 3600 * 1000;
+
+ if (settime < 0) {
+ goto error_time;
+ }
+
+ }
+
+ settime += (int64_t)(rtctime->tm_hour - current_time.tm_hour) * 3600 * 1000;
+
+ if (settime < 0) {
+ goto error_time;
+ }
+
+ settime += (int64_t)(rtctime->tm_min - current_time.tm_min) * 60 * 1000;
+
+ if (settime < 0) {
+ goto error_time;
+ }
+
+ settime += (int64_t)(rtctime->tm_sec - current_time.tm_sec) * 1000;
+
+ if (settime < 0) {
+ goto error_time;
+ }
+
+ ck_rtc_setmarchtime(addr, settime);
+
+ return 0;
+error_time:
+ return ERR_RTC(EDRV_RTC_TIME);
+}
+
+/**
+ \brief disable or enable RTC timer.
+ \param[in] handle rtc handle to operate.
+ \param[in] en set 1 enable for rtc timer
+ \return error code
+*/
+int32_t csi_rtc_timer_enable(rtc_handle_t handle, uint8_t en)
+{
+ RTC_NULL_PARAM_CHK(handle);
+
+ ck_rtc_priv_t *rtc_priv = handle;
+ ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
+
+ if (en == 1) {
+ ck_rtc_int_enable(addr);
+ } else if (en == 0) {
+ ck_rtc_int_disable(addr);
+ } else {
+ return ERR_RTC(EDRV_PARAMETER);
+ }
+
+ return 0;
+}
+
diff --git a/bsp/ck802/libraries/common/rtc/ck_rtc.h b/bsp/ck802/libraries/common/rtc/ck_rtc.h
new file mode 100644
index 0000000000..8d8d95c1a9
--- /dev/null
+++ b/bsp/ck802/libraries/common/rtc/ck_rtc.h
@@ -0,0 +1,44 @@
+/*
+ * 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 ck_rtc.h
+ * @brief header file for rtc driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef __CK_RTC_H
+#define __CK_RTC_H
+
+#include <stdio.h>
+#include "soc.h"
+
+#define SEC_PER_MIN ((time_t)60)
+#define SEC_PER_HOUR ((time_t)60 * SEC_PER_MIN)
+#define SEC_PER_DAY ((time_t)24 * SEC_PER_HOUR)
+
+typedef struct {
+ __IM uint32_t RTC_CCVR; /* Offset: 0x000 (R/ ) current count value register */
+ __IOM uint32_t RTC_CMR; /* Offset: 0x004 (R/W) count match register */
+ __IOM uint32_t RTC_CLR; /* Offset: 0x008 (R/W) count load register */
+ __IOM uint32_t RTC_CCR; /* Offset: 0x00c (R/W) count control register */
+ __IM uint32_t RTC_STAT; /* Offset: 0x010 (R/ ) interrupt status register */
+ __IM uint32_t RTC_RSTAT; /* Offset: 0x014 (R/ ) interrupt raw status register */
+ __IM uint32_t RTC_EOI; /* Offset: 0x018 (R/ ) end of interrupt register */
+ __IM uint32_t RTC_COMP_VERSION; /* Offset: 0x01c (R/ ) component version register */
+} ck_rtc_reg_t;
+
+#endif /* __CK_RTC_H */
+
diff --git a/bsp/ck802/libraries/common/sha/ck_sha.c b/bsp/ck802/libraries/common/sha/ck_sha.c
new file mode 100644
index 0000000000..1a58c595c9
--- /dev/null
+++ b/bsp/ck802/libraries/common/sha/ck_sha.c
@@ -0,0 +1,538 @@
+/*
+ * 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 ck_sha.c
+ * @brief CSI Source File for SHA Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include "csi_core.h"
+#include "drv_sha.h"
+#include "ck_sha.h"
+
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ sha_event_cb_t cb;
+ sha_status_t status;
+ sha_mode_e mode;
+ sha_endian_mode_e endian;
+} ck_sha_priv_t;
+
+static ck_sha_priv_t sha_handle[CONFIG_SHA_NUM];
+bool finish_flag = 0;
+
+/* Driver Capabilities */
+static const sha_capabilities_t driver_capabilities = {
+ .sha1 = 1, /* sha1 mode */
+ .sha224 = 1, /* sha224 mode */
+ .sha256 = 1, /* sha256 mode */
+ .sha384 = 1, /* sha384 mode */
+ .sha512 = 1, /* sha512 mode */
+ .sha512_224 = 1, /* sha512_224 mode */
+ .sha512_256 = 1, /* sha512_256 mode */
+ .endianmode = 1, /* endian mode */
+ .interruptmode = 1 /* interrupt mode */
+};
+
+#define ERR_SHA(errno) (CSI_DRV_ERRNO_SHA_BASE | errno)
+#define SHA_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_SHA(EDRV_PARAMETER); \
+ } \
+ } while (0)
+//
+// Functions
+//
+
+ck_sha_reg_t *sha_reg = NULL;
+volatile static uint8_t sha_int_flag = 1;
+
+static int32_t sha_set_mode(sha_mode_e mode)
+{
+ sha_reg->SHA_CON = mode;
+ return 0;
+}
+
+static int32_t sha_enable_interrupt(void)
+{
+ sha_reg->SHA_CON |= 1 << SHA_INT_ENABLE_OFFSET;
+ return 0;
+}
+
+static int32_t sha_disable_interrupt(void)
+{
+ sha_reg->SHA_CON &= ~(1 << SHA_INT_ENABLE_OFFSET);
+ return 0;
+}
+
+static void sha_clear_interrupt(void)
+{
+ sha_reg->SHA_INTSTATE = 0;
+}
+
+static int32_t sha_enable_initial(void)
+{
+ sha_reg->SHA_CON |= 1 << SHA_INIT_OFFSET;
+ return 0;
+}
+
+static int32_t sha_enable_calculate(void)
+{
+ sha_reg->SHA_CON |= 1 << SHA_CAL_OFFSET;
+ return 0;
+}
+
+static int32_t sha_select_endian_mode(sha_endian_mode_e mode)
+{
+ sha_reg->SHA_CON |= mode << SHA_ENDIAN_OFFSET;
+ return 0;
+}
+
+static int32_t sha_input_data(uint32_t *data, uint32_t length)
+{
+ uint8_t i;
+ uint32_t *input_data = (uint32_t *) & (sha_reg->SHA_DATA1);
+
+ for (i = 0; i < length; i++) {
+ *(input_data + i) = *(data + i);
+ }
+
+ return 0;
+}
+
+static int32_t sha_get_data(sha_handle_t handle, uint32_t *data)
+{
+ ck_sha_priv_t *sha_priv = handle;
+
+ uint8_t len;
+ uint8_t i;
+ uint32_t *result = (uint32_t *)&sha_reg->SHA_H0L;
+ /* according to different mode to obtain the hash result */
+ if (sha_priv->mode == SHA_MODE_1 || sha_priv->mode == SHA_MODE_224 || sha_priv->mode == SHA_MODE_256) {
+ if (sha_priv->mode == SHA_MODE_1) {
+ len = 5;
+ } else if (sha_priv->mode == SHA_MODE_224) {
+ len = 7;
+ } else if (sha_priv->mode == SHA_MODE_256) {
+ len = 8;
+ }
+
+ for (i = 0; i < len; i++) {
+ data[i] = *(result + i);
+ }
+ } else {
+ if (sha_priv->mode == SHA_MODE_384) {
+ len = 6;
+ } else if (sha_priv->mode == SHA_MODE_512) {
+ len = 8;
+ }
+
+ uint32_t *resulth = (uint32_t *)&sha_reg->SHA_H0H;
+ for (i = 0; i < len; i++) {
+ data[i << 1] = *(resulth + i);
+ data[(i << 1) + 1] = *(result + i);
+ }
+ }
+
+ return 0;
+}
+
+static inline void sha_reverse_order(uint8_t *pdata, int32_t length)
+{
+ uint8_t input_data[length];
+ uint8_t result[length];
+ uint32_t tmp = 0;
+ int32_t i = 0;
+ memcpy((void *)input_data, (void *)pdata, length);
+
+ for (i = 0; i < length; i++) {
+ tmp = i >> 2;
+ tmp = tmp << 3;
+ result[i] = input_data[tmp + 3 - i];
+ }
+
+ memcpy((void *)pdata, (void *)result, length);
+}
+
+void ck_sha_irqhandler(int32_t idx)
+{
+ sha_int_flag = 0;
+ sha_clear_interrupt(); //clear sha interrupt
+
+ ck_sha_priv_t *sha_priv = &sha_handle[idx];
+ if (finish_flag != 0) {
+ if (sha_priv->cb != NULL) {
+ sha_priv->cb(SHA_EVENT_COMPLETE); //execute the callback function
+ }
+ }
+}
+
+int32_t __attribute__((weak)) target_get_sha_count(void)
+{
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq)
+{
+ return NULL;
+}
+
+/**
+ \brief get sha handle count.
+ \return sha handle count
+*/
+int32_t csi_sha_get_instance_count(void)
+{
+ return target_get_sha_count();
+}
+
+/**
+ \brief Initialize SHA Interface. 1. Initializes the resources needed for the SHA interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_sha_get_instance_count()
+ \param[in] cb_event Pointer to \ref sha_event_cb_t
+ \return return sha handle if success
+*/
+sha_handle_t csi_sha_initialize(int32_t idx, sha_event_cb_t cb_event)
+{
+
+ if (idx < 0 || idx >= CONFIG_SHA_NUM) {
+ return NULL;
+ }
+
+ uint32_t base = 0u;
+ uint32_t irq;
+ /* obtain the sha information */
+ int32_t real_idx = target_get_sha(idx, &base, &irq);
+
+ if (real_idx != idx) {
+ return NULL;
+ }
+
+ ck_sha_priv_t *sha_priv = &sha_handle[idx];
+
+ sha_priv->base = base;
+ sha_priv->irq = irq;
+
+ /* initialize the sha context */
+ sha_priv->cb = cb_event;
+ sha_priv->status.busy = 0;
+
+ drv_nvic_enable_irq(sha_priv->irq);
+
+ return (sha_handle_t)sha_priv;
+}
+
+/**
+ \brief De-initialize SHA Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle sha handle to operate.
+ \return error code
+*/
+int32_t csi_sha_uninitialize(sha_handle_t handle)
+{
+ SHA_NULL_PARAM_CHK(handle);
+
+ ck_sha_priv_t *sha_priv = handle;
+ sha_priv->cb = NULL;
+
+ sha_disable_interrupt();
+ drv_nvic_disable_irq(sha_priv->irq);
+
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle sha handle to operate.
+ \return \ref sha_capabilities_t
+*/
+sha_capabilities_t csi_sha_get_capabilities(sha_handle_t handle)
+{
+ return driver_capabilities;
+}
+
+/**
+ \brief config sha mode.
+ \param[in] handle sha handle to operate.
+ \param[in] mode \ref sha_mode_e
+ \param[in] endian \ref sha_endian_mode_e
+ \return error code
+*/
+int32_t csi_sha_config(sha_handle_t handle, sha_mode_e mode, sha_endian_mode_e endian_mode)
+{
+ SHA_NULL_PARAM_CHK(handle);
+
+ ck_sha_priv_t *sha_priv = handle;
+ sha_reg = (ck_sha_reg_t *)(sha_priv->base);
+
+ /* config the sha mode */
+ switch (mode) {
+ case SHA_MODE_512_256:
+ case SHA_MODE_512_224:
+ return ERR_SHA(EDRV_UNSUPPORTED);
+
+ case SHA_MODE_1:
+ case SHA_MODE_224:
+ case SHA_MODE_256:
+ case SHA_MODE_384:
+ case SHA_MODE_512:
+ sha_priv->mode = mode;
+ break;
+
+ default:
+ return ERR_SHA(EDRV_PARAMETER);
+ }
+
+ sha_set_mode(mode);
+
+ /*config the sha endian mode */
+ if (endian_mode == SHA_ENDIAN_MODE_LITTLE) {
+ sha_priv->endian = endian_mode;
+ sha_select_endian_mode(endian_mode);
+ } else if (endian_mode == SHA_ENDIAN_MODE_BIG) {
+ sha_priv->endian = endian_mode;
+ sha_select_endian_mode(endian_mode);
+ } else {
+ return ERR_SHA(EDRV_PARAMETER);
+ }
+
+ sha_enable_interrupt();
+
+ return 0;
+}
+
+/**
+ \brief start the engine
+ \param[in] handle sha handle to operate.
+ \param[in] context Pointer to the sha context.
+ \return error code
+*/
+int32_t csi_sha_starts(sha_handle_t handle, void *context)
+{
+ SHA_NULL_PARAM_CHK(handle);
+
+ ck_sha_priv_t *sha_priv = handle;
+ sha_enable_initial();
+ sha_priv->status.busy = 1;
+
+ return 0;
+}
+
+/**
+ \brief updata the engine
+ \param[in] handle sha handle to operate.
+ \param[in] context Pointer to the sha context.
+ \param[in] input Pointer to the Source data
+ \param[in] len the data len
+ \return error code
+*/
+static uint8_t sha_buffer[128];
+static uint32_t total[2] = {0x0};
+static uint32_t last_left = 0;
+int32_t csi_sha_update(sha_handle_t handle, void *context, const void *input, uint32_t len)
+{
+ SHA_NULL_PARAM_CHK(handle);
+ SHA_NULL_PARAM_CHK(input);
+ if (len <= 0) {
+ return ERR_SHA(EDRV_PARAMETER);
+ }
+
+ ck_sha_priv_t *sha_priv = handle;
+ sha_reg = (ck_sha_reg_t *)(sha_priv->base);
+
+ uint32_t block_size;
+ uint32_t left_len = 0;
+ if (sha_priv->mode < 4) {
+ block_size = 64;
+ left_len = len & 0x3f;
+ } else {
+ block_size = 128;
+ left_len = len & 0x7f;
+ }
+
+ uint32_t left = total[0] & (block_size - 1);
+ uint32_t fill = block_size - left;
+
+ total[0] += len;
+ total[0] &= 0xffffffff;
+ uint32_t word_left = total[0] & 0x3;
+
+ uint8_t *p = (uint8_t *)input;
+ /* when the text is not aligned by block and len > fill */
+ if (left && len >= fill) {
+ if (last_left && sha_priv->endian == SHA_ENDIAN_MODE_LITTLE) {
+ uint32_t i;
+ for (i = 0; i < 4 - last_left; i++) {
+ if (finish_flag) {
+ *(sha_buffer + 3 - last_left - i) = *((uint8_t *)p + 3 - last_left - i);
+ } else {
+ *(sha_buffer + left + 3 - last_left - i) = *((uint8_t *)p + 3 - last_left - i);
+ }
+ }
+
+ fill = fill - 4 + last_left;
+ p = (p + 4 - last_left);
+ }
+
+ if (last_left) {
+ memcpy((void *)(sha_buffer + left + 4 - last_left), p, fill);
+ } else {
+ memcpy((void *)(sha_buffer + left), p, fill);
+ }
+
+ /* set the input data */
+ sha_input_data((uint32_t *)sha_buffer, block_size >> 2);
+ sha_enable_calculate();
+
+ while (sha_int_flag);
+
+ sha_int_flag = 1;
+ p += fill;
+ len -= fill;
+ left = 0;
+ }
+
+ /* calculate the hash by block */
+ while (len >= block_size) {
+ sha_input_data((uint32_t *)p, block_size >> 2);
+ sha_enable_calculate();
+
+ while (sha_int_flag);
+
+ sha_int_flag = 1;
+ p += block_size;
+ len -= block_size;
+ }
+
+ /* when the text is not aligned by block and len < fill */
+ if (len > 0) {
+ if (sha_priv->endian == SHA_ENDIAN_MODE_BIG || word_left == 0) {
+ memcpy((void *)(sha_buffer + left), p, len);
+ } else {
+ memcpy((void *)(sha_buffer + left), p, len + 4 - word_left);
+ last_left = word_left;
+ }
+ }
+
+ sha_priv->status.busy = 0;
+
+ return 0;
+}
+
+static unsigned char sha_padding[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/**
+ \brief finish the engine
+ \param[in] handle sha handle to operate.
+ \param[in] context Pointer to the sha context.
+ \param[out] output Pointer to the dest data
+ \return error code
+*/
+static uint32_t total_length;
+int32_t csi_sha_finish(sha_handle_t handle, void *context, void *output)
+{
+ SHA_NULL_PARAM_CHK(handle);
+ SHA_NULL_PARAM_CHK(output);
+
+ ck_sha_priv_t *sha_priv = handle;
+ uint32_t block_size;
+ if (sha_priv->mode < 4) {
+ block_size = 64;
+ } else {
+ block_size = 128;
+ }
+
+ total_length = total[0] << 3;
+ uint32_t last = total[0] & (block_size - 1);
+ uint32_t padn = (last < block_size) ? (block_size - last) : (block_size + block_size - last);
+
+ uint32_t left = total[0] & 0x3;
+
+ uint8_t temp_data[4];
+ uint32_t j;
+ /*calculate the final word*/
+ for (j = 0; j < 4; j++) {
+ temp_data[j] = (total_length >> (8 * j)) & 0xff;
+ }
+
+ /* group the final package according to the endian mode */
+ if (sha_priv->endian == SHA_ENDIAN_MODE_BIG) {
+ memset(sha_padding, 0x0, sizeof(sha_padding));
+ sha_padding[0] = 0x80;
+
+ for (j = 0; j < 4; j++) {
+ sha_padding[padn - 4 + j] = temp_data[3 - j];
+ }
+ } else {
+ memset(sha_padding, 0x0, sizeof(sha_padding));
+ sha_padding[3 - left] = 0x80;
+
+ for (j = 0; j < 4; j++) {
+ sha_padding[padn - 4 + j] = temp_data[j];
+ }
+ }
+
+ finish_flag = 1;
+
+ csi_sha_update(handle, NULL, sha_padding, padn);
+
+ /* get the hash result */
+ sha_get_data(handle, (uint32_t *)output);
+
+ uint8_t *p = output;
+ /* convert the data endian according the sha mode */
+ if (sha_priv->mode == SHA_MODE_1) {
+ sha_reverse_order(p, 20);
+ } else if (sha_priv->mode == SHA_MODE_224) {
+ sha_reverse_order(p, 28);
+ } else if (sha_priv->mode == SHA_MODE_256) {
+ sha_reverse_order(p, 32);
+ } else if (sha_priv->mode == SHA_MODE_512) {
+ sha_reverse_order(p, 64);
+ } else if (sha_priv->mode == SHA_MODE_384) {
+ sha_reverse_order(p, 48);
+ }
+
+ total[0] = 0;
+ memset(sha_buffer, 0, sizeof(sha_buffer));
+ memset(sha_padding, 0, sizeof(sha_padding));
+ last_left = 0;
+ finish_flag = 0;
+
+ return 0;
+}
+
+/**
+ \brief Get SHA status.
+ \param[in] handle sha handle to operate.
+ \return SHA status \ref sha_status_t
+*/
+sha_status_t csi_sha_get_status(sha_handle_t handle)
+{
+ ck_sha_priv_t *sha_priv = handle;
+ return sha_priv->status;
+}
diff --git a/bsp/ck802/libraries/common/sha/ck_sha.h b/bsp/ck802/libraries/common/sha/ck_sha.h
new file mode 100644
index 0000000000..c6fea64384
--- /dev/null
+++ b/bsp/ck802/libraries/common/sha/ck_sha.h
@@ -0,0 +1,63 @@
+/*
+ * 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 ck_sha.h
+ * @brief header file for sha driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CK_SHA_H_
+#define _CK_SHA_H_
+
+#include <stdio.h>
+#include "drv_sha.h"
+#include "soc.h"
+
+#define SHA_INIT_OFFSET 3
+#define SHA_INT_ENABLE_OFFSET 4
+#define SHA_ENDIAN_OFFSET 5
+#define SHA_CAL_OFFSET 6
+typedef struct {
+ __IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */
+ __IOM uint32_t SHA_INTSTATE; /* Offset: 0x004 (R/W) Instatus register */
+ __IOM uint32_t SHA_H0L; /* Offset: 0x008 (R/W) H0L register */
+ __IOM uint32_t SHA_H1L; /* Offset: 0x00c (R/W) H1L register */
+ __IOM uint32_t SHA_H2L; /* Offset: 0x010 (R/W) H2L register */
+ __IOM uint32_t SHA_H3L; /* Offset: 0x014 (R/W) H3L register */
+ __IOM uint32_t SHA_H4L; /* Offset: 0x018 (R/W) H4L register */
+ __IOM uint32_t SHA_H5L; /* Offset: 0x01c (R/W) H5L register */
+ __IOM uint32_t SHA_H6L; /* Offset: 0x020 (R/W) H6L register */
+ __IOM uint32_t SHA_H7L; /* Offset: 0x024 (R/W) H7L register */
+ __IOM uint32_t SHA_H0H; /* Offset: 0x028 (R/W) H0H register */
+ __IOM uint32_t SHA_H1H; /* Offset: 0x02c (R/W) H1H register */
+ __IOM uint32_t SHA_H2H; /* Offset: 0x030 (R/W) H2H register */
+ __IOM uint32_t SHA_H3H; /* Offset: 0x034 (R/W) H3H register */
+ __IOM uint32_t SHA_H4H; /* Offset: 0x038 (R/W) H4H register */
+ __IOM uint32_t SHA_H5H; /* Offset: 0x03c (R/W) H5H register */
+ __IOM uint32_t SHA_H6H; /* Offset: 0x040 (R/W) H6H register */
+ __IOM uint32_t SHA_H7H; /* Offset: 0x044 (R/W) H7H register */
+ __IOM uint32_t SHA_DATA1; /* Offset: 0x048 (R/W) DATA1 register */
+ uint32_t REV[15];
+ __IOM uint32_t SHA_DATA2; /* Offset: 0x088 (R/W) DATA2 register */
+} ck_sha_reg_t;
+#endif
+
+typedef enum {
+ SHA_STATUS_START_END = 0, /* the one time count mode */
+ SHA_STATUS_START = 1, /* the first time of the cal */
+ SHA_STATUS_CONTINUE = 2, /* the middle stage of the cal */
+ SHA_STATUS_END = 3 /* the last time of the cal*/
+} enum_sha_status;
diff --git a/bsp/ck802/libraries/common/spi/dw_spi.c b/bsp/ck802/libraries/common/spi/dw_spi.c
new file mode 100644
index 0000000000..f0016f5075
--- /dev/null
+++ b/bsp/ck802/libraries/common/spi/dw_spi.c
@@ -0,0 +1,1237 @@
+/*
+ * 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 dw_spi.c
+ * @brief CSI Source File for SPI Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include "csi_core.h"
+#include "drv_spi.h"
+#include "dw_spi.h"
+#include "drv_gpio.h"
+#ifdef CONFIG_SPI_DMA
+#include "ck_dmac.h"
+#include <string.h>
+#endif
+#include "soc.h" /*CONFIG_SPI_NUM*/
+
+#define ERR_SPI(errno) (CSI_DRV_ERRNO_SPI_BASE | errno)
+
+#define SPI_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_SPI(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ pin_t ssel;
+ spi_event_cb_t cb_event;
+ void *cb_arg;
+ uint32_t send_num;
+ uint32_t recv_num;
+ uint8_t *send_buf;
+ uint8_t *recv_buf;
+ uint8_t enable_slave;
+ uint32_t transfer_num;
+ uint32_t clk_num; //clock number with a process of communication
+ uint8_t state; //Current SPI state
+ uint32_t mode; //Current SPI mode
+ uint8_t ss_mode;
+ spi_status_t status;
+#ifdef CONFIG_SPI_DMA
+ dmac_handle_t dma_handle;
+ int32_t dma_tx_id;
+ int32_t dma_rx_id;
+#endif
+} dw_spi_priv_t;
+
+static dw_spi_priv_t spi_instance[CONFIG_SPI_NUM];
+static gpio_pin_handle_t pgpio_pin_handle;
+
+static const spi_capabilities_t spi_capabilities = {
+ .simplex = 1, /* Simplex Mode (Master and Slave) */
+ .ti_ssi = 1, /* TI Synchronous Serial Interface */
+ .microwire = 1, /* Microwire Interface */
+ .event_mode_fault = 0 /* Signal Mode Fault event: \ref CSKY_SPI_EVENT_MODE_FAULT */
+};
+
+static int32_t dw_spi_set_datawidth(dw_spi_reg_t *addr, DWENUM_SPI_DATAWIDTH datawidth);
+static int32_t dw_spi_set_mode(spi_handle_t handle, DWENUM_SPI_MODE mode);
+
+/**
+ \brief use phobos gpio pin to simulate ss line for hardware controlled Output mode.
+*/
+static int32_t dw_spi_ss_init(dw_spi_priv_t *spi_priv)
+{
+ csi_gpio_port_initialize(0, NULL);
+ pgpio_pin_handle = csi_gpio_pin_initialize(spi_priv->ssel);
+ csi_gpio_pin_config(pgpio_pin_handle, GPIO_MODE_PULLNONE, GPIO_DIRECTION_OUTPUT);
+ csi_gpio_pin_write(pgpio_pin_handle, true);
+ spi_priv->ss_mode = SPI_SS_MASTER_HW_OUTPUT;
+ return 0;
+}
+
+/**
+ \brief control ss line depend on controlled Output mode.
+*/
+static int32_t dw_spi_ss_control(dw_spi_priv_t *spi_priv, spi_ss_stat_e stat)
+{
+ if (spi_priv->ss_mode == SPI_SS_MASTER_HW_OUTPUT) {
+ if (stat == SPI_SS_INACTIVE) {
+ csi_gpio_pin_write(pgpio_pin_handle, true);
+ } else if (stat == SPI_SS_ACTIVE) {
+ csi_gpio_pin_write(pgpio_pin_handle, false);
+ } else {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_SPI_DMA
+void dw_spi_dma_event_cb(dma_event_e event, int32_t ch)
+{
+ dw_spi_priv_t *spi_priv = NULL;
+
+ uint8_t i = 0u;
+
+ for (i = 0; i < CONFIG_SPI_NUM; i++) { /* find the SPI id */
+ spi_priv = &spi_instance[i];
+
+ if ((spi_priv->dma_tx_id == ch) || (spi_priv->dma_rx_id == ch)) {
+ break;
+ }
+ }
+
+
+ if (spi_priv->dma_tx_id == ch) {
+ spi_priv->dma_tx_id = -1;
+ } else {
+ spi_priv->dma_rx_id = -1;
+ }
+
+ if (event == DMA_EVENT_TRANSFER_ERROR) { /* DMA transfer ERROR */
+
+ if (spi_priv->cb_event) {
+ spi_priv->cb_event(SPI_EVENT_DATA_LOST, NULL);
+ }
+ } else if (event == DMA_EVENT_TRANSFER_DONE) { /* DMA transfer complete */
+
+ if (spi_priv->mode == DWENUM_SPI_TXRX) {
+ if (spi_priv->cb_event) {
+ spi_priv->cb_event(SPI_EVENT_TRANSFER_COMPLETE, spi_priv->cb_arg);
+ }
+ } else if (spi_priv->mode == DWENUM_SPI_TX) {
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+
+ while (addr->SR & DW_SPI_DISABLE);
+
+ if (spi_priv->cb_event) {
+ spi_priv->cb_event(SPI_EVENT_TX_COMPLETE, spi_priv->cb_arg);
+ }
+ } else {
+ if (spi_priv->cb_event) {
+ spi_priv->cb_event(SPI_EVENT_RX_COMPLETE, spi_priv->cb_arg);
+ }
+ }
+ }
+
+ spi_priv->status.busy = 0U;
+}
+
+/**
+ \brief sending data to SPI transmitter with DMA,(received data is ignored).
+*/
+static int32_t dw_spi_dma_send(dw_spi_priv_t *spi_priv, const void *data, uint32_t num)
+{
+ int32_t ch = csi_dma_alloc_channel(spi_priv->dma_handle, -1);
+ spi_priv->dma_tx_id = ch;
+
+ dma_config_t config;
+ config.src_inc = DMA_ADDR_INC;
+ config.dst_inc = DMA_ADDR_CONSTANT;
+ config.src_tw = DMA_DATAWIDTH_SIZE8;
+ config.dst_tw = DMA_DATAWIDTH_SIZE8;
+ config.hs_if = CKENUM_DMA_SPI1_TX;
+ config.type = DMA_MEM2PERH;
+
+ dw_spi_ss_control(spi_priv, SPI_SS_ACTIVE);
+
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+ uint8_t *ptxbuffer = (uint8_t *)data;
+
+ int32_t ret = csi_dma_config(spi_priv->dma_handle, ch, ptxbuffer, (uint8_t *) & (addr->DR), num, &config, dw_spi_dma_event_cb);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ addr->SPIENR = DW_SPI_DISABLE; /* enable SPI */
+ dw_spi_set_mode(spi_priv, DWENUM_SPI_TX);
+
+ addr->DMATDLR = 0;
+ addr->DMACR = DW_SPI_TDMAE;
+ addr->SER = spi_priv->enable_slave;
+ addr->SPIENR = DW_SPI_ENABLE;
+ csi_dma_start(spi_priv->dma_handle, ch);
+
+ while (csi_dma_get_status(spi_priv->dma_handle, ch) != DMA_STATE_DONE);
+
+ while (addr->SR & DW_SPI_BUSY);
+
+ csi_dma_stop(spi_priv->dma_handle, ch);
+ csi_dma_release_channel(spi_priv->dma_handle, ch);
+ addr->SPIENR = DW_SPI_DISABLE;
+ addr->SER = 0;
+
+ dw_spi_ss_control(spi_priv, SPI_SS_INACTIVE);
+ spi_priv->status.busy = 0U;
+ return 0;
+
+}
+
+/**
+ \brief receiving data from SPI receiver with DMA.
+*/
+static int32_t dw_spi_dma_receive(dw_spi_priv_t *spi_priv, void *data, uint32_t num)
+{
+ int32_t ch;
+ ch = csi_dma_alloc_channel(spi_priv->dma_handle, -1);
+ spi_priv->dma_tx_id = ch;
+
+ dma_config_t config;
+
+ config.src_inc = DMA_ADDR_CONSTANT;
+ config.dst_inc = DMA_ADDR_INC;
+ config.src_tw = DMA_DATAWIDTH_SIZE8;
+ config.dst_tw = DMA_DATAWIDTH_SIZE8;
+ config.hs_if = CKENUM_DMA_SPI1_RX;
+ config.type = DMA_PERH2MEM;
+
+ dw_spi_ss_control(spi_priv, SPI_SS_ACTIVE);
+ uint8_t *prx_buffer = (uint8_t *)data;
+
+ spi_priv->recv_buf = prx_buffer;
+ spi_priv->clk_num = num;
+ spi_priv->recv_num = num;
+
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+ int32_t ret;
+
+ while (spi_priv->clk_num) {
+ if (spi_priv->clk_num >= DW_SPI_FIFO_MAX_LV / 2) {
+ spi_priv->recv_num = DW_SPI_FIFO_MAX_LV / 2;
+ }
+
+ ret = csi_dma_config(spi_priv->dma_handle, ch, (uint8_t *) & (addr->DR), spi_priv->recv_buf, spi_priv->recv_num, &config, dw_spi_dma_event_cb);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ addr->SPIENR = DW_SPI_DISABLE; /* enable SPI */
+ dw_spi_set_mode(spi_priv, DWENUM_SPI_RX);
+ addr->DMARDLR = spi_priv->recv_num - 1;
+ addr->CTRLR1 = spi_priv->recv_num - 1;
+
+ addr->DMACR = DW_SPI_RDMAE;
+ addr->SER = spi_priv->enable_slave;
+ csi_dma_start(spi_priv->dma_handle, ch);
+ addr->SPIENR = DW_SPI_ENABLE;
+ addr->DR = DW_SPI_START_RX;
+
+ while (csi_dma_get_status(spi_priv->dma_handle, ch) != DMA_STATE_DONE);
+
+ csi_dma_stop(spi_priv->dma_handle, ch);
+ spi_priv->clk_num -= spi_priv->recv_num;
+ spi_priv->recv_buf += spi_priv->recv_num;
+
+
+ }
+
+ addr->SPIENR = DW_SPI_DISABLE;
+ addr->SER = 0;
+ csi_dma_release_channel(spi_priv->dma_handle, ch);
+ dw_spi_ss_control(spi_priv, SPI_SS_INACTIVE);
+ spi_priv->status.busy = 0U;
+ return 0;
+
+}
+
+/**
+ \brief sending/receiving data to/from SPI transmitter/receiver with DMA.
+*/
+static int32_t dw_spi_dma_transfer(dw_spi_priv_t *spi_priv, const void *data_out, void *data_in, uint32_t num_out, uint32_t num_in)
+{
+ int32_t tx_ch = csi_dma_alloc_channel(spi_priv->dma_handle, -1);
+
+ if (tx_ch < 0) {
+ return tx_ch;
+ }
+
+ spi_priv->dma_tx_id = tx_ch;
+
+ int32_t rx_ch = csi_dma_alloc_channel(spi_priv->dma_handle, -1);
+
+ if (rx_ch < 0) {
+ return rx_ch;
+ }
+
+ spi_priv->dma_rx_id = rx_ch;
+
+ dma_config_t tx_config, rx_config;
+
+ tx_config.src_inc = DMA_ADDR_INC;
+ tx_config.dst_inc = DMA_ADDR_CONSTANT;
+ tx_config.src_tw = DMA_DATAWIDTH_SIZE8;
+ tx_config.dst_tw = DMA_DATAWIDTH_SIZE8;
+ tx_config.hs_if = CKENUM_DMA_SPI1_TX;
+ tx_config.type = DMA_MEM2PERH;
+
+ rx_config.src_inc = DMA_ADDR_CONSTANT;
+ rx_config.dst_inc = DMA_ADDR_INC;
+ rx_config.src_tw = DMA_DATAWIDTH_SIZE8;
+ rx_config.dst_tw = DMA_DATAWIDTH_SIZE8;
+ rx_config.hs_if = CKENUM_DMA_SPI1_RX;
+ rx_config.type = DMA_PERH2MEM;
+
+ dw_spi_ss_control(spi_priv, SPI_SS_ACTIVE);
+
+ uint8_t *ptx_buffer = (uint8_t *)data_out;
+ uint8_t *prx_buffer = (uint8_t *)data_in;
+ spi_priv->send_buf = ptx_buffer;
+ spi_priv->recv_buf = prx_buffer;
+ spi_priv->send_num = num_out;
+ spi_priv->recv_num = num_in;
+ spi_priv->clk_num = num_in;
+
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+ int32_t ret;
+ uint8_t dma_send_buf[DW_SPI_FIFO_MAX_LV];
+
+ while (spi_priv->clk_num) {
+ if (spi_priv->clk_num >= DW_SPI_FIFO_MAX_LV) {
+ spi_priv->transfer_num = DW_SPI_FIFO_MAX_LV;
+ } else {
+ spi_priv->transfer_num = spi_priv->clk_num;
+ }
+
+ if (spi_priv->send_num >= spi_priv->transfer_num) {
+ memcpy(dma_send_buf, spi_priv->send_buf, spi_priv->transfer_num);
+ spi_priv->send_num -= spi_priv->transfer_num;
+ spi_priv->send_buf += spi_priv->transfer_num;
+ } else {
+ if (spi_priv->send_num > 0) {
+ memcpy(dma_send_buf, spi_priv->send_buf, spi_priv->send_num);
+ spi_priv->send_buf = NULL;
+ }
+
+ memset(&dma_send_buf[spi_priv->send_num], 0, spi_priv->transfer_num - spi_priv->send_num);
+ spi_priv->send_num = 0;
+ }
+
+ ret = csi_dma_config(spi_priv->dma_handle, tx_ch, dma_send_buf, (uint8_t *) & (addr->DR), spi_priv->transfer_num, &tx_config, dw_spi_dma_event_cb);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = csi_dma_config(spi_priv->dma_handle, rx_ch, (uint8_t *) & (addr->DR), spi_priv->recv_buf, spi_priv->transfer_num, &rx_config, dw_spi_dma_event_cb);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ addr->SPIENR = DW_SPI_DISABLE; /* disable SPI */
+ addr->DMARDLR = (spi_priv->transfer_num - 1) % 16; /* set dma receive data level */
+ addr->DMATDLR = (spi_priv->transfer_num - 1) % 16 + 1; /* set dma transmit data level */
+ addr->DMACR = DW_SPI_RDMAE | DW_SPI_TDMAE;
+ dw_spi_set_mode(spi_priv, DWENUM_SPI_TXRX);
+ addr->SER = spi_priv->enable_slave;
+ addr->SPIENR = DW_SPI_ENABLE; /* enable SPI */
+
+ ret = csi_dma_start(spi_priv->dma_handle, tx_ch);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ while (csi_dma_get_status(spi_priv->dma_handle, tx_ch) != DMA_STATE_DONE);
+
+ ret = csi_dma_start(spi_priv->dma_handle, rx_ch);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ while (csi_dma_get_status(spi_priv->dma_handle, rx_ch) != DMA_STATE_DONE);
+
+ spi_priv->recv_buf += spi_priv->transfer_num;
+ spi_priv->recv_num -= spi_priv->transfer_num;
+ spi_priv->clk_num -= spi_priv->transfer_num;
+ addr->SPIENR = DW_SPI_DISABLE;
+ csi_dma_stop(spi_priv->dma_handle, tx_ch);
+ csi_dma_stop(spi_priv->dma_handle, rx_ch);
+ }
+
+ dw_spi_ss_control(spi_priv, SPI_SS_INACTIVE);
+ addr->SER = 0;
+
+ csi_dma_release_channel(spi_priv->dma_handle, tx_ch);
+ csi_dma_release_channel(spi_priv->dma_handle, rx_ch);
+ spi_priv->status.busy = 0U;
+
+ return 0;
+
+}
+#endif
+
+
+/**
+ \brief Set the SPI datawidth.
+ \param[in] addr pointer to register address
+ \param[in] datawidth date frame size
+ \return error code
+*/
+static int32_t dw_spi_set_datawidth(dw_spi_reg_t *addr, DWENUM_SPI_DATAWIDTH datawidth)
+{
+ if ((datawidth >= DWENUM_SPI_DATASIZE_4) && (datawidth <= DWENUM_SPI_DATASIZE_16)) {
+ uint16_t temp = addr->CTRLR0;
+ temp &= 0xfff0; /* temp has the value of CTRLR0 with DFS being cleared.*/
+ temp |= (datawidth); /* get the final CTRLR0 after datawidth config. */
+ addr->CTRLR0 = temp; /* write CTRLR0 */
+ return 0;
+ }
+
+ return -1;
+}
+
+/**
+ \brief Set the SPI clock divider.
+ \param[in] addr pointer to register address
+ \param[in] baud spi baud rate
+ \param[in] apbfreq sysclk for spi module.
+ \return error code
+*/
+static int32_t dw_spi_set_baudrate(dw_spi_reg_t *addr, int32_t baud, int32_t apbfreq)
+{
+ int32_t sckdv = apbfreq / baud;
+
+ if (sckdv < 0x10000) {
+ addr->BAUDR = sckdv;
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ \brief Set the SPI polarity.
+ \param[in] addr pointer to register address
+ \param[in] polarity spi polarity
+ \return error code
+*/
+static int32_t dw_spi_set_polarity(dw_spi_reg_t *addr, DWENUM_SPI_POLARITY polarity)
+{
+ /* To config the polarity, we can set the SCPOL bit(CTRLR0[7]) as below:
+ * 0 - inactive state of serial clock is low
+ * 1 - inactive state of serial clock is high
+ */
+ switch (polarity) {
+ case DWENUM_SPI_CLOCK_POLARITY_LOW:
+ addr->CTRLR0 &= (~DW_SPI_POLARITY);
+ break;
+
+ case DWENUM_SPI_CLOCK_POLARITY_HIGH:
+ addr->CTRLR0 |= DW_SPI_POLARITY;
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ \brief Set the SPI Phase.
+ \param[in] addr pointer to register address
+ \param[in] phase Serial clock phase
+ \return error code
+*/
+static int32_t dw_spi_set_phase(dw_spi_reg_t *addr, DWENUM_SPI_PHASE phase)
+{
+ switch (phase) {
+ case DWENUM_SPI_CLOCK_PHASE_MIDDLE:
+ addr->CTRLR0 &= (~DW_SPI_PHASE);
+ break;
+
+ case DWENUM_SPI_CLOCK_PHASE_START:
+ addr->CTRLR0 |= DW_SPI_PHASE;
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ \brief Set the SPI mode.
+ \param[in] addr pointer to register address
+ \param[in] mode SPI_Mode
+ \return error code
+*/
+static int32_t dw_spi_set_mode(spi_handle_t handle, DWENUM_SPI_MODE mode)
+{
+ dw_spi_priv_t *spi_priv = handle;
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+
+ /* It is impossible to write to this register when the SSI is enabled.*/
+ /* we can set the TMOD to config transfer mode as below:
+ * TMOD_BIT9 TMOD_BIT8 transfer mode
+ * 0 0 transmit & receive
+ * 0 1 transmit only
+ * 1 0 receive only
+ * 1 1 reserved
+ */
+ switch (mode) {
+ case DWENUM_SPI_TXRX:
+ addr->CTRLR0 &= (~DW_SPI_TMOD_BIT8);
+ addr->CTRLR0 &= (~DW_SPI_TMOD_BIT9);
+ break;
+
+ case DWENUM_SPI_TX:
+ addr->CTRLR0 |= DW_SPI_TMOD_BIT8;
+ addr->CTRLR0 &= (~DW_SPI_TMOD_BIT9);
+ break;
+
+ case DWENUM_SPI_RX:
+ addr->CTRLR0 &= (~DW_SPI_TMOD_BIT8);
+ addr->CTRLR0 |= DW_SPI_TMOD_BIT9;
+ break;
+
+ default:
+ addr->CTRLR0 |= DW_SPI_TMOD_BIT8;
+ addr->CTRLR0 |= DW_SPI_TMOD_BIT9;
+ break;
+ }
+
+ spi_priv->mode = mode;
+ return 0;
+}
+
+/**
+ \brief interrupt service function for receive FIFO full interrupt .
+ \param[in] spi_priv pointer to spi private.
+*/
+static void dw_spi_intr_rx_full(dw_spi_priv_t *spi_priv)
+{
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+
+ uint8_t temp = addr->ICR;
+ uint8_t *pbuffer = spi_priv->recv_buf;
+ uint32_t length = spi_priv->recv_num;
+
+
+ uint8_t rxnum;
+ rxnum = addr->RXFLR;
+ uint32_t i = 0u;
+
+ for (i = 0; i < rxnum; i++) {
+ *pbuffer = addr->DR;
+ pbuffer++;
+ }
+
+ length -= rxnum;
+
+ if (length < DW_SPI_FIFO_MAX_LV) {
+ addr->RXFTLR = length - 1;
+ }
+
+ if (length <= 0) {
+ temp = addr->IMR;
+ temp &= 0x2f;
+ addr->IMR = temp;
+
+ addr->SER = 0;
+ addr->SPIENR = DW_SPI_DISABLE;
+ spi_priv->status.busy = 0U;
+
+ dw_spi_ss_control(spi_priv, SPI_SS_INACTIVE);
+
+ if (spi_priv->cb_event) {
+ spi_priv->cb_event(SPI_EVENT_RX_COMPLETE, spi_priv->cb_arg);
+ return;
+ }
+ } else {
+ addr->SPIENR = DW_SPI_DISABLE; /* disable SPI */
+ dw_spi_set_mode(spi_priv, DWENUM_SPI_RX);
+ addr->SER = spi_priv->enable_slave; /* enable all cs */
+ spi_priv->recv_buf = pbuffer;
+ spi_priv->recv_num = length;
+
+ if (spi_priv->recv_num > DW_SPI_FIFO_MAX_LV) {
+ addr->RXFTLR = DW_SPI_FIFO_MAX_LV - 1;
+ addr->CTRLR1 = DW_SPI_FIFO_MAX_LV - 1;
+ } else {
+ addr->RXFTLR = spi_priv->recv_num - 1;
+ addr->CTRLR1 = spi_priv->recv_num - 1;
+ }
+
+ addr->SPIENR = DW_SPI_ENABLE; /* enable SPI */
+ addr->DR = DW_SPI_START_RX ;
+ }
+
+}
+
+/**
+ \brief interrupt service function for transmit FIFO empty interrupt.
+ \param[in] spi_priv pointer to spi private.
+*/
+static void dw_spi_intr_tx_empty(dw_spi_priv_t *spi_priv)
+{
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+ uint8_t temp = addr->ICR;
+
+ /* transfer mode:transmit & receive */
+ uint32_t i = 0u;
+
+ if (spi_priv->
+ mode == DWENUM_SPI_TXRX) {
+ /* read data out from rx FIFO */
+ while (spi_priv->transfer_num) {
+ *spi_priv->recv_buf = addr->DR;
+ spi_priv->recv_buf++;
+ spi_priv->transfer_num--;
+ }
+
+ if (spi_priv->clk_num >= DW_SPI_FIFO_MAX_LV) {
+ spi_priv->transfer_num = DW_SPI_FIFO_MAX_LV;
+ } else {
+ spi_priv->transfer_num = spi_priv->clk_num;
+ }
+
+ for (i = 0; i < spi_priv->transfer_num; i++) {
+ if (spi_priv->send_num == 0) {
+ addr->DR = 0x0;
+ } else {
+ addr->DR = *spi_priv->send_buf;
+ spi_priv->send_buf++;
+ }
+
+ spi_priv->send_num--;
+ }
+ } else { //transfer mode :transmit only
+ if (spi_priv->clk_num >= DW_SPI_FIFO_MAX_LV) {
+ spi_priv->transfer_num = DW_SPI_FIFO_MAX_LV;
+ } else {
+ spi_priv->transfer_num = spi_priv->clk_num;
+ }
+
+ for (i = 0; i < spi_priv->transfer_num; i++) {
+ addr->DR = *spi_priv->send_buf;
+ spi_priv->send_buf++;
+ spi_priv->send_num--;
+ }
+
+ }
+
+ if (spi_priv->clk_num == 0) {
+
+ temp = addr->IMR;
+ temp &= ~DW_SPI_IMR_TXEIM;
+ addr->IMR = temp;
+
+ addr->SER = 0;
+ addr->SPIENR = DW_SPI_DISABLE;
+ spi_priv->status.busy = 0U;
+
+ dw_spi_ss_control(spi_priv, SPI_SS_INACTIVE);
+
+ if (spi_priv->mode == DWENUM_SPI_TXRX) {
+ if (spi_priv->cb_event) {
+ spi_priv->cb_event(SPI_EVENT_TRANSFER_COMPLETE, spi_priv->cb_arg);
+ return;
+ }
+ } else {
+ if (spi_priv->cb_event) {
+ spi_priv->cb_event(SPI_EVENT_TX_COMPLETE, spi_priv->cb_arg);
+ return;
+ }
+ }
+ }
+
+ spi_priv->clk_num -= spi_priv->transfer_num;
+
+}
+/**
+ \brief handler the interrupt.
+ \param[in] spi Pointer to \ref SPI_RESOURCES
+*/
+void dw_spi_irqhandler(int32_t idx)
+{
+ dw_spi_priv_t *spi_priv = &spi_instance[idx];
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+
+ uint32_t intr = addr->ISR;
+
+ /* deal with receive FIFO full interrupt */
+ if (intr & DW_SPI_RXFIFO_FULL) {
+ dw_spi_intr_rx_full(spi_priv);
+ }
+ /* deal with transmit FIFO empty interrupt */
+ else if (intr & DW_SPI_TXFIFO_EMPTY) {
+ dw_spi_intr_tx_empty(spi_priv);
+ }
+}
+
+int32_t __attribute__((weak)) target_spi_init(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel, uint32_t *base, uint32_t *irq)
+{
+ return -1;
+}
+
+/**
+ \brief Initialize SPI Interface. 1. Initializes the resources needed for the SPI interface 2.registers event callback function
+ \param[in] spi pin of mosi
+ \param[in] spi pin of miso
+ \param[in] spi pin of sclk
+ \param[in] spi pin of ssel
+ \param[in] cb_event event call back function \ref spi_event_cb_t
+ \return return spi handle if success
+*/
+spi_handle_t csi_spi_initialize(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel, spi_event_cb_t cb_event, void *cb_arg)
+{
+ uint32_t base = 0u;
+ uint32_t irq = 0u;
+
+ int32_t idx = target_spi_init(mosi, miso, sclk, ssel, &base, &irq);
+
+ if (idx < 0 || idx >= CONFIG_SPI_NUM) {
+ return NULL;
+ }
+
+ dw_spi_priv_t *spi_priv = &spi_instance[idx];
+
+ spi_priv->base = base;
+ spi_priv->irq = irq;
+ spi_priv->ssel = ssel;
+
+ spi_priv->cb_event = cb_event;
+ spi_priv->cb_arg = cb_arg;
+ spi_priv->status.busy = 0U;
+ spi_priv->status.data_lost = 0U;
+ spi_priv->status.mode_fault = 0U;
+ spi_priv->enable_slave = 1U;
+ spi_priv->state = SPI_INITIALIZED;
+
+ drv_nvic_enable_irq(spi_priv->irq);
+#ifdef CONFIG_SPI_DMA
+ spi_priv->dma_handle = csi_dma_initialize(0);
+#endif
+
+ return (spi_handle_t)spi_priv;
+}
+
+/**
+ \brief De-initialize SPI Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle spi handle to operate.
+ \return error code
+*/
+int32_t csi_spi_uninitialize(spi_handle_t handle)
+{
+ SPI_NULL_PARAM_CHK(handle);
+
+ dw_spi_priv_t *spi_priv = handle;
+ drv_nvic_disable_irq(spi_priv->irq);
+
+ spi_priv->cb_event = NULL;
+ spi_priv->state = 0U;
+ spi_priv->status.busy = 0U;
+ spi_priv->status.data_lost = 0U;
+ spi_priv->status.mode_fault = 0U;
+
+#ifdef CONFIG_SPI_DMA
+ csi_dma_uninitialize(spi_priv->dma_handle);
+#endif
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] spi instance to operate.
+ \return \ref spi_capabilities_t
+*/
+spi_capabilities_t csi_spi_get_capabilities(spi_handle_t handle)
+{
+ return spi_capabilities;
+}
+
+/**
+ \brief config spi mode.
+ \param[in] handle spi handle to operate.
+ \param[in] sysclk sysclk for spi module.
+ \param[in] baud spi baud rate. if negative, then this attribute not changed
+ \param[in] mode \ref spi_mode_e . if negative, then this attribute not changed
+ \param[in] format \ref spi_format_e . if negative, then this attribute not changed
+ \param[in] order \ref spi_bit_order_e . if negative, then this attribute not changed
+ \param[in] ss_mode \ref spi_ss_mode_e . if negative, then this attribute not changed
+ \param[in] bit_width spi data bitwidth: (1 ~ SPI_DATAWIDTH_MAX) . if negative, then this attribute not changed
+ \return error code
+*/
+int32_t csi_spi_config(spi_handle_t handle,
+ int32_t sysclk,
+ int32_t baud,
+ spi_mode_e mode,
+ spi_format_e format,
+ spi_bit_order_e order,
+ spi_ss_mode_e ss_mode,
+ int32_t bit_width)
+{
+ SPI_NULL_PARAM_CHK(handle);
+
+ dw_spi_priv_t *spi_priv = handle;
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+
+ if ((spi_priv->state & SPI_INITIALIZED) == 0U) {
+ return ERR_SPI(EDRV_UNSUPPORTED);
+ }
+
+ if (spi_priv->status.busy) {
+ return ERR_SPI(EDRV_BUSY);
+ }
+
+ spi_priv->status.busy = 0U;
+ spi_priv->status.data_lost = 0U;
+ spi_priv->status.mode_fault = 0U;
+
+ addr->SPIENR = DW_SPI_DISABLE;
+ addr->IMR = DW_SPI_INT_DISABLE;
+
+ int32_t ret = 0;
+
+ if (baud >= 0) {
+ ret = dw_spi_set_baudrate(addr, baud, sysclk);
+
+ if (ret < 0) {
+ return ERR_SPI(EDRV_PARAMETER);
+ }
+ }
+
+ if (mode >= 0) {
+ switch (mode) {
+ case SPI_MODE_MASTER:
+ break;
+
+ default:
+ return ERR_SPI(EDRV_UNSUPPORTED);
+ }
+ }
+
+ if (format >= 0) {
+ switch (format) {
+ case SPI_FORMAT_CPOL0_CPHA0:
+ dw_spi_set_polarity(addr, DWENUM_SPI_CLOCK_POLARITY_LOW);
+ dw_spi_set_phase(addr, DWENUM_SPI_CLOCK_PHASE_MIDDLE);
+ break;
+
+ case SPI_FORMAT_CPOL0_CPHA1:
+ dw_spi_set_polarity(addr, DWENUM_SPI_CLOCK_POLARITY_LOW);
+ dw_spi_set_phase(addr, DWENUM_SPI_CLOCK_PHASE_START);
+ break;
+
+ case SPI_FORMAT_CPOL1_CPHA0:
+ dw_spi_set_polarity(addr, DWENUM_SPI_CLOCK_POLARITY_HIGH);
+ dw_spi_set_phase(addr, DWENUM_SPI_CLOCK_PHASE_MIDDLE);
+ break;
+
+ case SPI_FORMAT_CPOL1_CPHA1:
+ dw_spi_set_polarity(addr, DWENUM_SPI_CLOCK_POLARITY_HIGH);
+ dw_spi_set_phase(addr, DWENUM_SPI_CLOCK_PHASE_START);
+ break;
+
+ default:
+ return ERR_SPI(EDRV_PARAMETER);
+ }
+ }
+
+ if (order >= 0) {
+ //TD:
+ }
+
+ if (ss_mode >= 0) {
+ switch (ss_mode) {
+ case SPI_SS_MASTER_SW:
+ spi_priv->ss_mode = SPI_SS_MASTER_SW;
+ break;
+
+ case SPI_SS_MASTER_HW_OUTPUT:
+ dw_spi_ss_init(spi_priv);
+ break;
+
+ default:
+ return ERR_SPI(EDRV_UNSUPPORTED);
+ }
+ }
+
+ if (bit_width >= 0) {
+ ret = dw_spi_set_datawidth(addr, bit_width);
+
+ if (ret < 0) {
+ return ERR_SPI(EDRV_PARAMETER);
+ }
+ }
+
+ spi_priv->state |= SPI_CONFIGURED;
+
+ return 0;
+}
+
+/**
+ \brief config spi default tx value.
+ \param[in] handle spi handle to operate.
+ \param[in] value default tx value
+ \return error code
+*/
+int32_t csi_spi_set_default_tx_value(spi_handle_t handle, uint32_t value)
+{
+ SPI_NULL_PARAM_CHK(handle);
+
+ return ERR_SPI(EDRV_UNSUPPORTED);
+}
+
+/**
+ \brief sending data to SPI transmitter,(received data is ignored).
+ if non-blocking mode, this function only start the sending,
+ \ref spi_event_e is signaled when operation completes or error happens.
+ \ref csi_spi_get_status can indicates operation status.
+ if blocking mode, this function return after operation completes or error happens.
+ \param[in] handle spi handle to operate.
+ \param[in] data Pointer to buffer with data to send to SPI transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits,
+ \param[in] num Number of data items to send.
+ \param[in] block_mode blocking and non_blocking to selcect
+ \return error code
+*/
+int32_t csi_spi_send(spi_handle_t handle, const void *data, uint32_t num, uint8_t block_mode)
+
+{
+ if (handle == NULL || data == NULL || num == 0) {
+ return ERR_SPI(EDRV_PARAMETER);
+ }
+
+ dw_spi_priv_t *spi_priv = handle;
+
+ if ((spi_priv->state & SPI_CONFIGURED) == 0U) {
+ return ERR_SPI(EDRV_UNSUPPORTED);
+ }
+
+ if (spi_priv->status.busy) {
+ return ERR_SPI(EDRV_BUSY);
+ }
+
+ spi_priv->status.busy = 1U;
+ spi_priv->status.data_lost = 0U;
+ spi_priv->status.mode_fault = 0U;
+
+
+#ifdef CONFIG_SPI_DMA
+ return dw_spi_dma_send(spi_priv, data, num);
+#endif
+
+ dw_spi_ss_control(spi_priv, SPI_SS_ACTIVE);
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+ addr->SPIENR = DW_SPI_DISABLE; /* disable SPI */
+ dw_spi_set_mode(spi_priv, DWENUM_SPI_TX);
+ addr->SPIENR = DW_SPI_ENABLE; /* enable SPI */
+ uint8_t *ptxbuffer = (uint8_t *)data;
+
+ if (block_mode) {
+ addr->SER = spi_priv->enable_slave;
+ addr->TXFTLR = DW_SPI_TXFIFO_LV;
+
+ dw_spi_ss_control(spi_priv, SPI_SS_ACTIVE);
+ spi_priv->send_num = num;
+
+ uint32_t once_len , i;
+
+ while (spi_priv->send_num) {
+ once_len = (spi_priv->send_num >= DW_SPI_FIFO_MAX_LV) ?
+ DW_SPI_FIFO_MAX_LV : spi_priv->send_num;
+
+ for (i = 0; i < once_len; i++) {
+ addr->DR = *ptxbuffer++;
+ }
+
+ while (!(addr->SR & DW_SPI_TFE));
+
+ while (addr->SR & DW_SPI_BUSY);
+
+ spi_priv->send_num -= once_len;
+ }
+
+ dw_spi_ss_control(spi_priv, SPI_SS_INACTIVE);
+ spi_priv->status.busy = 0U;
+ } else {
+
+ spi_priv->send_num = num;
+ spi_priv->clk_num = num;
+ spi_priv->send_buf = ptxbuffer;
+ spi_priv->transfer_num = 0;
+ addr->SPIENR = DW_SPI_ENABLE; /* enable SPI */
+ addr->TXFTLR = DW_SPI_TXFIFO_LV;
+ addr->SER = spi_priv->enable_slave;
+ addr->IMR = DW_SPI_IMR_TXEIM;
+ }
+
+ return 0;
+}
+
+/**
+\brief receiving data from SPI receiver.transmits the default value as specified by csi_spi_set_default_tx_value
+ if non-blocking mode, this function only start the receiving,
+ \ref spi_event_e is signaled when operation completes or error happens.
+ \ref csi_spi_get_status can indicates operation status.
+ if blocking mode, this function return after operation completes or error happens.
+\param[in] handle spi handle to operate.
+\param[out] data Pointer to buffer for data to receive from SPI receiver
+\param[in] num Number of data items to receive
+\param[in] block_mode blocking and non_blocking to selcect
+\return error code
+*/
+int32_t csi_spi_receive(spi_handle_t handle, void *data, uint32_t num, uint8_t block_mode)
+{
+
+ if (handle == NULL || data == NULL || num == 0) {
+ return ERR_SPI(EDRV_PARAMETER);
+ }
+
+ dw_spi_priv_t *spi_priv = handle;
+
+ if ((spi_priv->state & SPI_CONFIGURED) == 0U) {
+ return ERR_SPI(EDRV_UNSUPPORTED);
+ }
+
+ if (spi_priv->status.busy) {
+ return ERR_SPI(EDRV_BUSY);
+ }
+
+ spi_priv->status.busy = 1U;
+ spi_priv->status.data_lost = 0U;
+ spi_priv->status.mode_fault = 0U;
+
+#ifdef CONFIG_SPI_DMA
+ return dw_spi_dma_receive(spi_priv, data, num);
+#endif
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+ uint8_t *prx_buffer = data;
+
+ if (block_mode) {
+ dw_spi_ss_control(spi_priv, SPI_SS_ACTIVE);
+
+ spi_priv->recv_buf = prx_buffer;
+ spi_priv->recv_num = num;
+
+
+ while (spi_priv->recv_num) {
+ addr->SPIENR = DW_SPI_DISABLE; /* disable SPI */
+ dw_spi_set_mode(spi_priv, DWENUM_SPI_RX);
+ addr->SER = spi_priv->enable_slave; /* enable all cs */
+
+ uint32_t once_len = (spi_priv->recv_num >= DW_SPI_FIFO_MAX_LV) ?
+ DW_SPI_FIFO_MAX_LV : spi_priv->recv_num;
+ addr->CTRLR1 = once_len - 1;
+ addr->RXFTLR = once_len - 1;
+ addr->SPIENR = DW_SPI_ENABLE;
+ addr->DR = 0;
+
+ while (addr->RXFLR < once_len);
+
+ int i = 0;
+
+ for (i = 0; i < once_len; i++) {
+ *spi_priv->recv_buf++ = addr->DR;
+ }
+
+ spi_priv->recv_num -= once_len;
+ }
+
+ dw_spi_ss_control(spi_priv, SPI_SS_INACTIVE);
+ spi_priv->status.busy = 0U;
+ } else {
+ dw_spi_ss_control(spi_priv, SPI_SS_ACTIVE);
+
+ addr->SPIENR = DW_SPI_DISABLE; /* disable SPI */
+ spi_priv->recv_buf = prx_buffer;
+ spi_priv->recv_num = num;
+ dw_spi_set_mode(spi_priv, DWENUM_SPI_RX);
+ addr->SER = spi_priv->enable_slave; /* enable all cs */
+
+ if (num > DW_SPI_FIFO_MAX_LV) {
+ addr->RXFTLR = DW_SPI_FIFO_MAX_LV - 1;
+ addr->CTRLR1 = DW_SPI_FIFO_MAX_LV - 1;
+ } else {
+ addr->RXFTLR = num - 1;
+ addr->CTRLR1 = num - 1;
+ }
+
+ addr->IMR = DW_SPI_IMR_RXFIM;
+ addr->SPIENR = DW_SPI_ENABLE; /* enable SPI */
+ addr->DR = DW_SPI_START_RX ;
+
+ }
+
+ return 0;
+}
+
+/**
+ \brief sending/receiving data to/from SPI transmitter/receiver.
+ if non-blocking mode, this function only start the transfer,
+ \ref spi_event_e is signaled when operation completes or error happens.
+ \ref csi_spi_get_status can indicates operation status.
+ if blocking mode, this function return after operation completes or error happens.
+ \param[in] handle spi handle to operate.
+ \param[in] data_out Pointer to buffer with data to send to SPI transmitter
+ \param[out] data_in Pointer to buffer for data to receive from SPI receiver
+ \param[in] num_out Number of data items to send
+ \param[in] num_in Number of data items to receive
+ \param[in] block_mode blocking and non_blocking to selcect
+ \return error code
+*/
+int32_t csi_spi_transfer(spi_handle_t handle, const void *data_out, void *data_in, uint32_t num_out, uint32_t num_in, uint8_t block_mode)
+{
+ if (handle == NULL || data_in == NULL || num_out == 0 || num_in == 0 || data_out == NULL) {
+ return ERR_SPI(EDRV_PARAMETER);
+ }
+
+ dw_spi_priv_t *spi_priv = handle;
+
+ if ((spi_priv->state & SPI_CONFIGURED) == 0U) {
+ return ERR_SPI(EDRV_UNSUPPORTED);
+ }
+
+ if (spi_priv->status.busy) {
+ return ERR_SPI(EDRV_BUSY);
+ }
+
+ spi_priv->status.busy = 1U;
+ spi_priv->status.data_lost = 0U;
+ spi_priv->status.mode_fault = 0U;
+
+#ifdef CONFIG_SPI_DMA
+ return dw_spi_dma_transfer(spi_priv, data_out, data_in, num_out, num_in);
+#endif
+ dw_spi_ss_control(spi_priv, SPI_SS_ACTIVE);
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+
+ addr->SPIENR = DW_SPI_DISABLE; /* disable SPI */
+ dw_spi_set_mode(spi_priv, DWENUM_SPI_TXRX);
+ addr->SER = spi_priv->enable_slave; /* enable all cs */
+ uint8_t *ptx_buffer = (uint8_t *)data_out;
+ uint8_t *prx_buffer = (uint8_t *)data_in;
+ uint32_t i = 0u;
+
+ if (block_mode) {
+ for (i = 0; i < num_out; i++) { /* transmit datas in transmit-buffer */
+ addr->DR = *ptx_buffer;
+ ptx_buffer++;
+ }
+
+ while ((addr->SR & DW_SPI_BUSY));
+
+ while ((addr->SR & DW_SPI_TFE) == 0);
+
+ while ((addr->SR & DW_SPI_RFNE) == 0);
+
+ addr->SPIENR = DW_SPI_DISABLE; /* disable SPI */
+
+ dw_spi_set_mode(addr, DWENUM_SPI_RX);
+ addr->SPIENR = DW_SPI_ENABLE;
+ addr->DR = DW_SPI_START_RX;
+
+ for (i = 0; i < num_in; i++) {
+ *prx_buffer = addr->DR;
+ prx_buffer++;
+ }
+
+ addr->SER = 0;
+
+ dw_spi_ss_control(spi_priv, SPI_SS_INACTIVE);
+ addr->SPIENR = DW_SPI_DISABLE;
+ spi_priv->status.busy = 0U;
+ } else {
+ spi_priv->send_buf = ptx_buffer;
+ spi_priv->recv_buf = prx_buffer;
+ spi_priv->send_num = num_out;
+ spi_priv->recv_num = num_in;
+ spi_priv->clk_num = num_in;
+ spi_priv->transfer_num = 0;
+
+ addr->TXFTLR = DW_SPI_TXFIFO_LV;
+ addr->SPIENR = DW_SPI_ENABLE;
+ /* enable transmit FIFO empty interrupt */
+ addr->IMR |= DW_SPI_IMR_TXEIM;
+ }
+
+ return 0;
+
+}
+
+/**
+ \brief abort spi transfer.
+ \param[in] handle spi handle to operate.
+ \return error code
+*/
+int32_t csi_spi_abort_transfer(spi_handle_t handle)
+{
+ SPI_NULL_PARAM_CHK(handle);
+
+ dw_spi_priv_t *spi_priv = handle;
+ dw_spi_reg_t *addr = (dw_spi_reg_t *)(spi_priv->base);
+
+ addr->SPIENR = DW_SPI_DISABLE;
+ spi_priv->status.busy = 0U;
+ spi_priv->recv_buf = NULL;
+ spi_priv->recv_num = 0;
+
+ return 0;
+}
+
+/**
+ \brief Get SPI status.
+ \param[in] handle spi handle to operate.
+ \return SPI status \ref ARM_SPI_STATUS
+*/
+spi_status_t csi_spi_get_status(spi_handle_t handle)
+{
+ spi_status_t spi_status = {0};
+
+ if (handle == NULL) {
+ return spi_status;
+ }
+
+ dw_spi_priv_t *spi_priv = handle;
+
+ return spi_priv->status;
+}
+
diff --git a/bsp/ck802/libraries/common/spi/dw_spi.h b/bsp/ck802/libraries/common/spi/dw_spi.h
new file mode 100644
index 0000000000..88fd79d91a
--- /dev/null
+++ b/bsp/ck802/libraries/common/spi/dw_spi.h
@@ -0,0 +1,159 @@
+/*
+ * 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 dw_spi.h
+ * @brief header file for spi driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef __DW_SPI_H
+#define __DW_SPI_H
+
+#include <stdio.h>
+#include "soc.h"
+
+/*
+ * SPI register bit definitions
+ */
+#define DW_SPI_ENABLE 0x01
+#define DW_SPI_DISABLE 0x00
+#define DW_SPI_TMOD_BIT8 0x0100
+#define DW_SPI_TMOD_BIT9 0x0200
+#define DW_SPI_POLARITY 0x80
+#define DW_SPI_PHASE 0x40
+#define DW_SPI_BUSY 0x01
+#define DW_SPI_TFE 0x04
+#define DW_SPI_RFNE 0x08
+#define DW_SPI_INT_EN 0x19
+#define DW_SPI_RINT_EN 0x3e
+#define DW_SPI_TINT_EN 0x3f
+#define DW_SPI_INT_DISABLE 0x00
+#define DW_SPI_INT_MASK_RX 0x27
+#define DW_SPI_INT_MASKTX 0x3e
+#define DW_SPI_RDMAE 0x1
+#define DW_SPI_TDMAE 0x2
+#define DW_SPI_TXFIFO_LV 0x0
+#define DW_SPI_RXFIFO_LV 0x1d
+#define DW_SPI_RXFIFO_NOT_EMPTY 0x08
+#define DW_SPI_START_RX 0x0
+#define DW_SPI_FIFO_MAX_LV 0x20
+#define DW_SPI_FIFO_OVER_LV 0x18
+#define DW_SPI_RXFIFO_OVERFLOW 0x08
+#define DW_SPI_RXFIFO_FULL 0x10
+#define DW_SPI_TXFIFO_EMPTY 0x01
+#define SPI_CS_SELECTED 0x0
+#define DW_SPI_IMR_TXEIM 0x01 /* Transmit FIFO Empty Interrupt Mask */
+#define DW_SPI_IMR_RXFIM 0x10 /* Receive FIFO Full Interrupt Mask */
+
+
+/* some infoermationgs of SPI for special MCU */
+#define DW_SPI_DEFAULT_BAUDR 10000000 /* 10M */
+#define DW_SPI_MAXID 0x1
+
+#define SPI_INITIALIZED ((uint8_t)(1U)) // SPI initalized
+#define SPI_POWERED ((uint8_t)(1U<< 1)) // SPI powered on
+#define SPI_CONFIGURED ((uint8_t)(1U << 2)) // SPI configured
+#define SPI_DATA_LOST ((uint8_t)(1U << 3)) // SPI data lost occurred
+#define SPI_MODE_FAULT ((uint8_t)(1U << 4)) // SPI mode fault occurred
+
+
+typedef enum {
+ DWENUM_SPI_DMACR_RXE = 0,
+ DWENUM_SPI_DMACR_TXE = 1,
+} DWENUM_SPI_DMACR;
+
+
+typedef enum {
+ DWENUM_SPI_TXRX = 0,
+ DWENUM_SPI_TX = 1,
+ DWENUM_SPI_RX = 2,
+ DWENUM_SPI_EERX = 3
+} DWENUM_SPI_MODE;
+
+typedef enum {
+ DWENUM_SPI_CLOCK_POLARITY_LOW = 0,
+ DWENUM_SPI_CLOCK_POLARITY_HIGH = 1
+} DWENUM_SPI_POLARITY;
+
+typedef enum {
+ DWENUM_SPI_CLOCK_PHASE_MIDDLE = 0,
+ DWENUM_SPI_CLOCK_PHASE_START = 1
+} DWENUM_SPI_PHASE;
+
+typedef enum {
+ DWENUM_SPI_DATASIZE_4 = 3,
+ DWENUM_SPI_DATASIZE_5 = 4,
+ DWENUM_SPI_DATASIZE_6 = 5,
+ DWENUM_SPI_DATASIZE_7 = 6,
+ DWENUM_SPI_DATASIZE_8 = 7,
+ DWENUM_SPI_DATASIZE_9 = 8,
+ DWENUM_SPI_DATASIZE_10 = 9,
+ DWENUM_SPI_DATASIZE_11 = 10,
+ DWENUM_SPI_DATASIZE_12 = 11,
+ DWENUM_SPI_DATASIZE_13 = 12,
+ DWENUM_SPI_DATASIZE_14 = 13,
+ DWENUM_SPI_DATASIZE_15 = 14,
+ DWENUM_SPI_DATASIZE_16 = 15
+} DWENUM_SPI_DATAWIDTH;
+
+typedef enum {
+ DWENUM_SPI_CS0 = 1,
+ DWENUM_SPI_CS1 = 2
+} DWENUM_SPI_SLAVE;
+
+typedef struct {
+ __IOM uint16_t CTRLR0; /* Offset: 0x000 (R/W) Control register 0 */
+ uint16_t RESERVED0;
+ __IOM uint16_t CTRLR1; /* Offset: 0x004 (R/W) Control register 1 */
+ uint16_t RESERVED1;
+ __IOM uint8_t SPIENR; /* Offset: 0x008 (R/W) SSI enable regiseter */
+ uint8_t RESERVED2[7];
+ __IOM uint32_t SER; /* Offset: 0x010 (R/W) Slave enable register */
+ __IOM uint16_t BAUDR; /* Offset: 0x014 (R/W) Baud rate select */
+ uint16_t RESERVED3;
+ __IOM uint32_t TXFTLR; /* Offset: 0x018 (R/W) Transmit FIFO Threshold Level */
+ __IOM uint32_t RXFTLR; /* Offset: 0x01c (R/W) Receive FIFO Threshold Level */
+ __IOM uint32_t TXFLR; /* Offset: 0x020 (R/W) Transmit FIFO Level register */
+ __IOM uint32_t RXFLR; /* Offset: 0x024 (R/W) Receive FIFO Level Register */
+ __IOM uint8_t SR; /* Offset: 0x028 (R/W) status register */
+ uint8_t RESERVED4[3];
+ __IOM uint32_t IMR; /* Offset: 0x02C (R/W) Interrupt Mask Register */
+ __IM uint32_t ISR; /* Offset: 0x030 (R/W) interrupt status register */
+ __IM uint32_t RISR; /* Offset: 0x034 (R/W) Raw Interrupt Status Register */
+ __IM uint8_t TXOICR; /* Offset: 0x038 (R/W) Transmit FIFO Overflow Interrupt Clear Register */
+ uint8_t RESERVED5[3];
+ __IM uint8_t RXOICR; /* Offset: 0x03C (R/W) Receive FIFO Overflow Interrupt Clear Register*/
+ uint8_t RESERVED6[3];
+ __IM uint8_t RXUICR; /* Offset: 0x040 (R/W) Receive FIFO Underflow Interrupt Clear Register */
+ uint8_t RESERVED7[3];
+ __IM uint8_t MSTICR; /* Offset: 0x044 (R/W) Multi-Master Interrupt Clear Register */
+ uint8_t RESERVED8[3];
+ __IM uint8_t ICR; /* Offset: 0x048 (R/W) Interrupt Clear Register */
+ uint8_t RESERVED9[3];
+ __IOM uint8_t DMACR; /* Offset: 0x04C (R/W) DMA Control Register */
+ uint8_t RESERVED10[3];
+ __IOM uint8_t DMATDLR; /* Offset: 0x050 (R/W) DMA Transmoit Data Level */
+ uint8_t RESERVED11[3];
+ __IOM uint8_t DMARDLR; /* Offset: 0x054 (R/W) DMA Receive Data Level */
+ uint8_t RESERVED12[3];
+ __IM uint32_t IDR; /* Offset: 0x058 (R/W) identification register */
+ uint32_t RESERVED13;
+ __IOM uint16_t DR; /* Offset: 0x060 (R/W) Data Register */
+ uint16_t RESERVED14[17];
+ __IOM uint8_t WR; /* Offset: 0x0A0 (R/W) SPI is Master or Slave Select Register */
+} dw_spi_reg_t;
+
+#endif /* __DW_SPI_H */
diff --git a/bsp/ck802/libraries/common/timer/dw_timer.c b/bsp/ck802/libraries/common/timer/dw_timer.c
new file mode 100644
index 0000000000..b2b8fc4528
--- /dev/null
+++ b/bsp/ck802/libraries/common/timer/dw_timer.c
@@ -0,0 +1,330 @@
+/*
+ * 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 dw_timer.c
+ * @brief CSI Source File for timer Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include "csi_core.h"
+#include "drv_timer.h"
+#include "dw_timer.h"
+#include "soc.h"
+
+#define ERR_TIMER(errno) (CSI_DRV_ERRNO_TIMER_BASE | errno)
+
+#define TIMER_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_TIMER(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ timer_event_cb_t cb_event;
+ uint32_t timeout; ///< the set time (us)
+ uint32_t timeout_flag;
+ void *arg;
+} dw_timer_priv_t;
+
+static dw_timer_priv_t timer_instance[CONFIG_TIMER_NUM];
+
+static const timer_capabilities_t timer_capabilities = {
+ .interrupt_mode = 1 ///< supports Interrupt mode
+};
+
+/**
+ \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(TIMER_EVENT_TIMEOUT, timer_priv->arg);
+ }
+
+}
+
+int32_t __attribute__((weak)) target_get_timer_count(void)
+{
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_timer(uint32_t idx, uint32_t *base, uint32_t *irq)
+{
+ return NULL;
+}
+
+/**
+ \brief get timer instance count.
+ \return timer instance count
+*/
+int32_t csi_timer_get_instance_count(void)
+{
+ return target_get_timer_count();
+}
+
+/**
+ \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, void *arg)
+{
+ if (idx < 0 || idx >= CONFIG_TIMER_NUM) {
+ return NULL;
+ }
+
+ uint32_t base = 0u;
+ uint32_t irq = 0u;
+
+ int32_t real_idx = target_get_timer(idx, &base, &irq);
+
+ 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->arg = arg;
+
+ dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
+ timer_priv->timeout = DW_TIMER_INIT_DEFAULT_VALUE;
+
+ timer_deactive_control(addr);
+ timer_priv->cb_event = cb_event;
+
+ drv_nvic_enable_irq(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_nvic_disable_irq(timer_priv->irq);
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle timer handle to operate.
+ \return \ref timer_capabilities_t
+*/
+timer_capabilities_t csi_timer_get_capabilities(timer_handle_t handle)
+{
+ return timer_capabilities;
+}
+
+/**
+ \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(EDRV_PARAMETER);
+ }
+
+ 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, uint32_t apbfreq)
+{
+ TIMER_NULL_PARAM_CHK(handle);
+
+ dw_timer_priv_t *timer_priv = handle;
+
+ timer_priv->timeout_flag = 0;
+
+ uint32_t min_us = apbfreq / 1000000;
+
+ if ((timer_priv->timeout < min_us) || (timer_priv->timeout > 0xffffffff / min_us)) {
+ return ERR_TIMER(EDRV_PARAMETER);
+ }
+
+ uint32_t load = (uint32_t)(timer_priv->timeout * min_us);
+
+ dw_timer_reg_t *addr = (dw_timer_reg_t *)(timer_priv->base);
+
+ 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 */
+
+ 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(EDRV_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[in] 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);
+
+ 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;
+}
+
diff --git a/bsp/ck802/libraries/common/timer/dw_timer.h b/bsp/ck802/libraries/common/timer/dw_timer.h
new file mode 100644
index 0000000000..38d9d033ee
--- /dev/null
+++ b/bsp/ck802/libraries/common/timer/dw_timer.h
@@ -0,0 +1,49 @@
+/*
+ * 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 dw_timer.h
+ * @brief header file for timer driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef __DW_TIMER_H
+#define __DW_TIMER_H
+
+#include <stdio.h>
+#include "soc.h"
+
+/*
+ * 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_INIT_DEFAULT_VALUE 0x7ffffff
+
+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: 4; /* 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;
+
+#endif /* __DW_TIMER_H */
+
diff --git a/bsp/ck802/libraries/common/trng/ck_trng.c b/bsp/ck802/libraries/common/trng/ck_trng.c
new file mode 100644
index 0000000000..b74145cc33
--- /dev/null
+++ b/bsp/ck802/libraries/common/trng/ck_trng.c
@@ -0,0 +1,237 @@
+/*
+ * 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 ck_trng.c
+ * @brief CSI Source File for TRNG Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include "drv_trng.h"
+#include "ck_trng.h"
+
+
+#define ERR_TRNG(errno) (CSI_DRV_ERRNO_TRNG_BASE | errno)
+#define TRNG_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_TRNG(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+typedef struct {
+ uint32_t base;
+ trng_event_cb_t cb;
+ trng_status_t status;
+} ck_trng_priv_t;
+
+static ck_trng_priv_t trng_handle[CONFIG_TRNG_NUM];
+
+/* Driver Capabilities */
+static const trng_capabilities_t driver_capabilities = {
+ .lowper_mode = 1 /* low power mode */
+};
+
+//
+// Functions
+//
+
+ck_trng_reg_t *trng_reg = NULL;
+
+static int32_t trng_enable(void)
+{
+ trng_reg->TCR |= TRNG_EN;
+ return 0;
+}
+
+static int32_t trng_get_data(void)
+{
+ int data = trng_reg->TDR;
+ return data;
+}
+
+static int32_t trng_data_is_ready(void)
+{
+ int flag = (trng_reg->TCR & TRNG_DATA_READY);
+ return flag;
+}
+
+
+int32_t __attribute__((weak)) target_get_trng_count(void)
+{
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_trng(int32_t idx, uint32_t *base)
+{
+ return NULL;
+}
+/**
+ \brief get trng handle count.
+ \return trng handle count
+*/
+int32_t csi_trng_get_instance_count(void)
+{
+ return target_get_trng_count();
+}
+
+/**
+ \brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_trng_get_instance_count()
+ \param[in] cb_event Pointer to \ref trng_event_cb_t
+ \return pointer to trng handle
+*/
+trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event)
+{
+
+ if (idx < 0 || idx >= CONFIG_TRNG_NUM) {
+ return NULL;
+ }
+
+ /* obtain the trng information */
+ uint32_t base = 0u;
+ int32_t real_idx = target_get_trng(idx, &base);
+
+ if (real_idx != idx) {
+ return NULL;
+ }
+
+ ck_trng_priv_t *trng_priv = &trng_handle[idx];
+ trng_priv->base = base;
+
+ /* initialize the trng context */
+ trng_reg = (ck_trng_reg_t *)(trng_priv->base);
+ trng_priv->cb = cb_event;
+ trng_priv->status.busy = 0;
+ trng_priv->status.data_valid = 0;
+
+ return (trng_handle_t)trng_priv;
+}
+
+/**
+ \brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle trng handle to operate.
+ \return error code
+*/
+int32_t csi_trng_uninitialize(trng_handle_t handle)
+{
+ TRNG_NULL_PARAM_CHK(handle);
+
+ ck_trng_priv_t *trng_priv = handle;
+ trng_priv->cb = NULL;
+
+ return 0;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] trng handle to operate.
+ \return \ref trng_capabilities_t
+*/
+trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle)
+{
+ return driver_capabilities;
+}
+
+/**
+ \brief Get data from the TRNG.
+ \param[in] handle trng handle to operate.
+ \param[out] data Pointer to buffer with data get from TRNG
+ \param[in] num Number of data items to obtain
+ \return error code
+*/
+int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num)
+{
+ TRNG_NULL_PARAM_CHK(handle);
+ TRNG_NULL_PARAM_CHK(data);
+ TRNG_NULL_PARAM_CHK(num);
+
+ ck_trng_priv_t *trng_priv = handle;
+
+ trng_priv->status.busy = 1U;
+ trng_priv->status.data_valid = 0U;
+
+ uint8_t left_len = (uint32_t)data & 0x3;
+ uint32_t result = 0;
+
+ /* if the data addr is not aligned by word */
+ if (left_len) {
+ trng_enable();
+ while (!trng_data_is_ready());
+ result = trng_get_data();
+ /* wait the data is ready */
+ while (trng_data_is_ready());
+
+ if (num > (4 - left_len)) {
+ memcpy(data, &result, 4 - left_len);
+ } else {
+ memcpy(data, &result, num);
+ trng_priv->status.busy = 0U;
+ trng_priv->status.data_valid = 1U;
+
+ if (trng_priv->cb) {
+ trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
+ }
+ return 0;
+ }
+ num -= (4 - left_len);
+ }
+
+ uint32_t word_len = num >> 2;
+ left_len = num & 0x3;
+
+ /* obtain the data by word */
+ while (word_len--) {
+ trng_enable();
+ while (!trng_data_is_ready());
+ result = trng_get_data();
+ while (trng_data_is_ready());
+ *(uint32_t *)data = result;
+ data += 4;
+ }
+
+ /* if the num is not aligned by word */
+ if (left_len) {
+ trng_enable();
+ while (!trng_data_is_ready());
+ result = trng_get_data();
+ while (trng_data_is_ready());
+ memcpy(data, &result, left_len);
+ }
+
+ trng_priv->status.busy = 0U;
+ trng_priv->status.data_valid = 1U;
+
+ if (trng_priv->cb) {
+ trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
+ }
+
+ return 0;
+}
+
+/**
+ \brief Get TRNG status.
+ \param[in] handle trng handle to operate.
+ \return TRNG status \ref trng_status_t
+*/
+trng_status_t csi_trng_get_status(trng_handle_t handle)
+{
+ ck_trng_priv_t *trng_priv = handle;
+ return trng_priv->status;
+}
diff --git a/bsp/ck802/libraries/common/trng/ck_trng.h b/bsp/ck802/libraries/common/trng/ck_trng.h
new file mode 100644
index 0000000000..4255cf2629
--- /dev/null
+++ b/bsp/ck802/libraries/common/trng/ck_trng.h
@@ -0,0 +1,40 @@
+/*
+ * 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 ck_trng.h
+ * @brief header file for trng driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CK_TRNG_H_
+#define _CK_TRNG_H_
+
+#include "drv_trng.h"
+#include "soc.h"
+
+/*
+ * define the bits for TCR
+ */
+#define TRNG_EN (1UL << 1)
+#define TRNG_LOWPER_MODE (1UL << 2)
+#define TRNG_DATA_READY 1
+
+typedef struct {
+ __IOM uint32_t TCR; /* Offset: 0x000 (W/R) TRNG control register */
+ __IM uint32_t TDR; /* Offset: 0x004 (R) TRNG Data register */
+
+} ck_trng_reg_t;
+#endif
diff --git a/bsp/ck802/libraries/common/usart/dw_usart.c b/bsp/ck802/libraries/common/usart/dw_usart.c
new file mode 100644
index 0000000000..a7cf839d3d
--- /dev/null
+++ b/bsp/ck802/libraries/common/usart/dw_usart.c
@@ -0,0 +1,768 @@
+/*
+ * 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 dw_usart.c
+ * @brief CSI Source File for usart Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <stdbool.h>
+#include "csi_core.h"
+#include "drv_usart.h"
+#include "dw_usart.h"
+#include "soc.h"
+
+#define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno)
+
+/*
+ * setting config may be accessed when the USART is not
+ * busy(USR[0]=0) and the DLAB bit(LCR[7]) is set.
+ */
+
+#define WAIT_USART_IDLE(addr)\
+ do { \
+ int32_t timecount = 0; \
+ while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\
+ timecount++;\
+ }\
+ if (timecount >= UART_BUSY_TIMEOUT) {\
+ return ERR_USART(EDRV_TIMEOUT);\
+ } \
+ } while(0)
+
+#define USART_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_USART(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ usart_event_cb_t cb_event; ///< Event callback
+ void *cb_arg;
+ uint32_t rx_total_num;
+ uint32_t tx_total_num;
+ uint8_t *rx_buf;
+ uint8_t *tx_buf;
+ volatile uint32_t rx_cnt;
+ volatile uint32_t tx_cnt;
+ volatile uint32_t tx_busy;
+ volatile uint32_t rx_busy;
+} dw_usart_priv_t;
+
+static dw_usart_priv_t usart_instance[CONFIG_USART_NUM];
+
+static const usart_capabilities_t usart_capabilities = {
+ .asynchronous = 1, /* supports USART (Asynchronous) mode */
+ .synchronous_master = 0, /* supports Synchronous Master mode */
+ .synchronous_slave = 0, /* supports Synchronous Slave mode */
+ .single_wire = 0, /* supports USART Single-wire mode */
+ .event_tx_complete = 1, /* Transmit completed event */
+ .event_rx_timeout = 0, /* Signal receive character timeout event */
+};
+
+/**
+ \brief set the bautrate of usart.
+ \param[in] addr usart base to operate.
+ \param[in] baudrate.
+ \param[in] apbfreq the frequence of the apb.
+ \return error code
+*/
+static int32_t dw_usart_set_baudrate(dw_usart_reg_t *addr, uint32_t baudrate, uint32_t apbfreq)
+{
+ WAIT_USART_IDLE(addr);
+
+ /* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/
+ uint32_t divisor = ((apbfreq * 10) / baudrate) >> 4;
+
+ if ((divisor % 10) >= 5) {
+ divisor = (divisor / 10) + 1;
+ } else {
+ divisor = divisor / 10;
+ }
+
+ addr->LCR |= LCR_SET_DLAB;
+ /* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/
+ addr->DLL = divisor & 0xff;
+ addr->DLH = (divisor >> 8) & 0xff;
+ /*
+ * The DLAB must be cleared after the baudrate is setted
+ * to access other registers.
+ */
+ addr->LCR &= (~LCR_SET_DLAB);
+
+ return 0;
+}
+
+/**
+ \brief enable or disable parity.
+ \param[in] addr usart base to operate.
+ \param[in] parity ODD=8, EVEN=16, or NONE=0.
+ \return error code
+*/
+
+static int32_t dw_usart_set_parity(dw_usart_reg_t *addr, usart_parity_e parity)
+{
+ WAIT_USART_IDLE(addr);
+
+ switch (parity) {
+ case USART_PARITY_NONE:
+ /*CLear the PEN bit(LCR[3]) to disable parity.*/
+ addr->LCR &= (~LCR_PARITY_ENABLE);
+ break;
+
+ case USART_PARITY_ODD:
+ /* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */
+ addr->LCR |= LCR_PARITY_ENABLE;
+ addr->LCR &= LCR_PARITY_ODD;
+ break;
+
+ case USART_PARITY_EVEN:
+ /* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/
+ addr->LCR |= LCR_PARITY_ENABLE;
+ addr->LCR |= LCR_PARITY_EVEN;
+ break;
+
+ default:
+ return ERR_USART(EDRV_USART_PARITY);
+ }
+
+ return 0;
+}
+
+/**
+ \brief set the stop bit.
+ \param[in] addr usart base to operate.
+ \param[in] stopbit two possible value: USART_STOP_BITS_1 and USART_STOP_BITS_2.
+ \return error code
+*/
+static int32_t dw_usart_set_stopbit(dw_usart_reg_t *addr, usart_stop_bits_e stopbit)
+{
+ WAIT_USART_IDLE(addr);
+
+ switch (stopbit) {
+ case USART_STOP_BITS_1:
+ /* Clear the STOP bit to set 1 stop bit*/
+ addr->LCR &= LCR_STOP_BIT1;
+ break;
+
+ case USART_STOP_BITS_2:
+ /*
+ * If the STOP bit is set "1",we'd gotten 1.5 stop
+ * bits when DLS(LCR[1:0]) is zero, else 2 stop bits.
+ */
+ addr->LCR |= LCR_STOP_BIT2;
+ break;
+
+ default:
+ return ERR_USART(EDRV_USART_STOP_BITS);
+ }
+
+ return 0;
+}
+
+/**
+ \brief the transmit data length,and we have four choices:5, 6, 7, and 8 bits.
+ \param[in] addr usart base to operate.
+ \param[in] databits the data length that user decides.
+ \return error code
+*/
+static int32_t dw_usart_set_databit(dw_usart_reg_t *addr, usart_data_bits_e databits)
+{
+ WAIT_USART_IDLE(addr);
+ /* The word size decides by the DLS bits(LCR[1:0]), and the
+ * corresponding relationship between them is:
+ * DLS word size
+ * 00 -- 5 bits
+ * 01 -- 6 bits
+ * 10 -- 7 bits
+ * 11 -- 8 bits
+ */
+
+ switch (databits) {
+ case USART_DATA_BITS_5:
+ addr->LCR &= LCR_WORD_SIZE_5;
+ break;
+
+ case USART_DATA_BITS_6:
+ addr->LCR &= 0xfd;
+ addr->LCR |= LCR_WORD_SIZE_6;
+ break;
+
+ case USART_DATA_BITS_7:
+ addr->LCR &= 0xfe;
+ addr->LCR |= LCR_WORD_SIZE_7;
+ break;
+
+ case USART_DATA_BITS_8:
+ addr->LCR |= LCR_WORD_SIZE_8;
+ break;
+
+ default:
+ return ERR_USART(EDRV_USART_DATA_BITS);
+ }
+
+ return 0;
+}
+
+/**
+ \brief get character in query mode.
+ \param[in] instance usart instance to operate.
+ \param[in] the pointer to the recieve charater.
+ \return error code
+*/
+int32_t dw_usart_getchar(usart_handle_t handle, uint8_t *ch)
+{
+ dw_usart_priv_t *usart_priv = handle;
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+
+ while (!(addr->LSR & LSR_DATA_READY));
+
+ *ch = addr->RBR;
+
+ return 0;
+}
+
+/**
+ \brief get character in query mode.
+ \param[in] instance usart instance to operate.
+ \param[in] the pointer to the recieve charater.
+ \return error code
+*/
+int32_t dw_usart_getchar_no_poll(usart_handle_t handle, uint8_t *ch)
+{
+ dw_usart_priv_t *usart_priv = handle;
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+
+ if (addr->LSR & LSR_DATA_READY)
+ {
+ *ch = addr->RBR;
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+int32_t dw_usart_set_int_flag(usart_handle_t handle,uint32_t flag)
+{
+ dw_usart_priv_t *usart_priv = handle;
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+
+ addr->IER |= flag;
+
+ return 0;
+}
+
+int32_t dw_usart_clr_int_flag(usart_handle_t handle,uint32_t flag)
+{
+ dw_usart_priv_t *usart_priv = handle;
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+
+ addr->IER &= ~flag;
+
+ return 0;
+}
+
+/**
+ \brief transmit character in query mode.
+ \param[in] instance usart instance to operate.
+ \param[in] ch the input charater
+ \return error code
+*/
+int32_t dw_usart_putchar(usart_handle_t handle, uint8_t ch)
+{
+ dw_usart_priv_t *usart_priv = handle;
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+
+ while ((!(addr->LSR & DW_LSR_TRANS_EMPTY)));
+
+ if (ch == '\n')
+ {
+ addr->THR = '\r';
+
+ while ((!(addr->LSR & DW_LSR_TRANS_EMPTY))) ;
+ }
+
+ addr->THR = ch;
+
+ return 0;
+
+}
+
+/**
+ \brief interrupt service function for transmitter holding register empty.
+ \param[in] usart_priv usart private to operate.
+*/
+static void dw_usart_intr_threshold_empty(dw_usart_priv_t *usart_priv)
+{
+ if (usart_priv->tx_total_num == 0) {
+ return;
+ }
+
+ uint8_t remain_txdata = usart_priv->tx_total_num - usart_priv->tx_cnt;
+
+ uint8_t txdata_num = (remain_txdata > UART_MAX_FIFO) ? UART_MAX_FIFO : remain_txdata;
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+ uint8_t i = 0u;
+
+ for (i = 0; i < txdata_num; i++) {
+ addr->THR = *((uint8_t *)usart_priv->tx_buf);
+ usart_priv->tx_cnt++;
+ usart_priv->tx_buf++;
+ }
+
+ if (usart_priv->tx_cnt >= usart_priv->tx_total_num) {
+ addr->IER &= (~IER_THRE_INT_ENABLE);
+
+ while ((!(addr->LSR & DW_LSR_TEMT)));
+
+ usart_priv->tx_cnt = 0;
+ usart_priv->tx_busy = 0;
+ usart_priv->tx_buf = NULL;
+ usart_priv->tx_total_num = 0;
+
+ if (usart_priv->cb_event) {
+ usart_priv->cb_event(USART_EVENT_SEND_COMPLETE, usart_priv->cb_arg);
+ }
+ }
+
+}
+
+/**
+ \brief interrupt service function for receiver data available.
+ \param[in] usart_priv usart private to operate.
+*/
+static void dw_usart_intr_recv_data(dw_usart_priv_t *usart_priv)
+{
+ if (usart_priv->cb_event && (usart_priv->rx_total_num == 0)) {
+ usart_priv->cb_event(USART_EVENT_RECEIVED, usart_priv->cb_arg);
+ return;
+ }
+
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+ uint8_t data = addr->RBR;
+
+ if ((usart_priv->rx_total_num == 0) || (usart_priv->rx_buf == NULL)) {
+ return;
+ }
+
+ *((uint8_t *)usart_priv->rx_buf) = data;
+ usart_priv->rx_cnt++;
+ usart_priv->rx_buf++;
+
+ if (usart_priv->rx_cnt >= usart_priv->rx_total_num) {
+ usart_priv->rx_cnt = 0;
+ usart_priv->rx_buf = NULL;
+ usart_priv->rx_busy = 0;
+ usart_priv->rx_total_num = 0;
+
+ if (usart_priv->cb_event) {
+ usart_priv->cb_event(USART_EVENT_RECEIVE_COMPLETE, usart_priv->cb_arg);
+ }
+ }
+
+}
+
+/**
+ \brief the interrupt service function.
+ \param[in] index of usart instance.
+*/
+void dw_usart_irqhandler(int32_t idx)
+{
+ dw_usart_priv_t *usart_priv = &usart_instance[idx];
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+
+ uint8_t intr_state = addr->IIR & 0xf;
+
+ switch (intr_state) {
+ case DW_IIR_THR_EMPTY: /* interrupt source:transmitter holding register empty */
+ dw_usart_intr_threshold_empty(usart_priv);
+ break;
+
+ case DW_IIR_RECV_DATA: /* interrupt source:receiver data available or receiver fifo trigger level reached */
+ dw_usart_intr_recv_data(usart_priv);
+ break;
+
+ default:
+ break;
+ }
+}
+
+int32_t __attribute__((weak)) target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq)
+{
+ return -1;
+}
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle usart handle to operate.
+ \return \ref usart_capabilities_t
+*/
+usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle)
+{
+ return usart_capabilities;
+}
+
+/**
+ \brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
+ \param[in] usart pin of tx
+ \param[in] usart pin of rx
+ \param[in] cb_event Pointer to \ref usart_event_cb_t
+ \return return usart handle if success
+*/
+usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg)
+{
+ uint32_t base = 0u;
+ uint32_t irq = 0u;
+
+ int32_t idx = target_usart_init(tx, rx, &base, &irq);
+
+ if (idx < 0 || idx >= CONFIG_USART_NUM) {
+ return NULL;
+ }
+
+ dw_usart_priv_t *usart_priv = &usart_instance[idx];
+ usart_priv->base = base;
+ usart_priv->irq = irq;
+ usart_priv->cb_event = cb_event;
+ usart_priv->cb_arg = cb_arg;
+
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+ /* FIFO enable */
+ addr->FCR = DW_FCR_FIFOE;
+// /* enable received data available */
+// addr->IER = IER_RDA_INT_ENABLE;
+ drv_nvic_enable_irq(usart_priv->irq);
+
+ return usart_priv;
+}
+
+/**
+ \brief De-initialize UART 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)
+{
+ USART_NULL_PARAM_CHK(handle);
+
+ dw_usart_priv_t *usart_priv = handle;
+
+ drv_nvic_disable_irq(usart_priv->irq);
+ usart_priv->cb_event = NULL;
+
+ return 0;
+}
+
+/**
+ \brief config usart mode.
+ \param[in] handle usart handle to operate.
+ \param[in] sysclk configured system clock.
+ \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
+ \param[in] baud configured baud
+ \return error code
+*/
+int32_t csi_usart_config(usart_handle_t handle,
+ uint32_t sysclk,
+ uint32_t baud,
+ usart_mode_e mode,
+ usart_parity_e parity,
+ usart_stop_bits_e stopbits,
+ usart_data_bits_e bits)
+{
+ USART_NULL_PARAM_CHK(handle);
+ dw_usart_priv_t *usart_priv = handle;
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+
+ /* control the data_bit of the usart*/
+ int32_t ret = dw_usart_set_baudrate(addr, baud, sysclk);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* control the parity of the usart*/
+ ret = dw_usart_set_parity(addr, parity);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* control the stopbit of the usart*/
+ ret = dw_usart_set_stopbit(addr, stopbits);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = dw_usart_set_databit(addr, bits);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+/**
+ \brief config usart default tx value. used in syn mode
+ \param[in] handle usart handle to operate.
+ \param[in] value default tx value
+ \return error code
+*/
+int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value)
+{
+ USART_NULL_PARAM_CHK(handle);
+ return ERR_USART(EDRV_UNSUPPORTED);
+}
+
+/**
+ \brief Start sending data to UART transmitter,(received data is ignored).
+ The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes.
+ csi_usart_get_status can indicates if transmission is still in progress or pending
+ \param[in] handle usart handle to operate.
+ \param[in] data Pointer to buffer with data to send to UART transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 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)
+{
+ USART_NULL_PARAM_CHK(handle);
+ USART_NULL_PARAM_CHK(data);
+
+ if (num == 0) {
+ return ERR_USART(EDRV_PARAMETER);
+ }
+
+ dw_usart_priv_t *usart_priv = handle;
+ uint8_t *source = NULL;
+ source = (uint8_t *)data;
+
+ usart_priv->tx_buf = (uint8_t *)data;
+ usart_priv->tx_total_num = num;
+ usart_priv->tx_cnt = 0;
+ usart_priv->tx_busy = 1;
+
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+ /* enable the interrupt*/
+ addr->IER |= IER_THRE_INT_ENABLE;
+ return 0;
+}
+
+/**
+ \brief Abort Send data to UART transmitter
+ \param[in] handle usart handle to operate.
+ \return error code
+*/
+int32_t csi_usart_abort_send(usart_handle_t handle)
+{
+ USART_NULL_PARAM_CHK(handle);
+ dw_usart_priv_t *usart_priv = handle;
+
+ usart_priv->tx_cnt = usart_priv->tx_total_num;
+ return 0;
+}
+
+/**
+ \brief Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value
+ \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 error code
+*/
+int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num)
+{
+ USART_NULL_PARAM_CHK(handle);
+ USART_NULL_PARAM_CHK(data);
+
+ uint8_t *dest = NULL;
+ dw_usart_priv_t *usart_priv = handle;
+ dest = (uint8_t *)data;
+
+ usart_priv->rx_buf = (uint8_t *)data; // Save receive buffer usart
+ usart_priv->rx_total_num = num; // Save number of data to be received
+ usart_priv->rx_cnt = 0;
+ usart_priv->rx_busy = 1;
+
+ return 0;
+
+}
+
+/**
+ \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 receive fifo data num
+*/
+int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num)
+{
+ USART_NULL_PARAM_CHK(handle);
+ USART_NULL_PARAM_CHK(data);
+
+ dw_usart_priv_t *usart_priv = handle;
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+ int32_t recv_num = 0;
+
+ while (addr->LSR & 0x1) {
+ *((uint8_t *)data++) = addr->RBR;
+ recv_num++;
+
+ if (recv_num >= num) {
+ break;
+ }
+ }
+
+ return recv_num;
+
+}
+
+/**
+ \brief Abort Receive data from UART receiver
+ \param[in] handle usart handle to operate.
+ \return error code
+*/
+int32_t csi_usart_abort_receive(usart_handle_t handle)
+{
+ USART_NULL_PARAM_CHK(handle);
+ dw_usart_priv_t *usart_priv = handle;
+
+ usart_priv->rx_cnt = usart_priv->rx_total_num;
+ return 0;
+}
+
+/**
+ \brief Start sending/receiving data to/from UART transmitter/receiver.
+ \param[in] handle usart handle to operate.
+ \param[in] data_out Pointer to buffer with data to send to USART transmitter
+ \param[out] data_in Pointer to buffer for data to receive from USART receiver
+ \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)
+{
+ USART_NULL_PARAM_CHK(handle);
+ return ERR_USART(EDRV_UNSUPPORTED);
+}
+
+/**
+ \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)
+{
+ USART_NULL_PARAM_CHK(handle);
+ return ERR_USART(EDRV_UNSUPPORTED);
+}
+
+/**
+ \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)
+{
+ usart_status_t usart_status;
+ dw_usart_priv_t *usart_priv = handle;
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+ uint32_t line_status_reg = addr->LSR;
+
+ usart_status.tx_busy = usart_priv->tx_busy;
+ usart_status.rx_busy = usart_priv->rx_busy;
+
+ if (line_status_reg & DW_LSR_BI) {
+ usart_status.rx_break = 1;
+ }
+
+ if (line_status_reg & DW_LSR_FE) {
+ usart_status.rx_framing_error = 1;
+ }
+
+ if (line_status_reg & DW_LSR_PE) {
+ usart_status.rx_parity_error = 1;
+ }
+
+ return usart_status;
+}
+
+/**
+ \brief control the transmit.
+ \param[in] handle usart handle to operate.
+ \param[in] enable the transmitter.
+ \return error code
+*/
+int32_t csi_usart_control_tx(usart_handle_t handle, bool enable)
+{
+ USART_NULL_PARAM_CHK(handle);
+ return ERR_USART(EDRV_UNSUPPORTED);
+}
+
+/**
+ \brief control the receive.
+ \param[in] handle usart handle to operate.
+ \param[in] enable the receive.
+ \return error code
+*/
+int32_t csi_usart_control_rx(usart_handle_t handle, bool enable)
+{
+ USART_NULL_PARAM_CHK(handle);
+ return ERR_USART(EDRV_UNSUPPORTED);
+}
+
+/**
+ \brief control the break.
+ \param[in] handle usart handle to operate.
+ \param[in] enable the break.
+ \return error code
+*/
+int32_t csi_usart_control_break(usart_handle_t handle, bool enable)
+{
+ USART_NULL_PARAM_CHK(handle);
+ return ERR_USART(EDRV_UNSUPPORTED);
+}
+
+/**
+ \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)
+{
+ USART_NULL_PARAM_CHK(handle);
+
+ dw_usart_priv_t *usart_priv = handle;
+ dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
+
+ if (type == USART_FLUSH_WRITE) {
+ addr->FCR |= DW_FCR_XFIFOR;
+ } else if (type == USART_FLUSH_READ) {
+ addr->FCR |= DW_FCR_RFIFOR;
+ } else {
+ return ERR_USART(EDRV_PARAMETER);
+ }
+
+ return 0;
+}
diff --git a/bsp/ck802/libraries/common/usart/dw_usart.h b/bsp/ck802/libraries/common/usart/dw_usart.h
new file mode 100644
index 0000000000..21d06bb69e
--- /dev/null
+++ b/bsp/ck802/libraries/common/usart/dw_usart.h
@@ -0,0 +1,110 @@
+/*
+ * 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 dw_usart.h
+ * @brief header file for usart driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef __DW_USART_H
+#define __DW_USART_H
+
+#include <stdio.h>
+#include "errno.h"
+#include "soc.h"
+
+#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_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_FCR_FIFOE 0x01
+#define DW_FCR_RFIFOR 0x02
+#define DW_FCR_XFIFOR 0x04
+#define DW_FCR_RT_FIFO_SINGLE 0x00 /* rcvr trigger 1 character in the FIFO */
+#define DW_FCR_RT_FIFO_QUARTER 0x01 /* rcvr trigger FIFO 1/4 full */
+#define DW_FCR_RT_FIFO_HALF 0x10 /* rcvr trigger FIFO 1/2 full */
+#define DW_FCR_RT_FIFO_LESSTWO 0x11 /* rcvr trigger FIFO 2 less than full */
+#define DW_FCR_TET_FIFO_EMPTY 0x00 /* tx empty trigger FIFO empty */
+#define DW_FCR_TET_FIFO_TWO 0x01 /* tx empty trigger 2 characters in the FIFO */
+#define DW_FCR_TET_FIFO_QUARTER 0x10 /* tx empty trigger FIFO 1/4 full */
+#define DW_FCR_TET_FIFO_HALF 0x11 /* tx empty trigger FIFO 1/2 full*/
+
+#define DW_IIR_THR_EMPTY 0x02 /* threshold empty */
+#define DW_IIR_RECV_DATA 0x04 /* received data available */
+
+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 */
+ };
+ union {
+ __IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */
+ __OM uint32_t FCR; /* Offset: 0x008 ( /W) FIFO control register */
+ };
+ __IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */
+ __IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem control register */
+ __IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */
+ __IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */
+ uint32_t RESERVED1[21];
+ __IOM uint32_t FAR; /* Offset: 0x070 (R/W) FIFO accesss register */
+ __IM uint32_t TFR; /* Offset: 0x074 (R/ ) transmit FIFO read */
+ __OM uint32_t RFW; /* Offset: 0x078 ( /W) receive FIFO write */
+ __IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */
+ __IM uint32_t TFL; /* Offset: 0x080 (R/ ) transmit FIFO level */
+ __IM uint32_t RFL; /* Offset: 0x084 (R/ ) receive FIFO level */
+} dw_usart_reg_t;
+
+
+#endif /* __DW_USART_H */
+
diff --git a/bsp/ck802/libraries/common/wdt/dw_wdt.c b/bsp/ck802/libraries/common/wdt/dw_wdt.c
new file mode 100644
index 0000000000..84d1149680
--- /dev/null
+++ b/bsp/ck802/libraries/common/wdt/dw_wdt.c
@@ -0,0 +1,267 @@
+/*
+ * 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 dw_wdt.c
+ * @brief CSI Source File for WDT Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#include <stdio.h>
+#include "csi_core.h"
+#include "drv_wdt.h"
+#include "dw_wdt.h"
+#include "soc.h"
+
+#define ERR_WDT(errno) (CSI_DRV_ERRNO_WDT_BASE | errno)
+
+static uint32_t timeout_ms[16] = {4, 7, 13, 26, 52, 105, 210, 419, 839, 1678, 3355, 6711,
+ 13422, 26844, 53687, 107374
+ };
+
+#define WDT_NULL_PARAM_CHK(para) \
+ do { \
+ if (para == NULL) { \
+ return ERR_WDT(EDRV_PARAMETER); \
+ } \
+ } while (0)
+
+typedef struct {
+ uint32_t base;
+ uint32_t irq;
+ wdt_event_cb_t cb_event;
+} dw_wdt_priv_t;
+
+static dw_wdt_priv_t wdt_instance[CONFIG_WDT_NUM];
+
+/* Driver Capabilities */
+static const wdt_capabilities_t wdt_capabilities = {
+ .interrupt = 1, ///< supports interrupt
+};
+
+static inline void dw_wdt_enable(dw_wdt_reg_t *addr)
+{
+ uint32_t value = addr->WDT_CR;
+ value |= 1 << 0;
+ addr->WDT_CR = value;
+}
+
+static inline void dw_wdt_disable(dw_wdt_reg_t *addr)
+{
+ uint32_t value = addr->WDT_CR;
+ value &= ~(1 << 0);
+ addr->WDT_CR = value;
+}
+
+
+void dw_wdt_irqhandler(int32_t idx)
+{
+ dw_wdt_priv_t *wdt_priv = &wdt_instance[idx];
+ dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
+
+ addr->WDT_EOI;
+
+ if (wdt_priv->cb_event) {
+ wdt_priv->cb_event(WDT_EVENT_TIMEOUT);
+ }
+}
+
+int32_t __attribute__((weak)) target_get_wdt_count(void)
+{
+ return 0;
+}
+
+int32_t __attribute__((weak)) target_get_wdt(uint32_t idx, uint32_t *base, uint32_t *irq)
+{
+ return NULL;
+}
+
+
+/**
+ \brief get wdt instance count.
+ \return wdt instance count
+*/
+int32_t csi_wdt_get_instance_count(void)
+{
+ return target_get_wdt_count();
+}
+
+/**
+ \brief Initialize WDT Interface. 1. Initializes the resources needed for the WDT interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_wdt_get_instance_count()
+ \param[in] cb_event Pointer to \ref wdt_event_cb_t
+ \return pointer to wdt instance
+*/
+wdt_handle_t csi_wdt_initialize(int32_t idx, wdt_event_cb_t cb_event)
+{
+ if (idx < 0 || idx >= CONFIG_WDT_NUM) {
+ return NULL;
+ }
+
+ uint32_t base = 0u;
+ uint32_t irq = 0u;
+
+ int32_t real_idx = target_get_wdt(idx, &base, &irq);
+
+ if (real_idx != idx) {
+ return NULL;
+ }
+
+ dw_wdt_priv_t *wdt_priv = &wdt_instance[idx];
+ wdt_priv->base = base;
+ wdt_priv->irq = irq;
+
+ wdt_priv->cb_event = cb_event;
+ drv_nvic_enable_irq(wdt_priv->irq);
+
+ return (wdt_handle_t)wdt_priv;
+}
+
+/**
+ \brief De-initialize WDT Interface. stops operation and releases the software resources used by the interface
+ \param[in] instance wdt instance to operate.
+ \return \ref execution_status
+*/
+int32_t csi_wdt_uninitialize(wdt_handle_t handle)
+{
+ WDT_NULL_PARAM_CHK(handle);
+
+ dw_wdt_priv_t *wdt_priv = handle;
+
+ wdt_priv->cb_event = NULL;
+ drv_nvic_disable_irq(wdt_priv->irq);
+ return 0;
+}
+/**
+ \brief Get driver capabilities.
+ \param[in] wdt instance to operate.
+ \return \ref wdt_capabilities_t
+*/
+wdt_capabilities_t csi_wdt_get_capabilities(wdt_handle_t handle)
+{
+ return wdt_capabilities;
+}
+
+/**
+ \brief Set the WDT value. value = (2^t*0xffff * 10^6 /freq)/10^3(t: 0 ~ 15).
+ \param[in] handle wdt handle to operate.
+ \param[in] value the timeout value(ms) \ref:timeout_ms[]
+ \return \ref execution_status
+*/
+int32_t csi_wdt_set_timeout(wdt_handle_t handle, uint32_t value)
+{
+ WDT_NULL_PARAM_CHK(handle);
+ uint32_t i = 0u;
+
+ for (i = 0; i <= 15 ; i++) {
+ if (timeout_ms[i] == value) {
+ break;
+ }
+
+ if (i == 15) {
+ return ERR_WDT(EDRV_PARAMETER);
+ }
+ }
+
+ dw_wdt_priv_t *wdt_priv = handle;
+ dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
+
+ uint32_t config = addr->WDT_CR;
+ uint32_t en_stat = 0; /*origin wdt enable status*/
+
+ if ((config & 0x1) != 0) {
+ en_stat = 1;
+ }
+
+ config = 0;
+ addr->WDT_CR = config;
+
+ /*before configuration, must disable wdt first*/
+ dw_wdt_disable(addr);
+ i += i << 4;
+ addr->WDT_TORR = i;
+
+ if (en_stat == 1) {
+ dw_wdt_enable(addr);
+ csi_wdt_restart(handle);
+ }
+
+ return 0;
+}
+
+/**
+ \brief Start the WDT.
+ \param[in] handle wdt handle to operate.
+ \return \ref execution_status
+*/
+int32_t csi_wdt_start(wdt_handle_t handle)
+{
+ WDT_NULL_PARAM_CHK(handle);
+
+ dw_wdt_priv_t *wdt_priv = handle;
+ dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
+
+ dw_wdt_enable(addr);
+ csi_wdt_restart(handle);
+ return 0;
+}
+
+/**
+ \brief Stop the WDT.
+ \param[in] handle wdt handle to operate.
+ \return \ref execution_status
+*/
+int32_t csi_wdt_stop(wdt_handle_t handle)
+{
+ WDT_NULL_PARAM_CHK(handle);
+
+ return ERR_WDT(EDRV_UNSUPPORTED);
+}
+
+/**
+ \brief Restart the WDT.
+ \param[in] handle wdt handle to operate.
+ \return \ref execution_status
+*/
+int32_t csi_wdt_restart(wdt_handle_t handle)
+{
+ WDT_NULL_PARAM_CHK(handle);
+
+ dw_wdt_priv_t *wdt_priv = handle;
+ dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
+
+ addr->WDT_CRR = DW_WDT_CRR_RESET;
+
+ return 0;
+}
+
+/**
+ \brief Read the WDT Current value.
+ \param[in] handle wdt handle to operate.
+ \param[in] value Pointer to the Value.
+ \return \ref execution_status
+*/
+int32_t csi_wdt_read_current_value(wdt_handle_t handle, uint32_t *value)
+{
+ WDT_NULL_PARAM_CHK(handle);
+
+ dw_wdt_priv_t *wdt_priv = handle;
+ dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
+
+ *value = addr->WDT_CCVR;
+ return 0;
+}
+
diff --git a/bsp/ck802/libraries/common/wdt/dw_wdt.h b/bsp/ck802/libraries/common/wdt/dw_wdt.h
new file mode 100644
index 0000000000..47cd9bea67
--- /dev/null
+++ b/bsp/ck802/libraries/common/wdt/dw_wdt.h
@@ -0,0 +1,44 @@
+/*
+ * 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 dw_wdt.h
+ * @brief header file for wdt driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef __DW_WDT_H
+#define __DW_WDT_H
+
+#include <stdio.h>
+#include "soc.h"
+
+#define DW_WDT_CRR_RESET 0x76
+typedef struct {
+ __IOM uint8_t WDT_CR:5; /* Offset: 0x000 (R/W) WDT control register */
+ uint8_t RESERVED0[3];
+ __IOM uint8_t WDT_TORR; /* Offset: 0x004 (R/W) WDT timeout range register */
+ uint8_t RESERVED1[3];
+ __IM uint32_t WDT_CCVR; /* Offset: 0x008 (R/ ) WDT current counter value register */
+ __OM uint8_t WDT_CRR:8; /* Offset: 0x00C ( /W) WDT count restart register */
+ uint8_t RESERVED2[3];
+ __IM uint8_t WDT_STAT:1; /* Offset: 0x010 (R/ ) WDT interrupt status register */
+ uint8_t RESERVED3[3];
+ __IM uint8_t WDT_EOI:1; /* Offset: 0x014 (R/ ) WDT interrupt clear register */
+ uint8_t RESERVED4[3];
+} dw_wdt_reg_t;
+
+#endif /* __DW_WDT_H */
+
diff --git a/bsp/ck802/libraries/include/drv_aes.h b/bsp/ck802/libraries/include/drv_aes.h
new file mode 100644
index 0000000000..7fa5e7c817
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_aes.h
@@ -0,0 +1,189 @@
+/*
+ * 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 drv_aes.h
+ * @brief Header File for AES Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CSI_AES_H_
+#define _CSI_AES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_common.h>
+#include <drv_errno.h>
+
+
+/// definition for aes handle.
+typedef void *aes_handle_t;
+
+/****** AES specific error codes *****/
+typedef enum {
+ AES_ERROR_MODE = (EDRV_SPECIFIC + 1) , ///< Specified Mode not supported
+ AES_ERROR_DATA_BITS , ///< Specified number of Data bits not supported
+ AES_ERROR_ENDIAN ///< Specified endian not supported
+} drv_aes_error_e;
+
+/*----- AES Control Codes: Mode -----*/
+typedef enum {
+ AES_MODE_ECB = 0, ///< ECB Mode
+ AES_MODE_CBC , ///< CBC Mode
+ AES_MODE_CFB , ///< CFB Mode
+ AES_MODE_OFB , ///< OFB Mode
+ AES_MODE_CTR ///< CTR Mode
+} aes_mode_e;
+
+/*----- AES Control Codes: Crypto Mode -----*/
+typedef enum {
+ AES_CRYPTO_MODE_ENCRYPT = 0, ///< encrypt Mode
+ AES_CRYPTO_MODE_DECRYPT , ///< decrypt Mode
+} aes_crypto_mode_e;
+
+/*----- AES Control Codes: Padding Mode -----*/
+typedef enum {
+ AES_PADDING_MODE_NO = 0, ///< NO-PADDING
+ AES_PADDING_MODE_ZERO , ///< ZERO-PADDING
+ AES_PADDING_MODE_PKCS5 ///< PKCS5-PADDING
+} aes_padding_mode_e;
+
+/*----- AES Control Codes: Mode Parameters: Key length -----*/
+typedef enum {
+ AES_KEY_LEN_BITS_128 = 0, ///< 128 Data bits
+ AES_KEY_LEN_BITS_192 , ///< 192 Data bits
+ AES_KEY_LEN_BITS_256 ///< 256 Data bits
+} aes_key_len_bits_e;
+
+/*----- AES Control Codes: Mode Parameters: Endian -----*/
+typedef enum {
+ AES_ENDIAN_LITTLE = 0, ///< Little Endian
+ AES_ENDIAN_BIG ///< Big Endian
+} aes_endian_mode_e;
+
+/**
+\brief AES Status
+*/
+typedef struct {
+ uint32_t busy : 1; ///< busy flag
+} aes_status_t;
+
+/****** AES Event *****/
+typedef enum {
+ AES_EVENT_CRYPTO_COMPLETE = 0 ///< Encrypt completed
+} aes_event_e;
+typedef void (*aes_event_cb_t)(aes_event_e event); ///< Pointer to \ref aes_event_cb_t : AES Event call back.
+
+
+/**
+\brief AES Device Driver Capabilities.
+*/
+typedef struct {
+ uint32_t ecb_mode : 1; ///< supports ECB mode
+ uint32_t cbc_mode : 1; ///< supports CBC mode
+ uint32_t cfb_mode : 1; ///< supports CFB mode
+ uint32_t ofb_mode : 1; ///< supports OFB mode
+ uint32_t ctr_mode : 1; ///< supports CTR mode
+ uint32_t bits_128 : 1; ///< supports 128bits key length
+ uint32_t bits_192 : 1; ///< supports 192bits key length
+ uint32_t bits_256 : 1; ///< supports 256bits key length
+} aes_capabilities_t;
+
+
+// Function documentation
+
+/**
+ \brief get aes instance count.
+ \return aes handle count
+*/
+int32_t csi_aes_get_instance_count(void);
+
+/**
+ \brief Initialize AES Interface. 1. Initializes the resources needed for the AES interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_aes_get_instance_count().
+ \param[in] cb_event Pointer to \ref aes_event_cb_t
+ \return return aes handle if success
+*/
+aes_handle_t csi_aes_initialize(int32_t idx, aes_event_cb_t cb_event);
+
+/**
+ \brief De-initialize AES Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle aes handle to operate.
+ \return error code
+*/
+int32_t csi_aes_uninitialize(aes_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle aes handle to operate.
+ \return \ref aes_capabilities_t
+*/
+aes_capabilities_t csi_aes_get_capabilities(aes_handle_t handle);
+
+/**
+ \brief config aes mode.
+ \param[in] handle aes handle to operate.
+ \param[in] mode \ref aes_mode_e
+ \param[in] keylen_bits \ref aes_key_len_bits_e
+ \param[in] endian \ref aes_endian_mode_e
+ \param[in] arg Pointer to the iv address when mode is cbc_mode
+ \return error code
+*/
+int32_t csi_aes_config(aes_handle_t handle,
+ aes_mode_e mode,
+ aes_key_len_bits_e keylen_bits,
+ aes_endian_mode_e endian,
+ uint32_t arg
+ );
+
+/**
+ \brief set crypto key.
+ \param[in] handle aes handle to operate.
+ \param[in] context aes information context(NULL when hardware implementation)
+ \param[in] key Pointer to the key buf
+ \param[in] key_len the key len
+ \param[in] enc \ref aes_crypto_mode_e
+ \return error code
+*/
+int32_t csi_aes_set_key(aes_handle_t handle, void *context, void *key, uint32_t key_len, aes_crypto_mode_e enc);
+
+/**
+ \brief encrypt or decrypt
+ \param[in] handle aes handle to operate.
+ \param[in] context aes information context(NULL when hardware implementation)
+ \param[in] in Pointer to the Source data
+ \param[out] out Pointer to the Result data.
+ \param[in] len the Source data len.
+ \param[in] padding \ref aes_padding_mode_e.
+ \return error code
+*/
+int32_t csi_aes_crypto(aes_handle_t handle, void *context, void *in, void *out, uint32_t len, aes_padding_mode_e padding);
+
+/**
+ \brief Get AES status.
+ \param[in] handle aes handle to operate.
+ \return AES status \ref aes_status_t
+*/
+aes_status_t csi_aes_get_status(aes_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_AES_H_ */
diff --git a/bsp/ck802/libraries/include/drv_common.h b/bsp/ck802/libraries/include/drv_common.h
new file mode 100644
index 0000000000..f7c22d90ea
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_common.h
@@ -0,0 +1,47 @@
+/*
+ * 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 drv_common.h
+ * @brief Header File for Common Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _DRV_COMMON_H_
+#define _DRV_COMMON_H_
+
+#include <stdint.h>
+#include <drv_errno.h>
+#include "config.h"
+
+/** pin definition */
+typedef int32_t pin_t;
+
+/// \details driver handle
+typedef void *drv_handle_t;
+
+/**
+\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_stat_e;
+
+#endif /* _DRV_COMMON_H */
+
diff --git a/bsp/ck802/libraries/include/drv_crc.h b/bsp/ck802/libraries/include/drv_crc.h
new file mode 100644
index 0000000000..bde0e9ed18
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_crc.h
@@ -0,0 +1,150 @@
+/*
+ * 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 drv_crc.h
+ * @brief Header File for CRC Driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CSI_CRC_H_
+#define _CSI_CRC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_errno.h>
+#include <drv_common.h>
+
+
+/****** CRC specific error codes *****/
+#define CRC_ERROR_MODE (EDRV_SPECIFIC + 1) ///< Specified Mode not supported
+
+/// definition for crc handle.
+typedef void *crc_handle_t;
+
+/*----- CRC Control Codes: Mode -----*/
+typedef enum {
+ CRC_MODE_CRC8 = 0, ///< Mode CRC8
+ CRC_MODE_CRC16 , ///< Mode CRC16
+ CRC_MODE_CRC32 ///< Mode CRC32
+} crc_mode_e;
+
+/*----- CRC Control Codes: Mode Parameters: Key length -----*/
+typedef enum {
+ CRC_STANDARD_CRC_ROHC = 0, ///< Standard CRC RHOC
+ CRC_STANDARD_CRC_MAXIM , ///< Standard CRC MAXIAM
+ CRC_STANDARD_CRC_X25 , ///< Standard CRC X25
+ CRC_STANDARD_CRC_CCITT , ///< Standard CRC CCITT
+ CRC_STANDARD_CRC_USB , ///< Standard CRC USB
+ CRC_STANDARD_CRC_IBM , ///< Standard CRC IBM
+ CRC_STANDARD_CRC_MODBUS ///< Standard CRC MODBUS
+} crc_standard_crc_e;
+
+/**
+\brief CRC Status
+*/
+typedef struct {
+ uint32_t busy : 1; ///< busy flag
+} crc_status_t;
+
+/****** CRC Event *****/
+typedef enum {
+ CRC_EVENT_CALCULATE_COMPLETE = 0, ///< Calculate completed
+} crc_event_e;
+
+typedef void (*crc_event_cb_t)(crc_event_e event); ///< Pointer to \ref crc_event_cb_t : CRC Event call back.
+
+/**
+\brief CRC Device Driver Capabilities.
+*/
+typedef struct {
+ uint32_t ROHC : 1; ///< supports ROHC mode
+ uint32_t MAXIM : 1; ///< supports MAXIM mode
+ uint32_t X25 : 1; ///< supports X25 mode
+ uint32_t CCITT : 1; ///< supports CCITT mode
+ uint32_t USB : 1; ///< supports USB mode
+ uint32_t IBM : 1; ///< supports IBM mode
+ uint32_t MODBUS : 1; ///< supports MODBUS mode
+} crc_capabilities_t;
+
+// Function documentation
+
+/**
+ \brief get crc handle count.
+ \return crc handle count
+*/
+int32_t csi_crc_get_instance_count(void);
+
+/**
+ \brief Initialize CRC Interface. 1. Initializes the resources needed for the CRC interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_crc_get_handle_count()
+ \param[in] cb_event Pointer to \ref crc_event_cb_t
+ \return return crc handle if success
+*/
+crc_handle_t csi_crc_initialize(int32_t idx, crc_event_cb_t cb_event);
+
+/**
+ \brief De-initialize CRC Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle crc handle to operate.
+ \return error code
+*/
+int32_t csi_crc_uninitialize(crc_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle crc handle to operate.
+ \return \ref crc_capabilities_t
+*/
+crc_capabilities_t csi_crc_get_capabilities(crc_handle_t handle);
+
+/**
+ \brief config crc mode.
+ \param[in] handle crc handle to operate.
+ \param[in] mode \ref crc_mode_e
+ \param[in] standard \ref crc_standard_crc_e
+ \return error code
+*/
+int32_t csi_crc_config(crc_handle_t handle,
+ crc_mode_e mode,
+ crc_standard_crc_e standard
+ );
+
+/**
+ \brief calculate crc.
+ \param[in] handle crc handle to operate.
+ \param[in] in Pointer to the input data
+ \param[out] out Pointer to the result.
+ \param[in] len intpu data len.
+ \return error code
+*/
+int32_t csi_crc_calculate(crc_handle_t handle, const void *in, void *out, uint32_t len);
+
+/**
+ \brief Get CRC status.
+ \param[in] handle crc handle to operate.
+ \return CRC status \ref crc_status_t
+*/
+crc_status_t csi_crc_get_status(crc_handle_t handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_CRC_H_ */
diff --git a/bsp/ck802/libraries/include/drv_dmac.h b/bsp/ck802/libraries/include/drv_dmac.h
new file mode 100644
index 0000000000..633e061699
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_dmac.h
@@ -0,0 +1,171 @@
+/*
+ * 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 drv_dmac.h
+ * @brief header file for dmac driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CSI_DMA_H_
+#define _CSI_DMA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_common.h>
+
+/// definition for dmac handle.
+typedef void *dmac_handle_t;
+
+/**
+\brief DMA Driver Capabilities.
+*/
+typedef struct {
+ uint32_t unalign_addr : 1; ///< support for unalign address transfer when memory is source
+} dma_capabilities_t;
+
+typedef enum {
+ DMA_STATE_FREE = 0, ///< DMA not yet initialized or disabled
+ DMA_STATE_READY, ///< DMA process success and ready for use, but not start yet
+ DMA_STATE_BUSY, ///< DMA process is ongoing
+ DMA_STATE_ERROR, ///< DMA transfer error
+ DMA_STATE_DONE, ///< DMA transfer done
+} dma_status_e;
+
+/****** DMA specific error codes *****/
+typedef enum {
+ EDRV_DMA_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
+} dma_error_e;
+
+/****** DMA Event *****/
+typedef enum {
+ DMA_EVENT_TRANSFER_DONE = 0, ///< transfer complete
+ DMA_EVENT_TRANSFER_ERROR = 1, ///< transfer error
+} dma_event_e;
+
+typedef enum {
+ DMA_ADDR_INC = 0,
+ DMA_ADDR_DEC,
+ DMA_ADDR_CONSTANT
+} dma_addr_inc_e;
+
+typedef enum {
+ DMA_MEM2MEM = 0,
+ DMA_MEM2PERH,
+ DMA_PERH2MEM,
+ DMA_PERH2PERH,
+} dma_trans_type_e;
+
+typedef struct {
+ dma_addr_inc_e src_inc; ///< source address increment
+ dma_addr_inc_e dst_inc; ///< destination address increment
+ uint8_t src_tw; ///< source transfer width in byte
+ uint8_t dst_tw; ///< destination transfer width in byte
+ uint8_t hs_if; ///< a hardware handshaking interface
+ dma_trans_type_e type; ///< transfer type
+} dma_config_t;
+
+typedef void (*dma_event_cb_t)(dma_event_e event, int32_t ch); ///< Pointer to \ref dma_event_cb_t : CRC Event call back.
+
+/**
+ \brief get dma instance count.
+ \return dma instance count
+*/
+int32_t csi_dma_get_instance_count(void);
+
+/**
+ \brief Initialize DMA Interface. 1. Initializes the resources needed for the DMA interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_dma_get_instance_count()
+ \return pointer to dma instances
+*/
+dmac_handle_t csi_dma_initialize(int32_t idx);
+
+/**
+ \brief De-initialize DMA Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle damc handle to operate.
+ \return error code
+*/
+int32_t csi_dma_uninitialize(dmac_handle_t handle);
+/**
+ \brief Get driver capabilities.
+ \param[in] handle damc handle to operate.
+ \return \ref dma_capabilities_t
+*/
+dma_capabilities_t csi_dma_get_capabilities(dmac_handle_t handle);
+
+/**
+ \brief get one free dma channel
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num. if -1 then allocate a free channal in this dma
+ \return -1 - no channel can be used, other - channel index
+ */
+int32_t csi_dma_alloc_channel(dmac_handle_t handle, int32_t ch);
+
+/**
+ \brief release dma channel and related resources
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num.
+ \return error code
+ */
+int32_t csi_dma_release_channel(dmac_handle_t handle, int32_t ch);
+
+/**
+ \brief
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num. if -1 then allocate a free channal in this dma
+ \param[in] psrcaddr dma transfer source address
+ \param[in] pstdaddr dma transfer source address
+ \param[in] length dma transfer length
+ \param[in] config dma transfer configure
+ \param[in] cb_event Pointer to \ref dma_event_cb_t
+ \return error code
+ */
+int32_t csi_dma_config(dmac_handle_t handle, int32_t ch,
+ void *psrcaddr, void *pstdaddr,
+ uint32_t length, dma_config_t *config, dma_event_cb_t cb_event);
+
+/**
+ \brief start generate dma signal.
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num.
+ \return error code
+*/
+int32_t csi_dma_start(dmac_handle_t handle, int32_t ch);
+
+/**
+ \brief Stop generate dma signal.
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num.
+ \return error code
+*/
+int32_t csi_dma_stop(dmac_handle_t handle, int32_t ch);
+
+/**
+ \brief Get DMA status.
+ \param[in] handle damc handle to operate.
+ \param[in] ch channel num.
+ \return DMA status \ref dma_status_e
+*/
+dma_status_e csi_dma_get_status(dmac_handle_t handle, int32_t ch);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_DMA_H_ */
+
diff --git a/bsp/ck802/libraries/include/drv_eflash.h b/bsp/ck802/libraries/include/drv_eflash.h
new file mode 100644
index 0000000000..35be506393
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_eflash.h
@@ -0,0 +1,157 @@
+/*
+ * 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 drv_eflash.h
+ * @brief header file for eflash driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CSI_EFLASH_H_
+#define _CSI_EFLASH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_common.h>
+
+
+/// definition for eflash handle.
+typedef void *eflash_handle_t;
+
+/**
+\brief Flash information
+*/
+typedef struct {
+ uint32_t start; ///< Chip Start address
+ uint32_t end; ///< Chip End address (start+size-1)
+ uint32_t sector_count; ///< Number of sectors
+ uint32_t sector_size; ///< Uniform sector size in bytes (0=sector_info used)
+ uint32_t page_size; ///< Optimal programming page size in bytes
+ uint32_t program_unit; ///< Smallest programmable unit in bytes
+ uint8_t erased_value; ///< Contents of erased memory (usually 0xFF)
+} eflash_info;
+
+/**
+\brief Flash Status
+*/
+typedef struct {
+ uint32_t busy : 1; ///< Flash busy flag
+ uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation)
+} eflash_status_t;
+
+/****** EFLASH Event *****/
+typedef enum {
+ EFLASH_EVENT_READY = 0, ///< Flash Ready
+ EFLASH_EVENT_ERROR , ///< Read/Program/Erase Error
+} eflash_event_e;
+
+typedef void (*eflash_event_cb_t)(eflash_event_e event); ///< Pointer to \ref eflash_event_cb_t : EFLASH Event call back.
+
+/**
+\brief Flash Driver Capabilities.
+*/
+typedef struct {
+ uint32_t event_ready : 1; ///< Signal Flash Ready event
+ uint32_t data_width : 2; ///< Data width: 0=8-bit, 1=16-bit, 2=32-bit
+ uint32_t erase_chip : 1; ///< Supports EraseChip operation
+} eflash_capabilities_t;
+
+// Function documentation
+
+/**
+ \brief get eflash handle count.
+ \return eflash handle count
+*/
+int32_t csi_eflash_get_instance_count(void);
+
+/**
+ \brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_eflash_get_instance_count()
+ \param[in] cb_event Pointer to \ref eflash_event_cb_t
+ \return pointer to eflash handle
+*/
+eflash_handle_t csi_eflash_initialize(int32_t idx, eflash_event_cb_t cb_event);
+
+/**
+ \brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle eflash handle to operate.
+ \return error code
+*/
+int32_t csi_eflash_uninitialize(eflash_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle eflash handle to operate.
+ \return \ref eflash_capabilities_t
+*/
+eflash_capabilities_t csi_eflash_get_capabilities(eflash_handle_t handle);
+
+/**
+ \brief Read data from Flash.
+ \param[in] handle eflash handle to operate.
+ \param[in] addr Data address.
+ \param[out] data Pointer to a buffer storing the data read from Flash.
+ \param[in] cnt Number of data items to read.
+ \return number of data items read or error code
+*/
+int32_t csi_eflash_read(eflash_handle_t handle, uint32_t addr, void *data, uint32_t cnt);
+
+/**
+ \brief Program data to Flash.
+ \param[in] handle eflash handle to operate.
+ \param[in] addr Data address.
+ \param[in] data Pointer to a buffer containing the data to be programmed to Flash..
+ \param[in] cnt Number of data items to program.
+ \return number of data items programmed or error code
+*/
+int32_t csi_eflash_program(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt);
+
+/**
+ \brief Erase Flash Sector.
+ \param[in] handle eflash handle to operate.
+ \param[in] addr Sector address
+ \return error code
+*/
+int32_t csi_eflash_erase_sector(eflash_handle_t handle, uint32_t addr);
+
+/**
+ \brief Erase complete Flash.
+ \param[in] handle eflash handle to operate.
+ \return error code
+*/
+int32_t csi_eflash_erase_chip(eflash_handle_t handle);
+
+/**
+ \brief Get Flash information.
+ \param[in] handle eflash handle to operate.
+ \return Pointer to Flash information \ref eflash_info
+*/
+eflash_info *csi_eflash_get_info(eflash_handle_t handle);
+
+/**
+ \brief Get EFLASH status.
+ \param[in] handle eflash handle to operate.
+ \return EFLASH status \ref eflash_status_t
+*/
+eflash_status_t csi_eflash_get_status(eflash_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_EFLASH_H_ */
diff --git a/bsp/ck802/libraries/include/drv_errno.h b/bsp/ck802/libraries/include/drv_errno.h
new file mode 100644
index 0000000000..c7187eb0da
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_errno.h
@@ -0,0 +1,116 @@
+/*
+ * 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 drv_errno.h
+ * @brief header file for error num
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+/******************************************************************************
+ * @file
+ * @details Error code field difination
+ * Error number is devided into 4 field:
+ * 0x8******* : 8 : means < 0
+ * 0x*A****** : A : means type number: bsp(1), driver(2), hal(3), app(4)...
+ * 0x**AB**** : AB : means module number: timer(1), rtc(2), ....
+ * 0x****AB** : AB : means API number: module API's definition
+ * 0x******AB : AB : means sub error number
+ * 0 ~ 0x80 is common error such as EPERM, refer to errno.h
+ * 0x80 ~ 0xFF is specific error, can difine in module
+ *
+ * For example 0x81020113 means:
+ * 1. 0x8*******: value < 0, means error happened
+ * 2. 0x*1******: type number is 1, means bsp error
+ * 3. 0x**02****: module number is 02, means RTC error
+ * 4. 0x****01**: module API is 01, means RTC's init
+ * 5. 0x******13: specific error is 0x13=19=ENODEV, means no such device
+ *
+ * For special bsp module example, you can return:
+ * (BSP_ERRNO_TIMER_BASE | BSP_API_RTC_INIT | EPERM) for rtc init error
+ * (BSP_ERRNO_TIMER_BASE | BSP_API_RTC_SETTIME | ENXIO) for rtc settime error
+ *
+ * Here list the common sub error number (0x******AB) below(0~127 defined in errno.h as standard err code):
+ * Code Hex Deci Meaning
+ * -------------------------------------------------------
+ * EPERM 0x01 1 Operation not permitted
+ * EIO 0x05 5 I/O error
+ * ENXIO 0x06 6 No such device or address
+ * ENOMEM 0x0C 12 Out of memory
+ * EACCES 0x0D 13 Permission denied
+ * EINVAL 0x16 22 Invalid argument
+ * ...
+ * SPEC_ERR_BASE 0x80 128 module special error number base
+ * ...
+ * ERRNO_MAX 0xFF -- Max sub error number
+ ******************************************************************************/
+
+#ifndef _DRV_ERRNO_H_
+#define _DRV_ERRNO_H_
+
+
+#include <errno.h>
+
+#define ERRNO_DRV_START 0X80
+
+/* drvier General return codes */
+typedef enum {
+ EDRV = ERRNO_DRV_START, ///< Unspecified error
+ EDRV_BUSY, ///< Driver is busy
+ EDRV_TIMEOUT, ///< Timeout occurred
+ EDRV_UNSUPPORTED, ///< Operation not supported
+ EDRV_PARAMETER, ///< Parameter error
+ EDRV_SPECIFIC ///< Start of driver specific errors
+} drv_common_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
+/** means bsp errors */
+#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_I2C_BASE 0x81040000
+#define CSI_DRV_ERRNO_FLASH_BASE 0x81050000
+#define CSI_DRV_ERRNO_PWM_BASE 0x81060000
+#define CSI_DRV_ERRNO_RTC_BASE 0x81070000
+#define CSI_DRV_ERRNO_TIMER_BASE 0x81080000
+#define CSI_DRV_ERRNO_WDT_BASE 0x81090000
+#define CSI_DRV_ERRNO_AES_BASE 0x810A0000
+#define CSI_DRV_ERRNO_CRC_BASE 0x810B0000
+#define CSI_DRV_ERRNO_RSA_BASE 0x810C0000
+#define CSI_DRV_ERRNO_SHA_BASE 0x810D0000
+#define CSI_DRV_ERRNO_TRNG_BASE 0x810E0000
+#define CSI_DRV_ERRNO_EFLASH_BASE 0x810F0000
+#define CSI_DRV_ERRNO_DMA_BASE 0x81100000
+
+#endif /* CSI_DRV_ERRNO_H */
diff --git a/bsp/ck802/libraries/include/drv_eth.h b/bsp/ck802/libraries/include/drv_eth.h
new file mode 100644
index 0000000000..12b5d18213
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_eth.h
@@ -0,0 +1,105 @@
+/**
+ * Copyright (C) 2016 CSI Project. 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.
+ */
+
+
+#ifndef _CSI_NET_H_
+#define _CSI_NET_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CSI_ETH_VERSION_MAJOR_MINOR(major,minor) (((major) << 8) | (minor))
+
+/**
+\brief Driver Version
+*/
+typedef struct csi_driver_version {
+ uint16_t api; ///< API version
+ uint16_t drv; ///< Driver version
+} csi_drv_version_t;
+
+/* General return codes */
+#define CSI_ETH_OK 0 ///< Operation succeeded
+#define CSI_ETH_ERROR CSI_DRV_ERRNO_ETH_BASE+1 ///< Unspecified error
+#define CSI_ETH_ERROR_BUSY CSI_DRV_ERRNO_ETH_BASE+2 ///< Driver is busy
+#define CSI_ETH_ERROR_TIMEOUT CSI_DRV_ERRNO_ETH_BASE+3 ///< Timeout occurred
+#define CSI_ETH_ERROR_UNSUPPORTED CSI_DRV_ERRNO_ETH_BASE+4 ///< Operation not supported
+#define CSI_ETH_ERROR_PARAMETER CSI_DRV_ERRNO_ETH_BASE+5 ///< Parameter error
+#define CSI_ETH_ERROR_SPECIFIC CSI_DRV_ERRNO_ETH_BASE+6 ///< Start of driver specific errors
+
+/**
+\brief General power states
+*/
+typedef enum eth_power_state {
+ CSI_ETH_POWER_OFF, ///< Power off: no operation possible
+ CSI_ETH_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events
+ CSI_ETH_POWER_FULL ///< Power on: full operation at maximum performance
+} eth_power_state_t;
+
+/**
+\brief Ethernet Media Interface type
+*/
+#define CSI_ETH_INTERFACE_MII (0) ///< Media Independent Interface (MII)
+#define CSI_ETH_INTERFACE_RMII (1) ///< Reduced Media Independent Interface (RMII)
+#define CSI_ETH_INTERFACE_SMII (2) ///< Serial Media Independent Interface (SMII)
+
+/**
+\brief Ethernet link speed
+*/
+#define CSI_ETH_SPEED_10M (0) ///< 10 Mbps link speed
+#define CSI_ETH_SPEED_100M (1) ///< 100 Mbps link speed
+#define CSI_ETH_SPEED_1G (2) ///< 1 Gpbs link speed
+
+/**
+\brief Ethernet duplex mode
+*/
+#define CSI_ETH_DUPLEX_HALF (0) ///< Half duplex link
+#define CSI_ETH_DUPLEX_FULL (1) ///< Full duplex link
+
+/**
+\brief Ethernet link state
+*/
+typedef enum eth_link_state {
+ ETH_LINK_DOWN, ///< Link is down
+ ETH_LINK_UP ///< Link is up
+} eth_link_state_t;
+
+/**
+\brief Ethernet link information
+*/
+typedef volatile struct eth_link_info {
+ uint32_t speed : 2; ///< Link speed: 0= 10 MBit, 1= 100 MBit, 2= 1 GBit
+ uint32_t duplex : 1; ///< Duplex mode: 0= Half, 1= Full
+ uint32_t Autonegotiation : 1; ///< Set the interface to Auto Negotiation mode of transmission parameters
+ uint32_t Loopback : 1; ///< Set the interface into a Loop-back test mode
+ uint32_t Isolation : 1; ///< Set to indicate electrical isolation of PHY interface from MII/RMII interface
+ uint32_t reserved : 26;
+} eth_link_info_t;
+
+/**
+\brief Ethernet MAC Address
+*/
+typedef struct eth_mac_addr {
+ uint8_t b[6]; ///< MAC Address (6 bytes), MSB first
+} eth_mac_addr_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CSI_NET_H_ */
+
diff --git a/bsp/ck802/libraries/include/drv_eth_mac.h b/bsp/ck802/libraries/include/drv_eth_mac.h
new file mode 100644
index 0000000000..30501ecebf
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_eth_mac.h
@@ -0,0 +1,367 @@
+/**
+ * Copyright (C) 2016 CSI Project. 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.
+ */
+
+#ifndef _CSI_ETH_H_
+#define _CSI_ETH_H_
+
+#include "drv_eth.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *eth_mac_handle_t;
+
+#define MAX_FRAMELEN 1518 /* (note: maximum ethernet frame length would be 1518) */
+
+#define CSI_ETH_MAC_API_VERSION CSI_DRIVER_VERSION_MAJOR_MINOR(2,1) /* API version */
+
+#define _CSI_Driver_ETH_MAC_(n) Driver_ETH_MAC##n
+#define CSI_Driver_ETH_MAC_(n) _CSI_Driver_ETH_MAC_(n)
+
+/****** Ethernet MAC Control Codes *****/
+
+#define CSI_ETH_MAC_CONFIGURE (0x01) ///< Configure MAC; arg = configuration
+#define CSI_ETH_MAC_CONTROL_TX (0x02) ///< Transmitter; arg: 0=disabled (default), 1=enabled
+#define CSI_ETH_MAC_CONTROL_RX (0x03) ///< Receiver; arg: 0=disabled (default), 1=enabled
+#define CSI_ETH_MAC_FLUSH (0x04) ///< Flush buffer; arg = CSI_ETH_MAC_FLUSH_...
+#define CSI_ETH_MAC_SLEEP (0x05) ///< Sleep mode; arg: 1=enter and wait for Magic packet, 0=exit
+#define CSI_ETH_MAC_VLAN_FILTER (0x06) ///< VLAN Filter for received frames; arg15..0: VLAN Tag; arg16: optional CSI_ETH_MAC_VLAN_FILTER_ID_ONLY; 0=disabled (default)
+
+/*----- Ethernet MAC Configuration -----*/
+#define CSI_ETH_MAC_SPEED_Pos 0
+#define CSI_ETH_MAC_SPEED_Msk (3UL << CSI_ETH_MAC_SPEED_Pos)
+#define CSI_ETH_MAC_SPEED_10M (CSI_ETH_SPEED_10M << CSI_ETH_MAC_SPEED_Pos) ///< 10 Mbps link speed
+#define CSI_ETH_MAC_SPEED_100M (CSI_ETH_SPEED_100M << CSI_ETH_MAC_SPEED_Pos) ///< 100 Mbps link speed
+#define CSI_ETH_MAC_SPEED_1G (CSI_ETH_SPEED_1G << CSI_ETH_MAC_SPEED_Pos) ///< 1 Gpbs link speed
+#define CSI_ETH_MAC_DUPLEX_Pos 2
+#define CSI_ETH_MAC_DUPLEX_Msk (1UL << CSI_ETH_MAC_DUPLEX_Pos)
+#define CSI_ETH_MAC_DUPLEX_HALF (CSI_ETH_DUPLEX_HALF << CSI_ETH_MAC_DUPLEX_Pos) ///< Half duplex link
+#define CSI_ETH_MAC_DUPLEX_FULL (CSI_ETH_DUPLEX_FULL << CSI_ETH_MAC_DUPLEX_Pos) ///< Full duplex link
+#define CSI_ETH_MAC_LOOPBACK (1UL << 4) ///< Loop-back test mode
+#define CSI_ETH_MAC_CHECKSUM_OFFLOAD_RX (1UL << 5) ///< Receiver Checksum offload
+#define CSI_ETH_MAC_CHECKSUM_OFFLOAD_TX (1UL << 6) ///< Transmitter Checksum offload
+#define CSI_ETH_MAC_ADDRESS_BROADCAST (1UL << 7) ///< Accept frames with Broadcast address
+#define CSI_ETH_MAC_ADDRESS_MULTICAST (1UL << 8) ///< Accept frames with any Multicast address
+#define CSI_ETH_MAC_ADDRESS_ALL (1UL << 9) ///< Accept frames with any address (Promiscuous Mode)
+
+/*----- Ethernet MAC Flush Flags -----*/
+#define CSI_ETH_MAC_FLUSH_RX (1UL << 0) ///< Flush Receive buffer
+#define CSI_ETH_MAC_FLUSH_TX (1UL << 1) ///< Flush Transmit buffer
+
+/*----- Ethernet MAC VLAN Filter Flag -----*/
+#define CSI_ETH_MAC_VLAN_FILTER_ID_ONLY (1UL << 16) ///< Compare only the VLAN Identifier (12-bit)
+
+
+/****** Ethernet MAC Frame Transmit Flags *****/
+#define CSI_ETH_MAC_TX_FRAME_FRAGMENT (1UL << 0) ///< Indicate frame fragment
+#define CSI_ETH_MAC_TX_FRAME_EVENT (1UL << 1) ///< Generate event when frame is transmitted
+#define CSI_ETH_MAC_TX_FRAME_TIMESTAMP (1UL << 2) ///< Capture frame time stamp
+
+
+/****** Ethernet MAC Timer Control Codes *****/
+#define CSI_ETH_MAC_TIMER_GET_TIME (0x01) ///< Get current time
+#define CSI_ETH_MAC_TIMER_SET_TIME (0x02) ///< Set new time
+#define CSI_ETH_MAC_TIMER_INC_TIME (0x03) ///< Increment current time
+#define CSI_ETH_MAC_TIMER_DEC_TIME (0x04) ///< Decrement current time
+#define CSI_ETH_MAC_TIMER_SET_ALCSI (0x05) ///< Set alarm time
+#define CSI_ETH_MAC_TIMER_ADJUST_CLOCK (0x06) ///< Adjust clock frequency; time->ns: correction factor * 2^31
+
+
+/**
+\brief Ethernet MAC Time
+*/
+typedef struct eth_mac_time {
+ uint32_t ns; ///< Nano seconds
+ uint32_t sec; ///< Seconds
+} eth_mac_time_t;
+
+
+/****** Ethernet MAC Event *****/
+#define CSI_ETH_MAC_EVENT_RX_FRAME (1UL << 0) ///< Frame Received
+#define CSI_ETH_MAC_EVENT_TX_FRAME (1UL << 1) ///< Frame Transmitted
+#define CSI_ETH_MAC_EVENT_WAKEUP (1UL << 2) ///< Wake-up (on Magic Packet)
+#define CSI_ETH_MAC_EVENT_TIMER_ALCSI (1UL << 3) ///< Timer Alarm
+#define CSI_ETH_MAC_EVENT_LINK_CHANGE (1UL << 4) ///< Link state
+
+typedef void (*eth_event_cb_t)(eth_mac_handle_t handle, uint32_t event); ///< Pointer to \ref eth_event_cb_t : Signal Ethernet Event.
+
+typedef enum
+{
+ FRAME_FILTER_RULE_POSITIVE_MATCHING = 0, /*!< Specifies that a filter should match a given pattern */
+ FRAME_FILTER_RULE_NEGATIVE_MATCHING = 1, /*!< Specifies that a filter should NOT match a given pattern */
+} frame_filter_rule_t;
+
+/**
+\brief Ethernet MAC Capabilities
+*/
+typedef struct eth_capabilities {
+ uint32_t checksum_offload_rx_ip4 : 1; ///< 1 = IPv4 header checksum verified on receive
+ uint32_t checksum_offload_rx_ip6 : 1; ///< 1 = IPv6 checksum verification supported on receive
+ uint32_t checksum_offload_rx_udp : 1; ///< 1 = UDP payload checksum verified on receive
+ uint32_t checksum_offload_rx_tcp : 1; ///< 1 = TCP payload checksum verified on receive
+ uint32_t checksum_offload_rx_icmp : 1; ///< 1 = ICMP payload checksum verified on receive
+ uint32_t checksum_offload_tx_ip4 : 1; ///< 1 = IPv4 header checksum generated on transmit
+ uint32_t checksum_offload_tx_ip6 : 1; ///< 1 = IPv6 checksum generation supported on transmit
+ uint32_t checksum_offload_tx_udp : 1; ///< 1 = UDP payload checksum generated on transmit
+ uint32_t checksum_offload_tx_tcp : 1; ///< 1 = TCP payload checksum generated on transmit
+ uint32_t checksum_offload_tx_icmp : 1; ///< 1 = ICMP payload checksum generated on transmit
+ uint32_t media_interface : 2; ///< Ethernet Media Interface type
+ uint32_t mac_address : 1; ///< 1 = driver provides initial valid MAC address
+ uint32_t event_rx_frame : 1; ///< 1 = callback event generated
+ uint32_t event_tx_frame : 1; ///< 1 = callback event generated
+ uint32_t event_wakeup : 1; ///< 1 = wakeup event generated
+ uint32_t precision_timer : 1; ///< 1 = Precision Timer supported
+ uint32_t reserved : 15; ///< Reserved (must be zero)
+} eth_capabilities_t;
+
+#if 0
+/**
+\brief Ethernet Frame filter
+*/
+typedef struct eth_frame_filter {
+ struct {
+ uint32_t and_or : 1; ///< 1 = AND: Packets will be rejected unless all enabled filters accept the packet; 0 = OR: Packets will be accepted unless all enabled filters reject the packet
+ uint32_t unicast_en : 1; ///< 1 = Packets with a destination address matching the local MAC address will be accepted
+ uint32_t multicast_en : 1; ///< 1 = Packets which have the Least Significant bit set in the destination address will be accepted
+ uint32_t broadcast_en : 1; ///< 1 = Packets which have a destination address of FF-FF-FF-FF-FF-FF will be accepted
+ uint32_t crc_en : 1; ///< 1 = All packets with an invalid CRC will be discarded
+ uint32_t patten_match_en : 1; ///< 1 = Packets which meet the Pattern Match criteria will be accepted
+ uint32_t magic_packet_en : 1; ///< 1 = Magic Packets for the local MAC address will be accepted
+ uint32_t hash_table_en : 1; ///< 1 = Packets which meet the Hash Table criteria will be accepted
+ } sum; ///< summary
+ uint32_t patten_match; ///< patten match filter
+ uint32_t magic_packet; ///< patten match filter
+ uint32_t hash_table; ///< hash table filter
+} eth_frame_filter_t;
+#else
+/**
+ * Structure describing a frame filter list item
+ */
+typedef struct
+{
+ uint32_t id; /*!< Unique identifier for a packet filter item */
+ frame_filter_rule_t rule; /*!< Filter matches are either POSITIVE or NEGATIVE matching */
+ uint16_t offset; /*!< Offset in bytes to start filtering (referenced to the start of the ethernet packet) */
+ uint16_t mask_size; /*!< Size of the mask in bytes */
+ uint8_t* mask; /*!< Pattern mask bytes to be ANDed with the pattern eg. "\xff00" (must be in network byte order) */
+ uint8_t* pattern; /*!< Pattern bytes used to filter eg. "\x0800" (must be in network byte order) */
+ bool enabled_status; /*!< When returned from mhd_get_packet_filters, indicates if the filter is enabled */
+} eth_frame_filter_t;
+
+struct eth_frame_filter_list
+{
+ struct eth_frame_filter_list* next;
+};
+typedef struct eth_frame_filter_list eth_frame_filter_list_t;
+#endif
+
+typedef struct {
+ eth_event_cb_t cb_event;
+ eth_capabilities_t capabilities;
+}eth_mac_priv_t;
+
+/**
+ \brief Get driver version.
+ \param[in] handle ethernet handle
+ \return ethernet version including chip version and driver version
+*/
+csi_drv_version_t csi_eth_mac_get_version(eth_mac_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle ethernet handle
+ \return ethernet capabilities
+*/
+eth_capabilities_t csi_eth_mac_get_capabilities(eth_mac_handle_t handle);
+
+/**
+ \brief This function is used to initialize Ethernet device and related resource, an event callback is registered. It is called when the middleware component like TCPIP starts operation.
+ \param[in] cb callback to handle ethernet event
+ \return return ethernet handle if success
+ */
+eth_mac_handle_t csi_eth_mac_initialize(eth_event_cb_t cb);
+
+/**
+ \brief This function is used to de-initialize Ethernet device. It is called when the middleware component stops operation and releases the software resources used by the interface.
+ \param[in] handle ethernet handle
+ \return error code
+ */
+int32_t csi_eth_mac_uninitialize(eth_mac_handle_t handle);
+
+/**
+ \brief Control Ethernet MAC Device Power.
+ \param[in] handle ethernet handle
+ \param[in] state Power state
+ \return error code
+*/
+int32_t csi_eth_mac_power_control(eth_mac_handle_t handle, eth_power_state_t state);
+
+/**
+ \brief Get Ethernet MAC Address.
+ \param[in] handle ethernet handle
+ \param[in] mac Pointer to address
+ \return error code
+*/
+int32_t csi_eth_mac_get_macaddr(eth_mac_handle_t handle, eth_mac_addr_t *mac);
+
+/**
+ \brief Set Ethernet MAC Address.
+ \param[in] handle ethernet handle
+ \param[in] mac Pointer to address
+ \return error code
+*/
+int32_t csi_eth_mac_set_macaddr(eth_mac_handle_t handle, const eth_mac_addr_t *mac);
+
+/**
+ \brief Configure Address Filter.
+ \param[in] handle ethernet handle
+ \param[in] addr Pointer to addresses
+ \param[in] num_addr Number of addresses to configure
+ \return error code
+*/
+int32_t csi_eth_mac_set_addrfilter(eth_mac_handle_t handle, const eth_mac_addr_t *addr, uint32_t num_addr);
+
+/**
+ \brief Send Ethernet frame.
+ \param[in] handle ethernet handle
+ \param[in] frame Pointer to frame buffer with data to send
+ \param[in] len Frame buffer length in bytes
+ \param[in] flags Frame transmit flags (see CSI_ETH_MAC_TX_FRAME_...)
+ \return error code
+*/
+int32_t csi_eth_mac_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len, uint32_t flags);
+
+/**
+ \brief Read data of received Ethernet frame.
+ \param[in] handle ethernet handle
+ \param[in] frame Pointer to frame buffer for data to read into
+ \param[in] len Frame buffer length in bytes
+ \return number of data bytes read or execution status
+ - value >= 0: number of data bytes read
+ - value < 0: error occurred, value is execution status as defined with execution_status
+*/
+int32_t csi_eth_mac_read_frame(eth_mac_handle_t handle, uint8_t *frame, uint32_t len);
+
+/**
+ \brief Get size of received Ethernet frame.
+ \param[in] handle ethernet handle
+ \return number of bytes in received frame
+*/
+int32_t csi_eth_mac_get_rx_framesize(eth_mac_handle_t handle);
+
+/**
+ \brief Get time of received Ethernet frame.
+ \param[in] handle ethernet handle
+ \param[in] time Pointer to time structure for data to read into
+ \return error code
+*/
+int32_t csi_eth_mac_get_rx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time);
+
+/**
+ \brief Get time of transmitted Ethernet frame.
+ \param[in] handle ethernet handle
+ \param[in] time Pointer to time structure for data to read into
+ \return error code
+*/
+int32_t csi_eth_mac_get_tx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time);
+
+/**
+ \brief Control Ethernet Interface.
+ \param[in] handle ethernet handle
+ \param[in] control Operation
+ \param[in] arg Argument of operation (optional)
+ \return error code
+*/
+int32_t csi_eth_mac_control(eth_mac_handle_t handle, uint32_t control, uint32_t arg);
+
+/**
+ \brief Control Precision Timer.
+ \param[in] handle ethernet handle
+ \param[in] control Operation
+ \param[in] time Pointer to time structure
+ \return error code
+*/
+int32_t csi_eth_mac_control_time(eth_mac_handle_t handle, uint32_t control, eth_mac_time_t *time);
+
+/**
+ \brief Read Ethernet PHY Register through Management Interface.
+ \param[in] handle ethernet handle
+ \param[in] phy_addr 5-bit device address
+ \param[in] reg_addr 5-bit register address
+ \param[out] data Pointer where the result is written to
+ \return error code
+*/
+int32_t csi_eth_mac_phy_read(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
+
+/**
+ \brief Write Ethernet PHY Register through Management Interface.
+ \param[in] handle ethernet handle
+ \param[in] phy_addr 5-bit device address
+ \param[in] reg_addr 5-bit register address
+ \param[in] data 16-bit data to write
+ \return error code
+*/
+int32_t csi_eth_mac_phy_write(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
+
+/**
+ \brief Callback function that signals a Ethernet Event.
+ \param[in] handle ethernet handle
+ \param[in] event event notification mask
+ \return none
+*/
+void csi_eth_mac_signal_event(eth_mac_handle_t handle, uint32_t event);
+
+/**
+ \brief Add Frame Filter Setting with Filter ID.
+ \param[in] handle ethernet handle
+ \param[in] filter Pointer to filter setting
+ \return error code
+*/
+int32_t csi_eth_mac_add_framefilter(eth_mac_handle_t handle, const eth_frame_filter_t *filter);
+
+/**
+ \brief Remove Frame Filter Setting.
+ \param[in] handle ethernet handle
+ \param[in] filter_id Frame Filter ID
+ \return error code
+*/
+int32_t csi_eth_mac_remove_framefilter(eth_mac_handle_t handle, uint32_t filter_id);
+
+/**
+ \brief Enable/Disable Specified Frame Filter ID.
+ \param[in] handle ethernet handle
+ \param[in] filter_id Frame Filter ID
+ \param[in] en Enable or disable
+ \return error code
+*/
+int32_t csi_eth_mac_en_framefilter(eth_mac_handle_t handle, uint32_t filter_id, bool en);
+
+/**
+ \brief Get frame filter table list.
+ \param[in] handle ethernet handle
+ \param[in] list frame filter table list
+ \param[in] count_out the count of filter setting added
+ \param[in] max_count max filter setting can be supported
+ \return error code
+*/
+int32_t csi_eth_mac_get_framefilter(eth_mac_handle_t handle, eth_frame_filter_list_t* list, uint32_t* count_out, uint32_t max_count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/ck802/libraries/include/drv_eth_phy.h b/bsp/ck802/libraries/include/drv_eth_phy.h
new file mode 100644
index 0000000000..adf4aa0171
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_eth_phy.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (C) 2016 CSI Project. 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.
+ */
+
+#ifndef _CSI_ETH_PHY_H_
+#define _CSI_ETH_PHY_H_
+
+#include "drv_eth.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *eth_phy_handle_t;
+
+#define CSI_ETH_PHY_API_VERSION CSI_ETH_VERSION_MAJOR_MINOR(2,1) /* API version */
+
+
+#define _CSI_Driver_ETH_PHY_(n) Driver_ETH_PHY##n
+#define CSI_Driver_ETH_PHY_(n) _CSI_Driver_ETH_PHY_(n)
+
+
+/****** Ethernet PHY Mode *****/
+#define CSI_ETH_PHY_SPEED_Pos 0
+#define CSI_ETH_PHY_SPEED_Msk (3UL << CSI_ETH_PHY_SPEED_Pos)
+#define CSI_ETH_PHY_SPEED_10M (CSI_ETH_SPEED_10M << CSI_ETH_PHY_SPEED_Pos) ///< 10 Mbps link speed
+#define CSI_ETH_PHY_SPEED_100M (CSI_ETH_SPEED_100M << CSI_ETH_PHY_SPEED_Pos) ///< 100 Mbps link speed
+#define CSI_ETH_PHY_SPEED_1G (CSI_ETH_SPEED_1G << CSI_ETH_PHY_SPEED_Pos) ///< 1 Gpbs link speed
+#define CSI_ETH_PHY_DUPLEX_Pos 2
+#define CSI_ETH_PHY_DUPLEX_Msk (1UL << CSI_ETH_PHY_DUPLEX_Pos)
+#define CSI_ETH_PHY_DUPLEX_HALF (CSI_ETH_DUPLEX_HALF << CSI_ETH_PHY_DUPLEX_Pos) ///< Half duplex link
+#define CSI_ETH_PHY_DUPLEX_FULL (CSI_ETH_DUPLEX_FULL << CSI_ETH_PHY_DUPLEX_Pos) ///< Full duplex link
+#define CSI_ETH_PHY_AUTO_NEGOTIATE (1UL << 3) ///< Auto Negotiation mode
+#define CSI_ETH_PHY_LOOPBACK (1UL << 4) ///< Loop-back test mode
+#define CSI_ETH_PHY_ISOLATE (1UL << 5) ///< Isolate PHY from MII/RMII interface
+
+typedef int32_t (*csi_eth_phy_read_t) (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); ///< Read Ethernet PHY Register.
+typedef int32_t (*csi_eth_phy_write_t) (uint8_t phy_addr, uint8_t reg_addr, uint16_t data); ///< Write Ethernet PHY Register.
+
+typedef struct {
+ csi_eth_phy_read_t phy_read;
+ csi_eth_phy_write_t phy_write;
+ eth_link_info_t link_info;
+}eth_phy_priv_t;
+
+// Function documentation
+/**
+ \brief Get driver version.
+ \param[in] handle ethernet phy handle
+ \return driver version
+*/
+csi_drv_version_t csi_eth_phy_get_version(eth_phy_handle_t handle);
+
+/**
+ \brief Initialize Ethernet PHY Device.
+ \param[in] fn_read
+ \param[in] fn_write
+ \return ethernet phy handle
+*/
+eth_phy_handle_t csi_eth_phy_initialize(csi_eth_phy_read_t fn_read, csi_eth_phy_write_t fn_write);
+
+/**
+ \brief De-initialize Ethernet PHY Device.
+ \param[in] handle ethernet phy handle
+ \return error code
+*/
+int32_t csi_eth_phy_uninitialize(eth_phy_handle_t handle);
+
+/**
+ \brief Control Ethernet PHY Device Power.
+ \param[in] handle ethernet phy handle
+ \param[in] state Power state
+ \return error code
+*/
+int32_t csi_eth_phy_power_control(eth_phy_handle_t handle, eth_power_state_t state);
+
+/**
+ \brief Set Ethernet Media Interface.
+ \param[in] handle ethernet phy handle
+ \param[in] interface Media Interface type
+ \return error code
+*/
+int32_t csi_eth_phy_set_interface(eth_phy_handle_t handle, uint32_t interface);
+
+/**
+ \brief Set Ethernet PHY Device Operation mode.
+ \param[in] handle ethernet phy handle
+ \param[in] mode Operation Mode
+ \return error code
+*/
+int32_t csi_eth_phy_set_mode(eth_phy_handle_t handle, uint32_t mode);
+
+/**
+ \brief Get Ethernet PHY Device Link state.
+ \param[in] handle ethernet phy handle
+ \return current link status \ref eth_link_state_t
+*/
+eth_link_state_t csi_eth_phy_get_linkstate(eth_phy_handle_t handle);
+
+/**
+ \brief Get Ethernet PHY Device Link information.
+ \param[in] handle ethernet phy handle
+ \return current link parameters \ref eth_link_info_t
+*/
+eth_link_info_t csi_eth_phy_get_linkinfo(eth_phy_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/bsp/ck802/libraries/include/drv_gpio.h b/bsp/ck802/libraries/include/drv_gpio.h
new file mode 100644
index 0000000000..c51022dea5
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_gpio.h
@@ -0,0 +1,183 @@
+/*
+ * 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 drv_gpio.h
+ * @brief header file for gpio driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_GPIO_H_
+#define _CSI_GPIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <drv_common.h>
+#include <pin_name.h>
+
+/// definition for gpio port handle.
+typedef void *gpio_port_handle_t;
+/// definition for gpio pin handle.
+typedef void *gpio_pin_handle_t;
+
+/****** GPIO specific error codes *****/
+typedef enum {
+ GPIO_ERROR_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not suphandleed
+ GPIO_ERROR_DIRECTION, ///< Specified direction not suphandleed
+ GPIO_ERROR_IRQ_MODE, ///< Specified irq mode not suphandleed
+} drv_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_PULLDOWM , ///< 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;
+
+/**
+\brief GPIO Driver Capabilities.
+*/
+typedef struct {
+ uint32_t interrupt_mode : 1; ///< suphandles GPIO interrupt mode
+ uint32_t pull_mode : 1;
+} gpio_capabilities_t;
+
+
+typedef void (*gpio_event_cb_t)(gpio_pin_handle_t io); ///< gpio Event call back.
+
+/**
+ \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.
+ \param[in] cb_event Pointer to \ref gpio_event_cb_t
+ \return gpio_port_handle
+*/
+gpio_port_handle_t csi_gpio_port_initialize(port_name_t port, gpio_event_cb_t cb_event);
+
+/**
+ \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);
+
+/**
+ \brief Get gpio capabilities.all pins have same capabilities in one handle
+ \param[in] handle handle instance to operate.
+ \return \ref gpio_capabilities_t
+*/
+gpio_capabilities_t csi_gpio_get_io_capabilities(gpio_port_handle_t handle);
+
+/**
+ \brief config multiple pin within one handle
+ \param[in] handle gpio port handle to operate.
+ \param[in] mask the bitmask to identify which bits in the handle should be included (0 - ignore)
+ \param[in] mode \ref gpio_mode_e
+ \param[in] dir \ref gpio_direction_e
+ \return error code
+*/
+int32_t csi_gpio_port_config(gpio_port_handle_t handle,
+ uint32_t mask,
+ gpio_mode_e mode,
+ gpio_direction_e dir);
+
+/**
+ \brief Write value to the handle(write value to multiple pins on one handle at the same time)
+ \param[in] handle gpio port handle to operate.
+ \param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
+ \param[in] value the value to be set
+ \return error code
+*/
+int32_t csi_gpio_port_write(gpio_port_handle_t handle, uint32_t mask, uint32_t value);
+
+/**
+ \brief Read the current value on the handle(read value of multiple pins on one handle at the same time)
+ \param[in] handle gpio port handle to operate.
+ \param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
+ \param[out] value an integer with each bit corresponding to an associated handle pin setting
+ \return error code
+*/
+int32_t csi_gpio_port_read(gpio_port_handle_t handle, uint32_t mask, uint32_t *value);
+
+/**
+ \brief Initialize GPIO handle.
+ \param[in] gpio_pin Pointer to the pin_t.
+ \return gpio_pin_handle
+*/
+gpio_pin_handle_t csi_gpio_pin_initialize(pin_t gpio_pin);
+/**
+ \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 pin,
+ 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 the value to be set
+ \return error code
+*/
+int32_t csi_gpio_pin_write(gpio_pin_handle_t pin, bool value);
+
+/**
+ \brief Get the value of selected GPIO pin.
+ \param[in] pin 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 pin, bool *value);
+
+/**
+ \brief set GPIO interrupt mode.
+ \param[in] pin 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_irq_set(gpio_pin_handle_t pin, gpio_irq_mode_e mode, bool enable);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_GPIO_H_ */
diff --git a/bsp/ck802/libraries/include/drv_iic.h b/bsp/ck802/libraries/include/drv_iic.h
new file mode 100644
index 0000000000..606afb8f8d
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_iic.h
@@ -0,0 +1,195 @@
+/*
+ * 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 drv_iic.h
+ * @brief header file for iic driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_IIC_H_
+#define _CSI_IIC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <drv_common.h>
+
+/// definition for iic handle.
+typedef void *iic_handle_t;
+
+/*----- IIC Control Codes: Mode -----*/
+typedef enum {
+ IIC_MODE_MASTER, ///< IIC Master
+ IIC_MODE_SLAVE ///< IIC Slave
+} iic_mode_e;
+
+/*----- IIC Control Codes: IIC Bus Speed -----*/
+typedef enum {
+ I2C_BUS_SPEED_STANDARD = 0, ///< Standard Speed (100kHz)
+ I2C_BUS_SPEED_FAST = 1, ///< Fast Speed (400kHz)
+ I2C_BUS_SPEED_FAST_PLUS = 2, ///< Fast+ Speed ( 1MHz)
+ I2C_BUS_SPEED_HIGH = 3 ///< High Speed (3.4MHz)
+} iic_speed_e;
+
+/*----- IIC Control Codes: IIC Address Mode -----*/
+typedef enum {
+ I2C_ADDRESS_7BIT = 0, ///< 7-bit address mode
+ I2C_ADDRESS_10BIT = 1 ///< 10-bit address mode
+} iic_address_mode_e;
+
+/**
+\brief IIC Status
+*/
+typedef struct {
+ uint32_t busy : 1; ///< Transmitter/Receiver busy flag
+ uint32_t mode : 1; ///< Mode: 0=Slave, 1=Master
+ uint32_t direction : 1; ///< Direction: 0=Transmitter, 1=Receiver
+ uint32_t general_call : 1; ///< General Call(address 0) indication (cleared on start of next Slave operation)
+ uint32_t arbitration_lost : 1; ///< Master lost arbitration(in case of multi-masters) (cleared on start of next Master operation)
+ uint32_t bus_error : 1; ///< Bus error detected (cleared on start of next Master/Slave operation)
+} iic_status_t;
+
+/****** IIC Event *****/
+typedef enum {
+ I2C_EVENT_TRANSFER_DONE = 0, ///< Master/Slave Transmit/Receive finished
+ I2C_EVENT_TRANSFER_INCOMPLETE = 1, ///< Master/Slave Transmit/Receive incomplete transfer
+ I2C_EVENT_SLAVE_TRANSMIT = 2, ///< Slave Transmit operation requested
+ I2C_EVENT_SLAVE_RECEIVE = 3, ///< Slave Receive operation requested
+ I2C_EVENT_ADDRESS_NACK = 4, ///< Address not acknowledged from Slave
+ I2C_EVENT_GENERAL_CALL = 5, ///< General Call indication
+ I2C_EVENT_ARBITRATION_LOST = 6, ///< Master lost arbitration
+ I2C_EVENT_BUS_ERROR = 7, ///< Bus error detected (START/STOP at illegal position)
+ I2C_EVENT_BUS_CLEAR = 8 ///< Bus clear finished
+} iic_event_e;
+
+typedef void (*iic_event_cb_t)(iic_event_e event, void *arg); ///< Pointer to \ref iic_event_cb_t : IIC Event call back.
+
+/**
+\brief IIC Driver Capabilities.
+*/
+typedef struct {
+ uint32_t address_10_bit : 1; ///< supports 10-bit addressing
+} iic_capabilities_t;
+
+/**
+ \brief Initialize IIC Interface specified by pins. \n
+ 1. Initializes the resources needed for the IIC interface 2.registers event callback function
+ \param[in] scl scl pin of iic.
+ \param[in] sda sda pin of iic.
+ \param[in] cb_event Pointer to \ref iic_event_cb_t
+ \param[in] cb_arg argument for call back function
+ \return 0 for success, negative for error code
+*/
+iic_handle_t csi_iic_initialize(pin_t scl, pin_t sda, iic_event_cb_t cb_event, void *cb_arg);
+
+/**
+ \brief De-initialize IIC Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle iic handle to operate.
+ \return 0 for success, negative for error code
+*/
+int32_t csi_iic_uninitialize(iic_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle iic handle to operate.
+ \return \ref iic_capabilities_t
+*/
+iic_capabilities_t csi_iic_get_capabilities(iic_handle_t handle);
+
+/**
+ \brief config iic attributes.
+ \param[in] handle iic handle to operate.
+ \param[in] mode iic mode \ref iic_mode_e. if negative, then this attribute not changed.
+ \param[in] speed iic speed \ref iic_speed_e. if negative, then this attribute not changed.
+ \param[in] addr_mode iic address mode \ref iic_address_mode_e. if negative, then this attribute not changed.
+ \param[in] slave_addr iic address of slave. if negative, then this attribute not changed.
+ \return 0 for success, negative for error code
+*/
+int32_t csi_iic_config(iic_handle_t handle,
+ iic_mode_e mode,
+ iic_speed_e speed,
+ iic_address_mode_e addr_mode,
+ int32_t slave_addr);
+
+/**
+ \brief Start transmitting data as I2C Master.
+ This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
+ \ref csi_iic_get_status can indicates transmission status.
+ \param[in] handle iic handle to operate.
+ \param[in] data data to send to I2C Slave
+ \param[in] num Number of data items to send
+ \param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
+ \return 0 for success, negative for error code
+*/
+int32_t csi_iic_master_send(iic_handle_t handle, const void *data, uint32_t num, bool xfer_pending);
+
+/**
+ \brief Start receiving data as I2C Master.
+ This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
+ \ref csi_iic_get_status can indicates transmission status.
+ \param[in] handle iic handle to operate.
+ \param[out] data Pointer to buffer for data to receive from IIC receiver
+ \param[in] num Number of data items to receive
+ \param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
+ \return 0 for success, negative for error code
+*/
+int32_t csi_iic_master_receive(iic_handle_t handle, const void *data, uint32_t num, bool xfer_pending);
+
+/**
+ \brief Start transmitting data as I2C Slave.
+ This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
+ \ref csi_iic_get_status can indicates transmission status.
+ \param[in] handle iic handle to operate.
+ \param[in] data Pointer to buffer with data to transmit to I2C Master
+ \param[in] num Number of data items to send
+ \return 0 for success, negative for error code
+*/
+int32_t csi_iic_slave_send(iic_handle_t handle, const void *data, uint32_t num);
+
+/**
+ \brief Start receiving data as I2C Slave.
+ This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
+ \ref csi_iic_get_status can indicates transmission status.
+ \param[in] handle iic handle to operate.
+ \param[out] data Pointer to buffer for data to receive from I2C Master
+ \param[in] num Number of data items to receive
+ \return 0 for success, negative for error code
+*/
+int32_t csi_iic_slave_receive(iic_handle_t handle, const void *data, uint32_t num);
+
+/**
+ \brief abort transfer.
+ \param[in] handle iic handle to operate.
+ \return 0 for success, negative for error code
+*/
+int32_t csi_iic_abort_transfer(iic_handle_t handle);
+
+/**
+ \brief Get IIC status.
+ \param[in] handle iic handle to operate.
+ \return IIC status \ref iic_status_t
+*/
+iic_status_t csi_iic_get_status(iic_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_IIC_H_ */
diff --git a/bsp/ck802/libraries/include/drv_pwm.h b/bsp/ck802/libraries/include/drv_pwm.h
new file mode 100644
index 0000000000..9d585429aa
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_pwm.h
@@ -0,0 +1,94 @@
+/*
+ * 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 drv_pwm.h
+ * @brief header file for pwm driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CSI_PWM_H_
+#define _CSI_PWM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_common.h>
+
+
+/// definition for pwm handle.
+typedef void *pwm_handle_t;
+
+/****** PWM specific error codes *****/
+typedef enum {
+ EDRV_PWM_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
+} drv_pwm_error_e;
+
+
+/**
+ \brief Initialize PWM Interface. 1. Initializes the resources needed for the PWM interface 2.registers event callback function
+ \param[in] pwm_pin pin name of pwm
+ \return handle pwm handle to operate.
+*/
+pwm_handle_t drv_pwm_initialize(pin_t pwm_pin);
+
+/**
+ \brief De-initialize PWM Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle pwm handle to operate.
+ \return error code
+*/
+int32_t drv_pwm_uninitialize(pwm_handle_t handle);
+
+/**
+ \brief config pwm mode.
+ \param[in] handle pwm handle to operate.
+ \param[in] sysclk configured system clock.
+ \param[in] period_us the PWM period in us
+ \param[in] duty the PMW duty. ( 0 - 10000 represents 0% - 100% ,other values are invalid)
+ \return error code
+*/
+int32_t drv_pwm_config(pwm_handle_t handle,
+ uint32_t sysclk,
+ uint32_t period_us,
+ uint32_t duty);
+
+/**
+ \brief start generate pwm signal.
+ \param[in] handle pwm handle to operate.
+ \return error code
+*/
+int32_t drv_pwm_start(pwm_handle_t handle);
+
+/**
+ \brief Stop generate pwm signal.
+ \param[in] handle pwm handle to operate.
+ \return error code
+*/
+int32_t drv_pwm_stop(pwm_handle_t handle);
+
+/**
+ \brief Get PWM status.
+ \param[in] handle pwm handle to operate.
+ \return PWM status \ref pwm_status_t
+pwm_status_t drv_pwm_get_status(pwm_handle_t handle);
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_PWM_H_ */
diff --git a/bsp/ck802/libraries/include/drv_rsa.h b/bsp/ck802/libraries/include/drv_rsa.h
new file mode 100644
index 0000000000..2ac8a87a8d
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_rsa.h
@@ -0,0 +1,222 @@
+/*
+ * 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 drv_rsa.h
+ * @brief header file for rsa driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CSI_RSA_H_
+#define _CSI_RSA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_common.h>
+
+
+/// definition for rsa handle.
+typedef void *rsa_handle_t;
+
+/****** RSA specific error codes *****/
+typedef enum {
+ RSA_ERROR_DATA_BITS , ///< Specified number of Data bits not supported
+ RSA_ERROR_ENDIAN ///< Specified endian not supported
+} drv_rsa_error_e;
+
+/*----- RSA Control Codes: Mode Parameters: Data Bits -----*/
+typedef enum {
+ RSA_DATA_BITS_192 = 0, ///< 192 Data bits
+ RSA_DATA_BITS_256 , ///< 256 Data bits
+ RSA_DATA_BITS_512 , ///< 512 Data bits
+ RSA_DATA_BITS_1024 , ///< 1024 Data bits (default)
+ RSA_DATA_BITS_2048 ///< 2048 Data bits
+} rsa_data_bits_e;
+
+/*----- RSA Control Codes: Mode Parameters: Endian -----*/
+typedef enum {
+ RSA_ENDIAN_MODE_LITTLE = 0, ///< RSA Little Endian Mode
+ RSA_ENDIAN_MODE_BIG ///< RSA Big Endian Mode
+} rsa_endian_mode_e;
+
+typedef enum {
+ RSA_PADDING_MODE_PKCS1 = 1, ///< RSA PKCS1 Padding Mode
+ RSA_PADDING_MODE_NO , ///< RSA NO Padding Mode
+ RSA_PADDING_MODE_SSLV23 , ///< RSA SSLV23 Padding Mode
+ RSA_PADDING_MODE_PKCS1_OAEP , ///< RSA PKCS1 OAEP Padding Mode
+ RSA_PADDING_MODE_X931 , ///< RSA X931 Padding Mode
+ RSA_PADDING_MODE_PSS ///< RSA PSS Padding Mode
+} rsa_padding_type_e;
+
+typedef enum {
+ RSA_HASH_TYPE_MD5 = 0,
+ RSA_HASH_TYPE_SHA1 ,
+ RSA_HASH_TYPE_SHA224 ,
+ RSA_HASH_TYPE_SHA256 ,
+ RSA_HASH_TYPE_SHA384 ,
+ RSA_HASH_TYPE_SHA512
+} rsa_hash_type_e;
+
+/*----- RSA Control Codes: Mode Parameters: Padding mode -----*/
+typedef struct {
+ rsa_padding_type_e padding_type;
+ rsa_hash_type_e hash_type;
+} rsa_padding_t;
+
+/**
+\brief RSA Status
+*/
+typedef struct {
+ uint32_t busy : 1; ///< Calculate busy flag
+} rsa_status_t;
+
+/****** RSA Event *****/
+typedef enum {
+ RSA_EVENT_ENCRYPT_COMPLETE = 0, ///< Encrypt completed
+ RSA_EVENT_DECRYPT_COMPLETE , ///< Decrypt completed
+ RSA_EVENT_SIGN_COMPLETE , ///< Sign completed
+ RSA_EVENT_VERIFY_COMPLETE , ///< Verify completed
+} rsa_event_e;
+
+typedef void (*rsa_event_cb_t)(rsa_event_e event); ///< Pointer to \ref rsa_event_cb_t : RSA Event call back.
+
+
+/**
+\brief RSA Device Driver Capabilities.
+*/
+typedef struct {
+ uint32_t bits_192 : 1; ///< supports 192bits modular length
+ uint32_t bits_256 : 1; ///< supports 256bits modular length
+ uint32_t bits_512 : 1; ///< supports 512bits modular length
+ uint32_t bits_1024 : 1; ///< supports 1024bits modular length
+ uint32_t bits_2048 : 1; ///< supports 2048bits modular length
+} rsa_capabilities_t;
+
+
+// Function documentation
+
+/**
+ \brief get rsa handle count.
+ \return rsa handle count
+*/
+int32_t csi_rsa_get_instance_count(void);
+
+/**
+ \brief Initialize RSA Interface. 1. Initializes the resources needed for the RSA interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_rsa_get_instance_count()
+ \param[in] cb_event Pointer to \ref rsa_event_cb_t
+ \return pointer to rsa handle
+*/
+rsa_handle_t csi_rsa_initialize(int32_t idx, rsa_event_cb_t cb_event);
+
+/**
+ \brief De-initialize RSA Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle rsa handle to operate.
+ \return error code
+*/
+int32_t csi_rsa_uninitialize(rsa_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle rsa handle to operate.
+ \return \ref rsa_capabilities_t
+*/
+rsa_capabilities_t csi_rsa_get_capabilities(rsa_handle_t handle);
+
+/**
+ \brief config rsa mode.
+ \param[in] handle rsa handle to operate.
+ \param[in] data_bits \ref rsa_data_bits_e
+ \param[in] endian \ref rsa_endian_mode_e
+ \return error code
+*/
+int32_t csi_rsa_config(rsa_handle_t handle,
+ rsa_data_bits_e data_bits,
+ rsa_endian_mode_e endian
+ );
+
+/**
+ \brief encrypt
+ \param[in] handle rsa handle to operate.
+ \param[in] n Pointer to the public modulus
+ \param[in] e Pointer to the public exponent
+ \param[in] src Pointer to the source data.
+ \param[in] src_size the source data len
+ \param[out] out Pointer to the result buffer
+ \param[out] out_size the result size
+ \param[in] padding \ref rsa_padding_t
+ \return error code
+*/
+int32_t csi_rsa_encrypt(rsa_handle_t handle, void *n, void *e, void *src, int32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding);
+
+
+/**
+ \brief decrypt
+ \param[in] handle rsa handle to operate.
+ \param[in] n Pointer to the public modulus
+ \param[in] d Pointer to the privte exponent
+ \param[in] src Pointer to the source data.
+ \param[in] src_size the source data len
+ \param[out] out Pointer to the result buffer
+ \param[out] out_size the result size
+ \param[in] padding \ref rsa_padding_t
+ \return error code
+*/
+int32_t csi_rsa_decrypt(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding);
+
+/**
+ \brief rsa sign
+ \param[in] handle rsa handle to operate.
+ \param[in] n Pointer to the public modulus
+ \param[in] d Pointer to the privte exponent
+ \param[in] src Pointer to the source data.
+ \param[in] src_size the source data len
+ \param[out] signature Pointer to the signature
+ \param[out] sig_size the signature size
+ \param[in] padding \ref rsa_padding_t
+ \return error code
+*/
+int32_t csi_rsa_sign(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *signature, void *sig_size, rsa_padding_t padding);
+
+/**
+ \brief rsa verify
+ \param[in] handle rsa handle to operate.
+ \param[in] n Pointer to the public modulus
+ \param[in] e Pointer to the public exponent
+ \param[in] src Pointer to the source data.
+ \param[in] src_size the source data len
+ \param[in] signature Pointer to the signature
+ \param[in] sig_size the signature size
+ \param[out] result Pointer to the result
+ \param[in] padding \ref rsa_padding_t
+ \return error code
+*/
+int32_t csi_rsa_verify(rsa_handle_t handle, void *n, void *e, void *src, uint32_t src_size, void *signature, uint32_t sig_size, void *result, rsa_padding_t padding);
+/**
+ \brief Get RSA status.
+ \param[in] handle rsa handle to operate.
+ \return RSA status \ref rsa_status_t
+*/
+rsa_status_t csi_rsa_get_status(rsa_handle_t handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_RSA_H_ */
diff --git a/bsp/ck802/libraries/include/drv_rtc.h b/bsp/ck802/libraries/include/drv_rtc.h
new file mode 100644
index 0000000000..182b3df843
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_rtc.h
@@ -0,0 +1,161 @@
+/*
+ * 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 drv_rtc.h
+ * @brief header file for rtc driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_RTC_H_
+#define _CSI_RTC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_common.h>
+#include <time.h>
+
+/// definition for rtc handle.
+typedef void *rtc_handle_t;
+
+/****** rtc specific error codes *****/
+typedef enum {
+ EDRV_RTC_TIME = (EDRV_SPECIFIC + 1), ///< timer data not supported
+} drv_rtc_error_e;
+
+/**
+\brief RTC Status
+*/
+typedef struct {
+ uint32_t active : 1; ///< rtc is running or not
+} rtc_status_t;
+
+/****** RTC Event *****/
+typedef enum {
+ RTC_EVENT_TIMER_INTRERRUPT = 0 ///< generate interrupt
+} rtc_event_e;
+
+typedef void (*rtc_event_cb_t)(rtc_event_e event); ///< Pointer to \ref rtc_event_cb_t : RTC Event call back.
+
+/**
+\brief RTC Device Driver Capabilities.
+*/
+typedef struct {
+ uint32_t interrupt_mode : 1; ///< supports Interrupt mode
+ uint32_t wrap_mode : 1; ///< supports wrap mode
+} rtc_capabilities_t;
+
+/**
+ \brief get rtc instance count.
+ \return rtc instance count
+*/
+int32_t csi_rtc_get_instance_count(void);
+
+/**
+ \brief Initialize RTC Interface. 1. Initializes the resources needed for the RTC interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_rtc_get_instance_count()
+ \param[in] cb_event Pointer to \ref rtc_event_cb_t
+ \return pointer to rtc instance
+*/
+rtc_handle_t csi_rtc_initialize(int32_t idx, rtc_event_cb_t cb_event);
+
+/**
+ \brief De-initialize RTC Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle rtc handle to operate.
+ \return error code
+*/
+int32_t csi_rtc_uninitialize(rtc_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle rtc handle to operate.
+ \return \ref rtc_capabilities_t
+*/
+rtc_capabilities_t csi_rtc_get_capabilities(rtc_handle_t handle);
+
+/**
+ \brief Set RTC timer.
+ \param[in] handle rtc handle to operate.
+ \param[in] rtctime pointer to rtc time
+ \return error code
+*/
+int32_t csi_rtc_set_time(rtc_handle_t handle, const struct tm *rtctime);
+
+/**
+ \brief Get RTC timer.
+ \param[in] handle rtc handle to operate.
+ \param[in] rtctime pointer to rtc time
+ \return error code
+*/
+int32_t csi_rtc_get_time(rtc_handle_t handle, struct tm *rtctime);
+
+
+
+/**
+ \brief Start RTC timer.
+ \param[in] handle rtc handle to operate.
+ \return error code
+*/
+int32_t csi_rtc_start(rtc_handle_t handle);
+
+/**
+ \brief Stop RTC timer.
+ \param[in] handle rtc handle to operate.
+ \return error code
+*/
+int32_t csi_rtc_stop(rtc_handle_t handle);
+
+/**
+ \brief config rtc mode.
+ \param[in] handle rtc handle to operate.
+ \return error code
+*/
+//int32_t drv_rtc_config (rtc_handle_t handle/*,rtc_mode_e mode*/);
+
+/**
+ \brief Get RTC status.
+ \param[in] handle rtc handle to operate.
+ \return RTC status \ref rtc_status_t
+*/
+rtc_status_t csi_rtc_get_status(rtc_handle_t handle);
+
+/**
+ \brief config RTC timer.
+ \param[in] handle rtc handle to operate.
+ \param[in] rtctime time to wake up
+ \return error code
+*/
+int32_t csi_rtc_timer_config(rtc_handle_t handle, const struct tm *rtctime);
+
+/**
+ \brief disable or enable RTC timer.
+ \param[in] handle rtc handle to operate.
+ \param[in] en set 1 enable for rtc timer
+ \return error code
+*/
+int32_t csi_rtc_timer_enable(rtc_handle_t handle, uint8_t en);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_RTC_H_ */
diff --git a/bsp/ck802/libraries/include/drv_sha.h b/bsp/ck802/libraries/include/drv_sha.h
new file mode 100644
index 0000000000..5620efcf74
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_sha.h
@@ -0,0 +1,172 @@
+/*
+ * 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 drv_sha.h
+ * @brief header file for sha driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CSI_SHA_H_
+#define _CSI_SHA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_common.h>
+#include <drv_errno.h>
+
+
+/// definition for sha handle.
+typedef void *sha_handle_t;
+
+/****** SHA specific error codes *****/
+typedef enum {
+ SHA_ERROR_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
+ SHA_ERROR_ENDIAN ///< Specified endian not supported
+} drv_sha_error_e;
+
+/*----- SHA Control Codes: Mode -----*/
+typedef enum {
+ SHA_MODE_1 = 1, ///< SHA_1 mode
+ SHA_MODE_256 , ///< SHA_256 mode
+ SHA_MODE_224 , ///< SHA_224 mode
+ SHA_MODE_512 , ///< SHA_512 mode
+ SHA_MODE_384 , ///< SHA_384 mode
+ SHA_MODE_512_256 , ///< SHA_512_256 mode
+ SHA_MODE_512_224 ///< SHA_512_224 mode
+} sha_mode_e;
+
+/*----- SHA Control Codes: Mode Parameters: Endian -----*/
+typedef enum {
+ SHA_ENDIAN_MODE_BIG = 0, ///< Big Endian Mode
+ SHA_ENDIAN_MODE_LITTLE , ///< Little Endian Mode
+} sha_endian_mode_e;
+
+/**
+\brief SHA Status
+*/
+typedef struct {
+ uint32_t busy : 1; ///< calculate busy flag
+} sha_status_t;
+
+/****** SHA Event *****/
+typedef enum {
+ SHA_EVENT_COMPLETE = 0 ///< calculate completed
+} sha_event_e;
+
+typedef void (*sha_event_cb_t)(sha_event_e event); ///< Pointer to \ref sha_event_cb_t : SHA Event call back.
+
+
+/**
+\brief SHA Device Driver Capabilities.
+*/
+typedef struct {
+ uint32_t sha1 : 1; ///< supports sha1 mode
+ uint32_t sha224 : 1; ///< supports sha224 mode
+ uint32_t sha256 : 1; ///< supports sha256 mode
+ uint32_t sha384 : 1; ///< supports sha384 mode
+ uint32_t sha512 : 1; ///< supports sha512 mode
+ uint32_t sha512_224 : 1; ///< supports sha512_224 mode
+ uint32_t sha512_256 : 1; ///< supports sha512_256 mode
+ uint32_t endianmode : 1; ///< supports endian mode control
+ uint32_t interruptmode : 1; ///< supports interrupt mode
+} sha_capabilities_t;
+
+
+// Function documentation
+
+/**
+ \brief get sha handle count.
+ \return sha handle count
+*/
+int32_t csi_sha_get_instance_count(void);
+
+/**
+ \brief Initialize SHA Interface. 1. Initializes the resources needed for the SHA interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_sha_get_instance_count()
+ \param[in] cb_event Pointer to \ref sha_event_cb_t
+ \return return sha handle if success
+*/
+sha_handle_t csi_sha_initialize(int32_t idx, sha_event_cb_t cb_event);
+
+/**
+ \brief De-initialize SHA Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle sha handle to operate.
+ \return error code
+*/
+int32_t csi_sha_uninitialize(sha_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle sha handle to operate.
+ \return \ref sha_capabilities_t
+*/
+sha_capabilities_t csi_sha_get_capabilities(sha_handle_t handle);
+
+/**
+ \brief config sha mode.
+ \param[in] handle sha handle to operate.
+ \param[in] mode \ref sha_mode_e
+ \param[in] endian \ref sha_endian_mode_e
+ \return error code
+*/
+int32_t csi_sha_config(sha_handle_t handle,
+ sha_mode_e mode,
+ sha_endian_mode_e endian
+ );
+
+/**
+ \brief start the engine
+ \param[in] handle sha handle to operate.
+ \param[in] context Pointer to the sha context.
+ \return error code
+*/
+int32_t csi_sha_starts(sha_handle_t handle, void *context);
+
+/**
+ \brief updata the engine
+ \param[in] handle sha handle to operate.
+ \param[in] context Pointer to the sha context.
+ \param[in] input Pointer to the Source data
+ \param[in] len the data len
+ \return error code
+*/
+int32_t csi_sha_update(sha_handle_t handle, void *context, const void *input, uint32_t len);
+
+/**
+ \brief finish the engine
+ \param[in] handle sha handle to operate.
+ \param[in] context Pointer to the sha context.
+ \param[out] output Pointer to the dest data
+ \return error code
+*/
+int32_t csi_sha_finish(sha_handle_t handle, void *context, void *output);
+
+/**
+ \brief Get SHA status.
+ \param[in] handle sha handle to operate.
+ \return SHA status \ref sha_status_t
+*/
+sha_status_t csi_sha_get_status(sha_handle_t handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_SHA_H_ */
diff --git a/bsp/ck802/libraries/include/drv_spi.h b/bsp/ck802/libraries/include/drv_spi.h
new file mode 100644
index 0000000000..e6c444414c
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_spi.h
@@ -0,0 +1,240 @@
+/*
+ * 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 drv_spi.h
+ * @brief header file for spi driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_SPI_H_
+#define _CSI_SPI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_common.h>
+#include <config.h>
+#ifdef CONFIG_SPI_DMA
+#include <drv_dmac.h>
+#endif
+
+/// definition for spi handle.
+typedef void *spi_handle_t;
+
+/****** SPI specific error codes *****/
+typedef enum {
+ EDRV_SPI_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
+ EDRV_SPI_FRAME_FORMAT, ///< Specified Frame Format not supported
+ EDRV_SPI_DATA_BITS, ///< Specified number of Data bits not supported
+ EDRV_SPI_BIT_ORDER, ///< Specified Bit order not supported
+ EDRV_SPI_SS_MODE ///< Specified Slave Select Mode not supported
+} drv_spi_err_e;
+
+/*----- SPI Control Codes: Mode -----*/
+typedef enum {
+ SPI_MODE_INACTIVE = 0, ///< SPI Inactive
+ SPI_MODE_MASTER, ///< SPI Master (Output on MOSI, Input on MISO); arg = Bus Speed in bps
+ SPI_MODE_SLAVE, ///< SPI Slave (Output on MISO, Input on MOSI)
+ SPI_MODE_MASTER_SIMPLEX, ///< SPI Master (Output/Input on MOSI); arg = Bus Speed in bps
+ SPI_MODE_SLAVE_SIMPLEX ///< SPI Slave (Output/Input on MISO)
+} spi_mode_e;
+
+/*----- SPI Control Codes: Mode Parameters: Frame Format -----*/
+typedef enum {
+ SPI_FORMAT_CPOL0_CPHA0 = 0, ///< Clock Polarity 0, Clock Phase 0 (default)
+ SPI_FORMAT_CPOL0_CPHA1, ///< Clock Polarity 0, Clock Phase 1
+ SPI_FORMAT_CPOL1_CPHA0, ///< Clock Polarity 1, Clock Phase 0
+ SPI_FORMAT_CPOL1_CPHA1, ///< Clock Polarity 1, Clock Phase 1
+} spi_format_e;
+
+/*----- SPI Control Codes: Mode Parameters: Bit Order -----*/
+typedef enum {
+ SPI_ORDER_MSB2LSB = 0, ///< SPI Bit order from MSB to LSB (default)
+ SPI_ORDER_LSB2MSB ///< SPI Bit order from LSB to MSB
+} spi_bit_order_e;
+
+/*----- SPI Control Codes: Mode Parameters: Data Width in bits -----*/
+#define SPI_DATAWIDTH_MAX 32 /* 1 ~ 32 bit*/
+
+/*----- SPI Control Codes: Mode Parameters: Slave Select Mode -----*/
+typedef enum {
+ /*options for SPI_MODE_MASTER/SPI_MODE_MASTER_SIMPLEX */
+ SPI_SS_MASTER_UNUSED = 0, ///< SPI Slave Select when Master: Not used (default).SS line is not controlled by master, For example,SS line connected to a fixed low level
+ SPI_SS_MASTER_SW, ///< SPI Slave Select when Master: Software controlled. SS line is configured by software
+ SPI_SS_MASTER_HW_OUTPUT, ///< SPI Slave Select when Master: Hardware controlled Output.SS line is activated or deactivated automatically by hardware
+ SPI_SS_MASTER_HW_INPUT, ///< SPI Slave Select when Master: Hardware monitored Input.Used in multi-master configuration where a master does not drive the Slave Select when driving the bus, but rather monitors it
+ /*options for SPI_MODE_SLAVE/SPI_MODE_SLAVE_SIMPLEX */
+ SPI_SS_SLAVE_HW, ///< SPI Slave Select when Slave: Hardware monitored (default).Hardware monitors the Slave Select line and accepts transfers only when the line is active
+ SPI_SS_SLAVE_SW ///< SPI Slave Select when Slave: Software controlled.Used only when the Slave Select line is not used. Software controls if the slave is responding or not(enables or disables transfers)
+} spi_ss_mode_e;
+
+/****** SPI Slave Select Signal definitions *****/
+typedef enum {
+ SPI_SS_INACTIVE = 0, ///< SPI Slave Select Signal/line Inactive
+ SPI_SS_ACTIVE ///< SPI Slave Select Signal/line Active
+} spi_ss_stat_e;
+
+/**
+\brief SPI Status
+*/
+typedef struct {
+ uint32_t busy : 1; ///< Transmitter/Receiver busy flag
+ uint32_t data_lost : 1; ///< Data lost: Receive overflow / Transmit underflow (cleared on start of transfer operation)
+ uint32_t mode_fault : 1; ///< Mode fault detected; optional (cleared on start of transfer operation)
+} spi_status_t;
+
+/****** SPI Event *****/
+typedef enum {
+ SPI_EVENT_TRANSFER_COMPLETE = 0, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation
+ SPI_EVENT_TX_COMPLETE, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation
+ SPI_EVENT_RX_COMPLETE, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation
+ SPI_EVENT_DATA_LOST, ///< Data lost: Receive overflow / Transmit underflow. Occurs in slave mode when data is requested/sent by master but send/receive/transfer operation has not been started and indicates that data is lost. Occurs also in master mode when driver cannot transfer data fast enough.
+ SPI_EVENT_MODE_FAULT ///< Master Mode Fault (SS deactivated when Master).Occurs in master mode when Slave Select is deactivated and indicates Master Mode Fault. The driver is ready for the next transfer operation.
+} spi_event_e;
+
+typedef void (*spi_event_cb_t)(spi_event_e event, void *arg); ///< Pointer to \ref spi_event_cb_t : SPI Event call back.
+
+/**
+\brief SPI Driver Capabilities.
+*/
+typedef struct {
+ uint32_t simplex : 1; ///< supports Simplex Mode (Master and Slave)
+ uint32_t ti_ssi : 1; ///< supports TI Synchronous Serial Interface
+ uint32_t microwire : 1; ///< supports Microwire Interface
+ uint32_t event_mode_fault : 1; ///< Signal Mode Fault event: \ref spi_event_e
+} spi_capabilities_t;
+
+/**
+ \brief Initialize SPI Interface. 1. Initializes the resources needed for the SPI interface 2.registers event callback function
+ \param[in] mosi spi pin of mosi
+ \param[in] miso spi pin of miso
+ \param[in] sclk spi pin of sclk
+ \param[in] ssel spi pin of ssel
+ \param[in] cb_event event call back function \ref spi_event_cb_t
+ \param[in] cb_arg argument for call back function
+ \return return spi handle if success
+*/
+spi_handle_t csi_spi_initialize(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel, spi_event_cb_t cb_event, void *cb_arg);
+
+/**
+ \brief De-initialize SPI Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle spi handle to operate.
+ \return error code
+*/
+int32_t csi_spi_uninitialize(spi_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle spi handle to operate.
+ \return \ref spi_capabilities_t
+*/
+spi_capabilities_t csi_spi_get_capabilities(spi_handle_t handle);
+
+/**
+ \brief config spi mode.
+ \param[in] handle spi handle to operate.
+ \param[in] sysclk sysclk for spi module.
+ \param[in] baud spi baud rate. if negative, then this attribute not changed
+ \param[in] mode \ref spi_mode_e . if negative, then this attribute not changed
+ \param[in] format \ref spi_format_e . if negative, then this attribute not changed
+ \param[in] order \ref spi_bit_order_e . if negative, then this attribute not changed
+ \param[in] ss_mode \ref spi_ss_mode_e . if negative, then this attribute not changed
+ \param[in] bit_width spi data bitwidth: (1 ~ SPI_DATAWIDTH_MAX) . if negative, then this attribute not changed
+ \return error code
+*/
+int32_t csi_spi_config(spi_handle_t handle,
+ int32_t sysclk,
+ int32_t baud,
+ spi_mode_e mode,
+ spi_format_e format,
+ spi_bit_order_e order,
+ spi_ss_mode_e ss_mode,
+ int32_t bit_width);
+
+/**
+ \brief config spi default tx value.
+ \param[in] handle spi handle to operate.
+ \param[in] value default tx value
+ \return error code
+*/
+int32_t csi_spi_set_default_tx_value(spi_handle_t handle, uint32_t value);
+
+/**
+\brief sending data to SPI transmitter,(received data is ignored).
+ if non-blocking mode, this function only start the sending,
+ \ref spi_event_e is signaled when operation completes or error happens.
+ \ref csi_spi_get_status can indicates operation status.
+ if blocking mode, this function return after operation completes or error happens.
+ \param[in] handle spi handle to operate.
+ \param[in] data Pointer to buffer with data to send to SPI transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits,
+ \param[in] num Number of data items to send.
+ \param[in] block_mode blocking and non_blocking to selcect
+ \return error code
+*/
+int32_t csi_spi_send(spi_handle_t handle, const void *data, uint32_t num, uint8_t block_mode);
+
+/**
+ \brief receiving data from SPI receiver.transmits the default value as specified by csi_spi_set_default_tx_value
+ if non-blocking mode, this function only start the receiving,
+ \ref spi_event_e is signaled when operation completes or error happens.
+ \ref csi_spi_get_status can indicates operation status.
+ if blocking mode, this function return after operation completes or error happens.
+ \param[in] handle spi handle to operate.
+ \param[out] data Pointer to buffer for data to receive from SPI receiver
+ \param[in] num Number of data items to receive
+ \param[in] block_mode blocking and non_blocking to selcect
+ \return error code
+*/
+int32_t csi_spi_receive(spi_handle_t handle, void *data, uint32_t num, uint8_t block_mode);
+
+/**
+ \brief sending/receiving data to/from SPI transmitter/receiver.
+ if non-blocking mode, this function only start the transfer,
+ \ref spi_event_e is signaled when operation completes or error happens.
+ \ref csi_spi_get_status can indicates operation status.
+ if blocking mode, this function return after operation completes or error happens.
+ \param[in] handle spi handle to operate.
+ \param[in] data_out Pointer to buffer with data to send to SPI transmitter
+ \param[out] data_in Pointer to buffer for data to receive from SPI receiver
+ \param[in] num_out Number of data items to send
+ \param[in] num_in Number of data items to receive
+ \param[in] block_mode blocking and non_blocking to selcect
+ \return error code
+*/
+int32_t csi_spi_transfer(spi_handle_t handle, const void *data_out, void *data_in, uint32_t num_out, uint32_t num_in, uint8_t block_mode);
+
+/**
+ \brief abort spi transfer.
+ \param[in] handle spi handle to operate.
+ \return error code
+*/
+int32_t csi_spi_abort_transfer(spi_handle_t handle);
+
+/**
+ \brief Get SPI status.
+ \param[in] handle spi handle to operate.
+ \return SPI status \ref spi_status_t
+*/
+spi_status_t csi_spi_get_status(spi_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_SPI_H_ */
diff --git a/bsp/ck802/libraries/include/drv_timer.h b/bsp/ck802/libraries/include/drv_timer.h
new file mode 100644
index 0000000000..c33590ee34
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_timer.h
@@ -0,0 +1,160 @@
+/*
+ * 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 drv_timer.h
+ * @brief header file for timer driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_TIMER_H_
+#define _CSI_TIMER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_common.h>
+
+/// 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)(timer_event_e event, void *arg); ///< Pointer to \ref timer_event_cb_t : TIMER Event call back.
+
+/**
+\brief TIMER Device Driver Capabilities.
+*/
+typedef struct {
+ uint32_t interrupt_mode : 1; ///< supports Interrupt mode
+} timer_capabilities_t;
+
+/**
+ \brief get timer instance count.
+ \return timer instance count
+*/
+int32_t csi_timer_get_instance_count(void);
+
+/**
+ \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
+ \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, void *cb_arg);
+
+/**
+ \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 Get driver capabilities.
+ \param[in] handle timer handle to operate.
+ \return \ref timer_capabilities_t
+*/
+timer_capabilities_t csi_timer_get_capabilities(timer_handle_t handle);
+
+/**
+ \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 timer.
+ \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.
+ \param[in] apbfreq APB frequency
+ \return error code
+*/
+int32_t csi_timer_start(timer_handle_t handle, uint32_t apbfreq);
+
+/**
+ \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[in] 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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_TIMER_H_ */
+
diff --git a/bsp/ck802/libraries/include/drv_trng.h b/bsp/ck802/libraries/include/drv_trng.h
new file mode 100644
index 0000000000..5646c4c768
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_trng.h
@@ -0,0 +1,118 @@
+/*
+ * 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 drv_trng.h
+ * @brief header file for trng driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+#ifndef _CSI_TRNG_H_
+#define _CSI_TRNG_H_
+
+#include "drv_common.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+
+/// definition for trng handle.
+typedef void *trng_handle_t;
+/****** TRNG specific error codes *****/
+typedef enum {
+ TRNG_ERROR_MODE = 0, ///< Specified Mode not supported
+} drv_trng_error_e;
+
+/*----- TRNG Control Codes: Mode -----*/
+typedef enum {
+ TRNG_MODE_LOWPOWER = 0, ///< TRNG Low power Mode
+ TRNG_MODE_NORMAL ///< TRNG Normal Mode
+} trng_mode_e;
+
+/**
+\brief TRNG Status
+*/
+typedef struct {
+ uint32_t busy : 1;
+ uint32_t data_valid : 1; ///< Data is valid flag
+} trng_status_t;
+
+/****** TRNG Event *****/
+typedef enum {
+ TRNG_EVENT_DATA_GENERATE_COMPLETE = 0 ///< Get data from TRNG success
+} trng_event_e;
+typedef void (*trng_event_cb_t)(trng_event_e event); ///< Pointer to \ref trng_event_cb_t : TRNG Event call back.
+
+/**
+\brief TRNG Device Driver Capabilities.
+*/
+typedef struct {
+ uint32_t lowper_mode : 1; ///< supports low power mode
+} trng_capabilities_t;
+
+// Function documentation
+
+/**
+ \brief get trng handle count.
+ \return trng handle count
+*/
+int32_t csi_trng_get_instance_count(void);
+
+/**
+ \brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_trng_get_instance_count()
+ \param[in] cb_event Pointer to \ref trng_event_cb_t
+ \return pointer to trng handle
+*/
+trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event);
+
+/**
+ \brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle trng handle to operate.
+ \return error code
+*/
+int32_t csi_trng_uninitialize(trng_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle trng handle to operate.
+ \return \ref trng_capabilities_t
+*/
+trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle);
+
+/**
+ \brief Get data from the TRNG.
+ \param[in] handle trng handle to operate.
+ \param[out] data Pointer to buffer with data get from TRNG
+ \param[in] num Number of data items to obtain
+ \return error code
+*/
+int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num);
+
+/**
+ \brief Get TRNG status.
+ \param[in] handle trng handle to operate.
+ \return TRNG status \ref trng_status_t
+*/
+trng_status_t csi_trng_get_status(trng_handle_t handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_TRNG_H_ */
diff --git a/bsp/ck802/libraries/include/drv_usart.h b/bsp/ck802/libraries/include/drv_usart.h
new file mode 100644
index 0000000000..b41aac90a2
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_usart.h
@@ -0,0 +1,282 @@
+/*
+ * 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 drv_usart.h
+ * @brief header file for usart driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_USART_H_
+#define _CSI_USART_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <drv_common.h>
+
+/// definition for usart handle.
+typedef void *usart_handle_t;
+
+/****** USART specific error codes *****/
+typedef enum {
+ EDRV_USART_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
+ EDRV_USART_BAUDRATE, ///< Specified baudrate not supported
+ EDRV_USART_DATA_BITS, ///< Specified number of Data bits not supported
+ EDRV_USART_PARITY, ///< Specified Parity not supported
+ EDRV_USART_STOP_BITS, ///< Specified number of Stop bits not supported
+ EDRV_USART_FLOW_CONTROL, ///< Specified Flow Control not supported
+ EDRV_USART_CPOL, ///< Specified Clock Polarity not supported
+ EDRV_USART_CPHA ///< Specified Clock Phase not supported
+} drv_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_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)
+ USART_CPOL1 ///< CPOL = 1
+} usart_cpol_e;
+
+/*----- USART Control Codes: Mode Parameters: Clock Phase (Synchronous mode) -----*/
+typedef enum {
+ USART_CPHA0 = 0, ///< CPHA = 0 (default)
+ USART_CPHA1 ///< CPHA = 1
+} usart_cpha_e;
+
+/*----- USART Control Codes: flush data type-----*/
+typedef enum {
+ USART_FLUSH_WRITE,
+ USART_FLUSH_READ
+} usart_flush_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)
+} 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_RECEIVED = 2, ///< Receiving data
+ USART_EVENT_TRANSFER_COMPLETE = 3, ///< Transfer completed
+ USART_EVENT_TX_COMPLETE = 4, ///< Transmit completed (optional)
+ USART_EVENT_TX_UNDERFLOW = 5, ///< Transmit data not available (Synchronous Slave)
+ USART_EVENT_RX_OVERFLOW = 6, ///< Receive data overflow
+ USART_EVENT_RX_TIMEOUT = 7, ///< Receive character timeout (optional)
+ USART_EVENT_RX_BREAK = 8, ///< Break detected on receive
+ USART_EVENT_RX_FRAMING_ERROR = 9, ///< Framing error detected on receive
+ USART_EVENT_RX_PARITY_ERROR = 10, ///< Parity error detected on receive
+} usart_event_e;
+
+typedef void (*usart_event_cb_t)(usart_event_e event, void *cb_arg); ///< Pointer to \ref usart_event_cb_t : USART Event call back.
+
+/**
+\brief USART Driver Capabilities.
+*/
+typedef struct {
+ uint32_t asynchronous : 1; ///< supports USART (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 USART Single-wire mode
+ uint32_t event_tx_complete : 1; ///< Transmit completed event
+ uint32_t event_rx_timeout : 1; ///< Signal receive character timeout event
+} usart_capabilities_t;
+
+/**
+ \brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
+ \param[in] tx usart pin of tx
+ \param[in] rx usart pin of rx
+ \param[in] cb_event Pointer to \ref usart_event_cb_t
+ \param[in] cb_arg argument for cb_event
+ \return return usart handle if success
+*/
+usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg);
+
+/**
+ \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] handle usart handle to operate.
+ \return \ref usart_capabilities_t
+*/
+usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle);
+
+/**
+ \brief config usart mode.
+ \param[in] handle usart handle to operate.
+ \param[in] sysclk system clock.
+ \param[in] baud configured baud .
+ \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 sysclk,
+ uint32_t baud,
+ usart_mode_e mode,
+ usart_parity_e parity,
+ usart_stop_bits_e stopbits,
+ usart_data_bits_e bits);
+
+/**
+ \brief config usart default tx value. used in synchronous mode
+ \param[in] handle usart handle to operate.
+ \param[in] value default tx value
+ \return error code
+*/
+int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value);
+
+/**
+ \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 indicates 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/*,bool asynch*/);
+
+/**
+ \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.transmits the default value as specified by csi_usart_set_default_tx_value. \n
+ This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens.
+ \ref csi_usart_get_status can indicates 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/*,bool asynch*/);
+
+/**
+ \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 receive fifo data num
+*/
+int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num/*,bool asynch*/);
+
+/**
+ \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 indicates 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/*,bool asynch*/);
+
+/**
+ \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);
+
+
+//add function
+int32_t dw_usart_getchar(usart_handle_t handle, uint8_t *ch);
+int32_t dw_usart_getchar_no_poll(usart_handle_t handle, uint8_t *ch);
+int32_t dw_usart_putchar(usart_handle_t handle, uint8_t ch);
+int32_t dw_usart_set_int_flag(usart_handle_t handle,uint32_t flag);
+int32_t dw_usart_clr_int_flag(usart_handle_t handle,uint32_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_USART_H_ */
diff --git a/bsp/ck802/libraries/include/drv_wdt.h b/bsp/ck802/libraries/include/drv_wdt.h
new file mode 100644
index 0000000000..bf69c127c1
--- /dev/null
+++ b/bsp/ck802/libraries/include/drv_wdt.h
@@ -0,0 +1,119 @@
+/*
+ * 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 drv_wdt.h
+ * @brief header file for wdt driver
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_WDT_H_
+#define _CSI_WDT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <drv_common.h>
+
+/// definition for wdt handle.
+typedef void *wdt_handle_t;
+
+/****** WDT Event *****/
+typedef enum {
+ WDT_EVENT_TIMEOUT = 0 ///< generate the interrupt
+} wdt_event_e;
+
+typedef void (*wdt_event_cb_t)(wdt_event_e event); ///< Pointer to \ref wdt_event_cb_t : WDT Event call back.
+
+/**
+\brief WDT Device Driver Capabilities.
+*/
+typedef struct {
+ uint32_t interrupt : 1; ///< supports interrupt
+} wdt_capabilities_t;
+
+/**
+ \brief get wdt instance count.
+ \return wdt instance count
+*/
+int32_t csi_wdt_get_instance_count(void);
+
+/**
+ \brief Initialize WDT Interface. 1. Initializes the resources needed for the WDT interface 2.registers event callback function
+ \param[in] idx must not exceed return value of csi_wdt_get_instance_count()
+ \param[in] cb_event Pointer to \ref wdt_event_cb_t
+ \return pointer to wdt instance
+*/
+wdt_handle_t csi_wdt_initialize(int32_t idx, wdt_event_cb_t cb_event);
+
+/**
+ \brief De-initialize WDT Interface. stops operation and releases the software resources used by the interface
+ \param[in] handle wdt handle to operate.
+ \return error code
+*/
+int32_t csi_wdt_uninitialize(wdt_handle_t handle);
+
+/**
+ \brief Get driver capabilities.
+ \param[in] handle wdt handle to operate.
+ \return \ref wdt_capabilities_t
+*/
+wdt_capabilities_t csi_wdt_get_capabilities(wdt_handle_t handle);
+
+/**
+ \brief Set the WDT value.
+ \param[in] handle wdt handle to operate.
+ \param[in] value the timeout value(ms).
+ \return error code
+*/
+int32_t csi_wdt_set_timeout(wdt_handle_t handle, uint32_t value);
+
+/**
+ \brief Start the WDT.
+ \param[in] handle wdt handle to operate.
+ \return error code
+*/
+int32_t csi_wdt_start(wdt_handle_t handle);
+
+/**
+ \brief Stop the WDT.
+ \param[in] handle wdt handle to operate.
+ \return error code
+*/
+int32_t csi_wdt_stop(wdt_handle_t handle);
+
+/**
+ \brief Restart the WDT.
+ \param[in] handle wdt handle to operate.
+ \return error code
+*/
+int32_t csi_wdt_restart(wdt_handle_t handle);
+
+/**
+ \brief Read the WDT Current value.
+ \param[in] handle wdt handle to operate.
+ \param[in] value Pointer to the Value.
+ \return error code
+*/
+int32_t csi_wdt_read_current_value(wdt_handle_t handle, uint32_t *value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CSI_WDT_H_ */
diff --git a/bsp/ck802/libraries/startup_gcc.S b/bsp/ck802/libraries/startup_gcc.S
new file mode 100644
index 0000000000..07122fcf98
--- /dev/null
+++ b/bsp/ck802/libraries/startup_gcc.S
@@ -0,0 +1,244 @@
+/*
+ * File : startup.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-01-01 Urey first version
+ */
+
+
+#undef VIC_TSPR
+#define VIC_TSPR 0xE000EC10
+
+#ifndef CONFIG_SEPARATE_IRQ_SP
+#define CONFIG_SEPARATE_IRQ_SP 1
+#endif
+
+#ifndef CONFIG_ARCH_INTERRUPTSTACK
+#define CONFIG_ARCH_INTERRUPTSTACK 1024
+#endif
+
+.import SysTick_Handler
+.import PendSV_Handler
+
+ .section .vectors
+ .align 10
+ .globl __Vectors
+ .type __Vectors, @object
+__Vectors:
+ .long Reset_Handler /* 0: Reset Handler */
+
+ .rept 15
+ .long Default_Handler /* 60 0x40 */
+ .endr /* 64 0x40 */
+
+ .long Default_Handler /* 64 0x44 */
+
+ .rept 5
+ .long Default_Handler /* 88 0x58 */
+ .endr /* 92 0x5C */
+
+ .long PendSV_Handler /* 92 0x5C */
+
+ .rept 9
+ .long Default_Handler /* 128 0x80 */
+ .endr
+
+ /* External interrupts */
+ .long GPIOA_IRQHandler /* 32# 0: GPIOA */ /*128 0x80 */
+ .long SysTick_Handler /* 1: System Tick */
+ .long TIMA0_IRQHandler /* 2: TimerA0 */
+ .long TIMA1_IRQHandler /* 3: TimerA1 */
+ .long Default_Handler
+ .long WDT_IRQHandler /* 5: WDT */
+ .long USART0_IRQHandler /* 6: UART0 */
+ .long USART1_IRQHandler /* 0x27 39 7: UART1 */
+ .long USART2_IRQHandler /* 8: UART2 */
+ .long I2C0_IRQHandler /* 9: I2C0 */
+ .long I2C1_IRQHandler /* 10: I2C1 */
+ .long SPI1_IRQHandler /* 11: SPI1 */
+ .long SPI0_IRQHandler /* 12: SPI0 */
+ .long RTC_IRQHandler /* 13: RTC */
+ .long Default_Handler
+ .long Default_Handler
+ .long Default_Handler
+ .long DMAC_IRQHandler /* 17: DMAC */
+ .long Default_Handler
+ .long PWM_IRQHandler /* 19: PWM */
+ .long Default_Handler
+ .long USART3_IRQHandler /* 21: UART3 */
+ .long Default_Handler
+ .long TIMB0_IRQHandler /* 23: TimerB0 */
+ .long TIMB1_IRQHandler /* 24: TimerB1 */
+ .long Default_Handler
+ .long AES_IRQHandler /* 26: AES */
+ .long GPIOB_IRQHandler /* 27: GPIOB */
+ .long Default_Handler
+ .long SHA_IRQHandler /* 29: SHA */
+
+ .size __Vectors, . - __Vectors
+
+ .text
+ .align 1
+_start:
+ .text
+ .align 1
+ .globl Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ /* under normal circumstances, it should not be opened */
+
+#ifndef CONFIG_SYSTEM_SECURE
+ lrw r0, 0x80000000
+ mtcr r0, psr
+#endif
+
+/* Initialize the normal stack pointer from the linker definition. */
+ lrw a1, __StackTop
+ mov sp, a1
+
+/*
+ * The ranges of copy from/to are specified by following symbols
+ * __etext: LMA of start of the section to copy from. Usually end of text
+ * __data_start__: VMA of start of the section to copy to
+ * __data_end__: VMA of end of the section to copy to
+ *
+ * All addresses must be aligned to 4 bytes boundary.
+ */
+ lrw r1, __erodata
+ lrw r2, __data_start__
+ lrw r3, __data_end__
+
+ subu r3, r2
+ cmpnei r3, 0
+ bf .L_loop0_done
+
+.L_loop0:
+ ldw r0, (r1, 0)
+ stw r0, (r2, 0)
+ addi r1, 4
+ addi r2, 4
+ subi r3, 4
+ cmpnei r3, 0
+ bt .L_loop0
+
+.L_loop0_done:
+
+/*
+ * The BSS section is specified by following symbols
+ * __bss_start__: start of the BSS section.
+ * __bss_end__: end of the BSS section.
+ *
+ * Both addresses must be aligned to 4 bytes boundary.
+ */
+ lrw r1, __bss_start__
+ lrw r2, __bss_end__
+
+ movi r0, 0
+
+ subu r2, r1
+ cmpnei r2, 0
+ bf .L_loop1_done
+
+.L_loop1:
+ stw r0, (r1, 0)
+ addi r1, 4
+ subi r2, 4
+ cmpnei r2, 0
+ bt .L_loop1
+.L_loop1_done:
+
+#ifdef CONFIG_SEPARATE_IRQ_SP
+ lrw r0, g_top_irqstack
+ mtcr r0, cr<15, 1>
+
+ mfcr r0, cr<31, 0>
+ bseti r0, 14
+ mtcr r0, cr<31, 0>
+#endif
+
+#ifndef __NO_SYSTEM_INIT
+ bsr SystemInit
+#endif
+
+//#ifndef __NO_BOARD_INIT
+// bsr board_init
+//#endif
+
+//VIC init...
+ lrw r0, VIC_TSPR
+ movi r1, 0xb00
+ stw r1, (r0)
+
+ bsr entry
+
+__exit:
+ bkpt
+ .size Reset_Handler, . - Reset_Handler
+
+ .align 1
+ .weak Default_Handler
+ .type Default_Handler, %function
+Default_Handler:
+ br Default_Handler
+ .size Default_Handler, . - Default_Handler
+
+.section .bss
+
+ .align 2
+ .globl g_intstackalloc
+ .global g_intstackbase
+ .global g_top_irqstack
+g_intstackalloc:
+g_intstackbase:
+ .space CONFIG_ARCH_INTERRUPTSTACK
+g_top_irqstack:
+
+/* 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
+ .set \handler_name, Default_Handler
+ .endm
+
+ def_irq_handler CORET_IRQHandler
+ def_irq_handler TIMA0_IRQHandler
+ def_irq_handler TIMA1_IRQHandler
+ def_irq_handler TIMB0_IRQHandler
+ def_irq_handler TIMB1_IRQHandler
+ def_irq_handler USART0_IRQHandler
+ def_irq_handler USART1_IRQHandler
+ def_irq_handler USART2_IRQHandler
+ def_irq_handler USART3_IRQHandler
+ def_irq_handler GPIOA_IRQHandler
+ def_irq_handler GPIOB_IRQHandler
+ def_irq_handler I2C0_IRQHandler
+ def_irq_handler I2C1_IRQHandler
+ def_irq_handler SPI0_IRQHandler
+ def_irq_handler SPI1_IRQHandler
+ def_irq_handler RTC_IRQHandler
+ def_irq_handler WDT_IRQHandler
+ def_irq_handler PWM_IRQHandler
+ def_irq_handler DMAC_IRQHandler
+ def_irq_handler AES_IRQHandler
+ def_irq_handler SHA_IRQHandler
+
+ .end
+
diff --git a/bsp/ck802/project.cdkproj b/bsp/ck802/project.cdkproj
new file mode 100644
index 0000000000..52563908b8
--- /dev/null
+++ b/bsp/ck802/project.cdkproj
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Project Name="rt-thread" Version="1">
+ <Dependencies Name="Debug"/>
+ <Description/>
+ <Dependencies Name="BuildSet"/>
+ <BuildConfigs>
+ <BuildConfig Name="BuildSet">
+ <Target>
+ <ROMBank Selected="1">
+ <ROM1>
+ <InUse>yes</InUse>
+ <Start>0x10000000</Start>
+ <Size>0x40000</Size>
+ </ROM1>
+ <ROM2>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ </ROM2>
+ <ROM3>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ </ROM3>
+ <ROM4>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ </ROM4>
+ <ROM5>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ </ROM5>
+ </ROMBank>
+ <RAMBank>
+ <RAM1>
+ <InUse>yes</InUse>
+ <Start>0x20000000</Start>
+ <Size>0x18000</Size>
+ <Init>yes</Init>
+ </RAM1>
+ <RAM2>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ <Init>yes</Init>
+ </RAM2>
+ <RAM3>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ <Init>yes</Init>
+ </RAM3>
+ <RAM4>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ <Init>yes</Init>
+ </RAM4>
+ <RAM5>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ <Init>yes</Init>
+ </RAM5>
+ </RAMBank>
+ <CPU>ck802</CPU>
+ <UseMiniLib>yes</UseMiniLib>
+ <Endian>little</Endian>
+ <UseHardFloat>no</UseHardFloat>
+ <UseEnhancedLRW>no</UseEnhancedLRW>
+ </Target>
+ <Output>
+ <OutputName>$(ProjectName)</OutputName>
+ <Type>Executable</Type>
+ <CreateHexFile>yes</CreateHexFile>
+ <Preprocessor>yes</Preprocessor>
+ <Disasm>yes</Disasm>
+ <CallGraph>yes</CallGraph>
+ <Map>yes</Map>
+ </Output>
+ <User>
+ <BeforeCompile>
+ <RunUserProg>no</RunUserProg>
+ <UserProgName/>
+ </BeforeCompile>
+ <BeforeMake>
+ <RunUserProg>no</RunUserProg>
+ <UserProgName/>
+ </BeforeMake>
+ <AfterMake>
+ <RunUserProg>no</RunUserProg>
+ <UserProgName/>
+ </AfterMake>
+ </User>
+ <Compiler>
+ <Define>RT_USING_MINILIBC</Define>
+ <Undefine/>
+ <Optim>None (-O0)</Optim>
+ <DebugLevel>Maximum (-g3)</DebugLevel>
+ <IncludePath>applications;.;drivers;libraries\include;libraries\common\aes;libraries\common\aes;libraries\common\crc;libraries\common\dmac;libraries\common\eflash;libraries\common\gpio;libraries\common\iic;libraries\common\pwm;libraries\common\rsa;libraries\common\rtc;libraries\common\sha;libraries\common\spi;libraries\common\timer;libraries\common\trng;libraries\common\usart;libraries\common\wdt;..\..\include;..\..\libcpu\c-sky\ck802;..\..\libcpu\c-sky\common;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh;..\..\components\libc\compilers\minilibc</IncludePath>
+ <OtherFlags> -c -mistack -ffunction-sections</OtherFlags>
+ <Verbose>no</Verbose>
+ <Ansi>no</Ansi>
+ <Syntax>no</Syntax>
+ <Pedantic>no</Pedantic>
+ <PedanticErr>no</PedanticErr>
+ <InhibitWarn>no</InhibitWarn>
+ <AllWarn>yes</AllWarn>
+ <WarnErr>no</WarnErr>
+ <OneElfS>no</OneElfS>
+ <Fstrict>no</Fstrict>
+ </Compiler>
+ <Asm>
+ <Define>CONFIG_CKCPU_MMU=0</Define>
+ <Undefine/>
+ <IncludePath>applications;.;drivers;libraries\include;libraries\common\aes;libraries\common\aes;libraries\common\crc;libraries\common\dmac;libraries\common\eflash;libraries\common\gpio;libraries\common\iic;libraries\common\pwm;libraries\common\rsa;libraries\common\rtc;libraries\common\sha;libraries\common\spi;libraries\common\timer;libraries\common\trng;libraries\common\usart;libraries\common\wdt;..\..\include;..\..\libcpu\c-sky\ck802;..\..\libcpu\c-sky\common;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh;..\..\components\libc\compilers\minilibc</IncludePath>
+ <OtherFlags/>
+ <DebugLevel>gdwarf2</DebugLevel>
+ </Asm>
+ <Linker>
+ <Garbage>yes</Garbage>
+ <LDFile>$(ProjectPath)\gcc_csky.ld</LDFile>
+ <LibName/>
+ <LibPath/>
+ <OtherFlags/>
+ <AutoLDFile>no</AutoLDFile>
+ </Linker>
+ <Debug>
+ <LoadApplicationAtStartup>yes</LoadApplicationAtStartup>
+ <Connector>ICE</Connector>
+ <StopAt>yes</StopAt>
+ <StopAtText>main</StopAtText>
+ <InitFile/>
+ <AutoRun>no</AutoRun>
+ <ResetType>Hard Reset</ResetType>
+ <SoftResetVal>0</SoftResetVal>
+ <ResetAfterLoad>no</ResetAfterLoad>
+ <ConfigICE>
+ <IP>localhost</IP>
+ <PORT>1025</PORT>
+ <Clock>12000</Clock>
+ <Delay>10</Delay>
+ <DDC>yes</DDC>
+ <TRST>no</TRST>
+ <Connect>Normal</Connect>
+ <ResetType>Soft Reset</ResetType>
+ <SoftResetVal>0</SoftResetVal>
+ <RTOSType>Bare Metal</RTOSType>
+ <DownloadToFlash>no</DownloadToFlash>
+ <ResetAfterConnect>yes</ResetAfterConnect>
+ </ConfigICE>
+ <ConfigSIM>
+ <SIMTarget>soccfg/cskyv2/smart_v3_802_cfg.xml</SIMTarget>
+ <OtherFlags/>
+ <NoGraphic>no</NoGraphic>
+ <Log>yes</Log>
+ </ConfigSIM>
+ </Debug>
+ <Flash>
+ <InitFile/>
+ <Erase>Erase Sectors</Erase>
+ <Algorithms Path=""/>
+ <Program>yes</Program>
+ <Verify>no</Verify>
+ <ResetAndRun>no</ResetAndRun>
+ </Flash>
+ </BuildConfig>
+ </BuildConfigs>
+ <VirtualDirectory Name="Applications">
+ <File Name="applications/main.c"/>
+ </VirtualDirectory>
+ <VirtualDirectory Name="Drivers">
+ <File Name="drivers/board.c"/>
+ <File Name="drivers/board_coretimer.c"/>
+ <File Name="drivers/board_uart.c"/>
+ <File Name="drivers/isr.c"/>
+ <File Name="drivers/pinmux.c"/>
+ <File Name="drivers/system.c"/>
+ </VirtualDirectory>
+ <VirtualDirectory Name="libraries">
+ <File Name="libraries/startup_gcc.S"/>
+ <File Name="libraries/common/aes/ck_aes.c"/>
+ <File Name="libraries/common/crc/ck_crc.c"/>
+ <File Name="libraries/common/dmac/ck_dmac.c"/>
+ <File Name="libraries/common/eflash/ck_eflash.c"/>
+ <File Name="libraries/common/pwm/ck_pwm.c"/>
+ <File Name="libraries/common/rsa/ck_rsa.c"/>
+ <File Name="libraries/common/sha/ck_sha.c"/>
+ <File Name="libraries/common/trng/ck_trng.c"/>
+ <File Name="libraries/common/timer/dw_timer.c"/>
+ <File Name="libraries/common/gpio/dw_gpio.c"/>
+ <File Name="libraries/common/spi/dw_spi.c"/>
+ <File Name="libraries/common/iic/dw_iic.c"/>
+ <File Name="libraries/common/usart/dw_usart.c"/>
+ <File Name="libraries/common/wdt/dw_wdt.c"/>
+ </VirtualDirectory>
+ <VirtualDirectory Name="Kernel">
+ <File Name="../../src/clock.c"/>
+ <File Name="../../src/components.c"/>
+ <File Name="../../src/device.c"/>
+ <File Name="../../src/idle.c"/>
+ <File Name="../../src/ipc.c"/>
+ <File Name="../../src/irq.c"/>
+ <File Name="../../src/kservice.c"/>
+ <File Name="../../src/mem.c"/>
+ <File Name="../../src/mempool.c"/>
+ <File Name="../../src/object.c"/>
+ <File Name="../../src/scheduler.c"/>
+ <File Name="../../src/signal.c"/>
+ <File Name="../../src/thread.c"/>
+ <File Name="../../src/timer.c"/>
+ </VirtualDirectory>
+ <VirtualDirectory Name="CK802">
+ <File Name="../../libcpu/c-sky/ck802/core_ck802.c"/>
+ <File Name="../../libcpu/c-sky/ck802/stack_ck802.c"/>
+ <File Name="../../libcpu/c-sky/ck802/contex_ck802_gcc.S"/>
+ </VirtualDirectory>
+ <VirtualDirectory Name="DeviceDrivers">
+ <File Name="../../components/drivers/misc/pin.c"/>
+ <File Name="../../components/drivers/serial/serial.c"/>
+ <File Name="../../components/drivers/src/completion.c"/>
+ <File Name="../../components/drivers/src/dataqueue.c"/>
+ <File Name="../../components/drivers/src/pipe.c"/>
+ <File Name="../../components/drivers/src/ringbuffer.c"/>
+ <File Name="../../components/drivers/src/waitqueue.c"/>
+ <File Name="../../components/drivers/src/workqueue.c"/>
+ </VirtualDirectory>
+ <VirtualDirectory Name="finsh">
+ <File Name="../../components/finsh/shell.c"/>
+ <File Name="../../components/finsh/symbol.c"/>
+ <File Name="../../components/finsh/cmd.c"/>
+ <File Name="../../components/finsh/msh.c"/>
+ <File Name="../../components/finsh/msh_cmd.c"/>
+ <File Name="../../components/finsh/msh_file.c"/>
+ </VirtualDirectory>
+ <VirtualDirectory Name="libc">
+ <File Name="../../components/libc/compilers/minilibc/ctype.c"/>
+ <File Name="../../components/libc/compilers/minilibc/math.c"/>
+ <File Name="../../components/libc/compilers/minilibc/qsort.c"/>
+ <File Name="../../components/libc/compilers/minilibc/rand.c"/>
+ <File Name="../../components/libc/compilers/minilibc/stdlib.c"/>
+ <File Name="../../components/libc/compilers/minilibc/string.c"/>
+ <File Name="../../components/libc/compilers/minilibc/time.c"/>
+ </VirtualDirectory>
+ <DebugSessions>
+ <watchExpressions/>
+ <memoryExpressions>;;;</memoryExpressions>
+ <statistics>;;MHZ</statistics>
+ </DebugSessions>
+</Project>
diff --git a/bsp/ck802/rtconfig.h b/bsp/ck802/rtconfig.h
new file mode 100644
index 0000000000..3eb48b11f0
--- /dev/null
+++ b/bsp/ck802/rtconfig.h
@@ -0,0 +1,145 @@
+#ifndef RT_CONFIG_H__
+#define RT_CONFIG_H__
+
+/* Automatically generated file; DO NOT EDIT. */
+/* RT-Thread Configuration */
+
+/* RT-Thread Kernel */
+
+#define RT_NAME_MAX 8
+#define RT_ALIGN_SIZE 4
+#define RT_THREAD_PRIORITY_32
+#define RT_THREAD_PRIORITY_MAX 32
+#define RT_TICK_PER_SECOND 100
+#define RT_DEBUG
+#define RT_USING_OVERFLOW_CHECK
+#define RT_DEBUG_INIT 0
+#define RT_DEBUG_THREAD 0
+#define RT_USING_HOOK
+#define IDLE_THREAD_STACK_SIZE 256
+
+/* 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"
+
+/* RT-Thread Components */
+
+#define RT_USING_COMPONENTS_INIT
+#define RT_USING_USER_MAIN
+#define RT_MAIN_THREAD_STACK_SIZE 2048
+
+/* 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 512
+#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_USING_SERIAL
+#define RT_USING_PIN
+
+/* Using USB */
+
+
+/* POSIX layer and C standard library */
+
+
+/* Network stack */
+
+/* light weight TCP/IP stack */
+
+
+/* Modbus master and slave stack */
+
+
+/* VBUS(Virtual Software BUS) */
+
+
+/* Utilities */
+
+
+/* RT-Thread online packages */
+
+/* IoT - internet of things */
+
+
+/* Wi-Fi */
+
+/* Marvell WiFi */
+
+
+/* Wiced WiFi */
+
+
+/* security packages */
+
+
+/* language packages */
+
+
+/* multimedia packages */
+
+
+/* tools packages */
+
+
+/* system packages */
+
+/* RT-Thread GUI Engine */
+
+
+/* peripheral libraries and drivers */
+
+
+/* miscellaneous packages */
+
+
+/* sample package */
+
+
+/* example package: hello */
+
+
+/* Privated Packages of RealThread */
+
+
+/* Network Utilities */
+
+#define RT_USING_UART1
+
+#endif
diff --git a/bsp/ck802/rtconfig.py b/bsp/ck802/rtconfig.py
new file mode 100644
index 0000000000..2c46a92894
--- /dev/null
+++ b/bsp/ck802/rtconfig.py
@@ -0,0 +1,63 @@
+import os
+
+# toolchains options
+ARCH ='c-sky'
+CPU ='ck802'
+CROSS_TOOL ='gcc'
+
+if os.getenv('RTT_CC'):
+ CROSS_TOOL = os.getenv('RTT_CC')
+
+if CROSS_TOOL == 'gcc':
+ PLATFORM = 'gcc'
+ EXEC_PATH = r'F:\c-sky\CSKY\MinGW\csky-abiv2-elf-toolchain\bin'
+ # EXEC_PATH = r'/home/tanek/c-sky/CK802/toolchain/csky-abiv2-elf-tools-x86_64-minilibc-20161211/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 = 'csky-abiv2-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 CPU == 'ck802':
+ DEVICE = ' -mcpu=ck802'
+
+ CFLAGS = DEVICE + ' -DCONFIG_CPU_CK802 -c -g -ffunction-sections -Wall -mistack -mlittle-endian'
+ AFLAGS = ' -c' + DEVICE + ' -EL -x assembler-with-cpp -save-temps=ojb'
+ LFLAGS = DEVICE + ' -EL -Wl,--gc-sections,-Map=rtthread_ck802.map,-cref,-u,Reset_Handler -T gcc_csky.ld'
+ CPATH = ''
+ LPATH = ''
+
+ if BUILD == 'debug':
+ CFLAGS += ' -O0 -gdwarf-2'
+ AFLAGS += ' -gdwarf-2'
+ else:
+ CFLAGS += ' -O2'
+
+ 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'
diff --git a/bsp/ck802/template.cdkproj b/bsp/ck802/template.cdkproj
new file mode 100644
index 0000000000..817ca128c7
--- /dev/null
+++ b/bsp/ck802/template.cdkproj
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Project Name="rt-thread" Version="1">
+ <Dependencies Name="Debug"/>
+ <Description/>
+ <Dependencies Name="BuildSet"/>
+ <BuildConfigs>
+ <BuildConfig Name="BuildSet">
+ <Target>
+ <ROMBank Selected="1">
+ <ROM1>
+ <InUse>yes</InUse>
+ <Start>0x10000000</Start>
+ <Size>0x40000</Size>
+ </ROM1>
+ <ROM2>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ </ROM2>
+ <ROM3>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ </ROM3>
+ <ROM4>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ </ROM4>
+ <ROM5>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ </ROM5>
+ </ROMBank>
+ <RAMBank>
+ <RAM1>
+ <InUse>yes</InUse>
+ <Start>0x20000000</Start>
+ <Size>0x18000</Size>
+ <Init>yes</Init>
+ </RAM1>
+ <RAM2>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ <Init>yes</Init>
+ </RAM2>
+ <RAM3>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ <Init>yes</Init>
+ </RAM3>
+ <RAM4>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ <Init>yes</Init>
+ </RAM4>
+ <RAM5>
+ <InUse>no</InUse>
+ <Start/>
+ <Size/>
+ <Init>yes</Init>
+ </RAM5>
+ </RAMBank>
+ <CPU>ck802</CPU>
+ <UseMiniLib>yes</UseMiniLib>
+ <Endian>little</Endian>
+ <UseHardFloat>no</UseHardFloat>
+ <UseEnhancedLRW>no</UseEnhancedLRW>
+ </Target>
+ <Output>
+ <OutputName>$(ProjectName)</OutputName>
+ <Type>Executable</Type>
+ <CreateHexFile>yes</CreateHexFile>
+ <Preprocessor>yes</Preprocessor>
+ <Disasm>yes</Disasm>
+ <CallGraph>yes</CallGraph>
+ <Map>yes</Map>
+ </Output>
+ <User>
+ <BeforeCompile>
+ <RunUserProg>no</RunUserProg>
+ <UserProgName/>
+ </BeforeCompile>
+ <BeforeMake>
+ <RunUserProg>no</RunUserProg>
+ <UserProgName/>
+ </BeforeMake>
+ <AfterMake>
+ <RunUserProg>no</RunUserProg>
+ <UserProgName/>
+ </AfterMake>
+ </User>
+ <Compiler>
+ <Define/>
+ <Undefine/>
+ <Optim>None (-O0)</Optim>
+ <DebugLevel>Maximum (-g3)</DebugLevel>
+ <IncludePath/>
+ <OtherFlags></OtherFlags>
+ <Verbose>no</Verbose>
+ <Ansi>no</Ansi>
+ <Syntax>no</Syntax>
+ <Pedantic>no</Pedantic>
+ <PedanticErr>no</PedanticErr>
+ <InhibitWarn>no</InhibitWarn>
+ <AllWarn>yes</AllWarn>
+ <WarnErr>no</WarnErr>
+ <OneElfS>no</OneElfS>
+ <Fstrict>no</Fstrict>
+ </Compiler>
+ <Asm>
+ <Define>CONFIG_CKCPU_MMU=0</Define>
+ <Undefine/>
+ <IncludePath></IncludePath>
+ <OtherFlags/>
+ <DebugLevel>gdwarf2</DebugLevel>
+ </Asm>
+ <Linker>
+ <Garbage>yes</Garbage>
+ <LDFile>$(ProjectPath)\gcc_csky.ld</LDFile>
+ <LibName/>
+ <LibPath/>
+ <OtherFlags/>
+ <AutoLDFile>no</AutoLDFile>
+ </Linker>
+ <Debug>
+ <LoadApplicationAtStartup>yes</LoadApplicationAtStartup>
+ <Connector>ICE</Connector>
+ <StopAt>yes</StopAt>
+ <StopAtText>main</StopAtText>
+ <InitFile/>
+ <AutoRun>no</AutoRun>
+ <ResetType>Hard Reset</ResetType>
+ <SoftResetVal>0</SoftResetVal>
+ <ResetAfterLoad>no</ResetAfterLoad>
+ <ConfigICE>
+ <IP>localhost</IP>
+ <PORT>1025</PORT>
+ <Clock>12000</Clock>
+ <Delay>10</Delay>
+ <DDC>yes</DDC>
+ <TRST>no</TRST>
+ <Connect>Normal</Connect>
+ <ResetType>Soft Reset</ResetType>
+ <SoftResetVal>0</SoftResetVal>
+ <RTOSType>Bare Metal</RTOSType>
+ <DownloadToFlash>no</DownloadToFlash>
+ <ResetAfterConnect>yes</ResetAfterConnect>
+ </ConfigICE>
+ <ConfigSIM>
+ <SIMTarget>soccfg/cskyv2/smart_v3_802_cfg.xml</SIMTarget>
+ <OtherFlags/>
+ <NoGraphic>no</NoGraphic>
+ <Log>yes</Log>
+ </ConfigSIM>
+ </Debug>
+ <Flash>
+ <InitFile/>
+ <Erase>Erase Sectors</Erase>
+ <Algorithms Path=""/>
+ <Program>yes</Program>
+ <Verify>no</Verify>
+ <ResetAndRun>no</ResetAndRun>
+ </Flash>
+ </BuildConfig>
+ </BuildConfigs>
+ <DebugSessions>
+ <watchExpressions/>
+ <memoryExpressions>;;;</memoryExpressions>
+ <statistics>;;MHZ</statistics>
+ </DebugSessions>
+</Project>