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 + +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 +#include + +#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 +#include + +#include "board.h" +#include "board_coretimer.h" + +#include + +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 + +#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 + +#ifdef RT_USING_CONSOLE + +#include +#include + +#include +#include +#include +#include + +#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 +#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 +#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 +#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 +#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 +#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; curstatus.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 +#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 +#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 +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef CONFIG_KERNEL_NONE +#include +#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 + +#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 + +/* ****** 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 +#include +#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 +#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 +#include +#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 +#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 +#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, ¤t_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 +#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 +#include +#include +#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 +#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 +#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 +#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 +#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 +#include +#include +#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 +#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 +#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 +#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 +#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 +#include +#include + + +/// 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 +#include +#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 +#include +#include + + +/****** 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 +#include + +/// 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 +#include + + +/// 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 + +#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 +#include +#include +#include + +/// 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 +#include +#include + +/// 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 +#include + + +/// 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 +#include + + +/// 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 +#include +#include + +/// 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 +#include +#include + + +/// 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 +#include +#include +#ifdef CONFIG_SPI_DMA +#include +#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 +#include + +/// 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 + + +/// 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 + +/// 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 +#include + +/// 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 @@ + + + + + + + + + + + yes + 0x10000000 + 0x40000 + + + no + + + + + no + + + + + no + + + + + no + + + + + + + yes + 0x20000000 + 0x18000 + yes + + + no + + + yes + + + no + + + yes + + + no + + + yes + + + no + + + yes + + + ck802 + yes + little + no + no + + + $(ProjectName) + Executable + yes + yes + yes + yes + yes + + + + no + + + + no + + + + no + + + + + RT_USING_MINILIBC + + None (-O0) + Maximum (-g3) + 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 + -c -mistack -ffunction-sections + no + no + no + no + no + no + yes + no + no + no + + + CONFIG_CKCPU_MMU=0 + + 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 + + gdwarf2 + + + yes + $(ProjectPath)\gcc_csky.ld + + + + no + + + yes + ICE + yes + main + + no + Hard Reset + 0 + no + + localhost + 1025 + 12000 + 10 + yes + no + Normal + Soft Reset + 0 + Bare Metal + no + yes + + + soccfg/cskyv2/smart_v3_802_cfg.xml + + no + yes + + + + + Erase Sectors + + yes + no + no + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ;;; + ;;MHZ + + 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 @@ + + + + + + + + + + + yes + 0x10000000 + 0x40000 + + + no + + + + + no + + + + + no + + + + + no + + + + + + + yes + 0x20000000 + 0x18000 + yes + + + no + + + yes + + + no + + + yes + + + no + + + yes + + + no + + + yes + + + ck802 + yes + little + no + no + + + $(ProjectName) + Executable + yes + yes + yes + yes + yes + + + + no + + + + no + + + + no + + + + + + + None (-O0) + Maximum (-g3) + + + no + no + no + no + no + no + yes + no + no + no + + + CONFIG_CKCPU_MMU=0 + + + + gdwarf2 + + + yes + $(ProjectPath)\gcc_csky.ld + + + + no + + + yes + ICE + yes + main + + no + Hard Reset + 0 + no + + localhost + 1025 + 12000 + 10 + yes + no + Normal + Soft Reset + 0 + Bare Metal + no + yes + + + soccfg/cskyv2/smart_v3_802_cfg.xml + + no + yes + + + + + Erase Sectors + + yes + no + no + + + + + + ;;; + ;;MHZ + + diff --git a/bsp/lpc54608-LPCXpresso/project.uvoptx b/bsp/lpc54608-LPCXpresso/project.uvoptx index f6c0cc3fdd..568861960e 100644 --- a/bsp/lpc54608-LPCXpresso/project.uvoptx +++ b/bsp/lpc54608-LPCXpresso/project.uvoptx @@ -101,7 +101,9 @@ 0 0 1 - 2 + 0 + 0 + 3 @@ -178,4 +180,2340 @@ + + Libraries + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/sdmmc_2.1.2/src/fsl_sd.c + fsl_sd.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/sdmmc_2.1.2/src/fsl_sdmmc.c + fsl_sdmmc.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/sdmmc_2.1.2/src/fsl_host.c + fsl_host.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/sdmmc_2.1.2/src/fsl_sd_event.c + fsl_sd_event.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_adc.c + fsl_adc.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_clock.c + fsl_clock.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_common.c + fsl_common.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_crc.c + fsl_crc.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_ctimer.c + fsl_ctimer.c + 0 + 0 + + + 1 + 10 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_dma.c + fsl_dma.c + 0 + 0 + + + 1 + 11 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_dmic.c + fsl_dmic.c + 0 + 0 + + + 1 + 12 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_dmic_dma.c + fsl_dmic_dma.c + 0 + 0 + + + 1 + 13 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_eeprom.c + fsl_eeprom.c + 0 + 0 + + + 1 + 14 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_emc.c + fsl_emc.c + 0 + 0 + + + 1 + 15 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_enet.c + fsl_enet.c + 0 + 0 + + + 1 + 16 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_flashiap.c + fsl_flashiap.c + 0 + 0 + + + 1 + 17 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_flexcomm.c + fsl_flexcomm.c + 0 + 0 + + + 1 + 18 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_fmc.c + fsl_fmc.c + 0 + 0 + + + 1 + 19 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_fmeas.c + fsl_fmeas.c + 0 + 0 + + + 1 + 20 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_gint.c + fsl_gint.c + 0 + 0 + + + 1 + 21 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_gpio.c + fsl_gpio.c + 0 + 0 + + + 1 + 22 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_i2c.c + fsl_i2c.c + 0 + 0 + + + 1 + 23 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_i2c_dma.c + fsl_i2c_dma.c + 0 + 0 + + + 1 + 24 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_i2s.c + fsl_i2s.c + 0 + 0 + + + 1 + 25 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_i2s_dma.c + fsl_i2s_dma.c + 0 + 0 + + + 1 + 26 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_inputmux.c + fsl_inputmux.c + 0 + 0 + + + 1 + 27 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_lcdc.c + fsl_lcdc.c + 0 + 0 + + + 1 + 28 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_mcan.c + fsl_mcan.c + 0 + 0 + + + 1 + 29 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_mrt.c + fsl_mrt.c + 0 + 0 + + + 1 + 30 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_pint.c + fsl_pint.c + 0 + 0 + + + 1 + 31 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_power.c + fsl_power.c + 0 + 0 + + + 1 + 32 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_reset.c + fsl_reset.c + 0 + 0 + + + 1 + 33 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_rit.c + fsl_rit.c + 0 + 0 + + + 1 + 34 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_rtc.c + fsl_rtc.c + 0 + 0 + + + 1 + 35 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_sctimer.c + fsl_sctimer.c + 0 + 0 + + + 1 + 36 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_sdif.c + fsl_sdif.c + 0 + 0 + + + 1 + 37 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_spi.c + fsl_spi.c + 0 + 0 + + + 1 + 38 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_spi_dma.c + fsl_spi_dma.c + 0 + 0 + + + 1 + 39 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_spifi.c + fsl_spifi.c + 0 + 0 + + + 1 + 40 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_spifi_dma.c + fsl_spifi_dma.c + 0 + 0 + + + 1 + 41 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_usart.c + fsl_usart.c + 0 + 0 + + + 1 + 42 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_usart_dma.c + fsl_usart_dma.c + 0 + 0 + + + 1 + 43 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_utick.c + fsl_utick.c + 0 + 0 + + + 1 + 44 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_wwdt.c + fsl_wwdt.c + 0 + 0 + + + + + CMSIS + 0 + 0 + 0 + 0 + + 2 + 45 + 2 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/arm/startup_LPC54608.s + startup_LPC54608.s + 0 + 0 + + + 2 + 46 + 1 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/system_LPC54608.c + system_LPC54608.c + 0 + 0 + + + 2 + 47 + 4 + 0 + 0 + 0 + SDK_2.2_LPCXpresso54608/devices/LPC54608/arm/keil_lib_power.lib + keil_lib_power.lib + 0 + 0 + + + + + Drivers + 0 + 0 + 0 + 0 + + 3 + 48 + 1 + 0 + 0 + 0 + drivers/board.c + board.c + 0 + 0 + + + 3 + 49 + 1 + 0 + 0 + 0 + drivers/clock_config.c + clock_config.c + 0 + 0 + + + 3 + 50 + 1 + 0 + 0 + 0 + drivers/drt_mpu.c + drt_mpu.c + 0 + 0 + + + 3 + 51 + 1 + 0 + 0 + 0 + drivers/drv_emac.c + drv_emac.c + 0 + 0 + + + 3 + 52 + 1 + 0 + 0 + 0 + drivers/drv_ft5406.c + drv_ft5406.c + 0 + 0 + + + 3 + 53 + 1 + 0 + 0 + 0 + drivers/drv_i2c.c + drv_i2c.c + 0 + 0 + + + 3 + 54 + 1 + 0 + 0 + 0 + drivers/drv_lcd.c + drv_lcd.c + 0 + 0 + + + 3 + 55 + 1 + 0 + 0 + 0 + drivers/drv_sd.c + drv_sd.c + 0 + 0 + + + 3 + 56 + 1 + 0 + 0 + 0 + drivers/drv_sdram.c + drv_sdram.c + 0 + 0 + + + 3 + 57 + 1 + 0 + 0 + 0 + drivers/drv_sram.c + drv_sram.c + 0 + 0 + + + 3 + 58 + 1 + 0 + 0 + 0 + drivers/drv_uart.c + drv_uart.c + 0 + 0 + + + 3 + 59 + 1 + 0 + 0 + 0 + drivers/fsl_phy.c + fsl_phy.c + 0 + 0 + + + + + Applications + 1 + 0 + 0 + 0 + + 4 + 60 + 1 + 0 + 0 + 0 + applications/application.c + application.c + 0 + 0 + + + 4 + 61 + 1 + 0 + 0 + 0 + applications/mnt.c + mnt.c + 0 + 0 + + + 4 + 62 + 1 + 0 + 0 + 0 + applications/startup.c + startup.c + 0 + 0 + + + + + Kernel + 1 + 0 + 0 + 0 + + 5 + 63 + 1 + 0 + 0 + 0 + ../../src/clock.c + clock.c + 0 + 0 + + + 5 + 64 + 1 + 0 + 0 + 0 + ../../src/components.c + components.c + 0 + 0 + + + 5 + 65 + 1 + 0 + 0 + 0 + ../../src/device.c + device.c + 0 + 0 + + + 5 + 66 + 1 + 0 + 0 + 0 + ../../src/idle.c + idle.c + 0 + 0 + + + 5 + 67 + 1 + 0 + 0 + 0 + ../../src/ipc.c + ipc.c + 0 + 0 + + + 5 + 68 + 1 + 0 + 0 + 0 + ../../src/irq.c + irq.c + 0 + 0 + + + 5 + 69 + 1 + 0 + 0 + 0 + ../../src/kservice.c + kservice.c + 0 + 0 + + + 5 + 70 + 1 + 0 + 0 + 0 + ../../src/mem.c + mem.c + 0 + 0 + + + 5 + 71 + 1 + 0 + 0 + 0 + ../../src/memheap.c + memheap.c + 0 + 0 + + + 5 + 72 + 1 + 0 + 0 + 0 + ../../src/mempool.c + mempool.c + 0 + 0 + + + 5 + 73 + 1 + 0 + 0 + 0 + ../../src/module.c + module.c + 0 + 0 + + + 5 + 74 + 1 + 0 + 0 + 0 + ../../src/object.c + object.c + 0 + 0 + + + 5 + 75 + 1 + 0 + 0 + 0 + ../../src/scheduler.c + scheduler.c + 0 + 0 + + + 5 + 76 + 1 + 0 + 0 + 0 + ../../src/signal.c + signal.c + 0 + 0 + + + 5 + 77 + 1 + 0 + 0 + 0 + ../../src/thread.c + thread.c + 0 + 0 + + + 5 + 78 + 1 + 0 + 0 + 0 + ../../src/timer.c + timer.c + 0 + 0 + + + + + CORTEX-M4 + 0 + 0 + 0 + 0 + + 6 + 79 + 1 + 0 + 0 + 0 + ../../libcpu/arm/cortex-m4/cpuport.c + cpuport.c + 0 + 0 + + + 6 + 80 + 2 + 0 + 0 + 0 + ../../libcpu/arm/cortex-m4/context_rvds.S + context_rvds.S + 0 + 0 + + + 6 + 81 + 1 + 0 + 0 + 0 + ../../libcpu/arm/common/backtrace.c + backtrace.c + 0 + 0 + + + 6 + 82 + 1 + 0 + 0 + 0 + ../../libcpu/arm/common/div0.c + div0.c + 0 + 0 + + + 6 + 83 + 1 + 0 + 0 + 0 + ../../libcpu/arm/common/showmem.c + showmem.c + 0 + 0 + + + + + CPlusPlus + 0 + 0 + 0 + 0 + + 7 + 84 + 8 + 0 + 0 + 0 + ../../components/cplusplus/Mutex.cpp + Mutex.cpp + 0 + 0 + + + 7 + 85 + 8 + 0 + 0 + 0 + ../../components/cplusplus/Semaphore.cpp + Semaphore.cpp + 0 + 0 + + + 7 + 86 + 8 + 0 + 0 + 0 + ../../components/cplusplus/Thread.cpp + Thread.cpp + 0 + 0 + + + 7 + 87 + 8 + 0 + 0 + 0 + ../../components/cplusplus/crt.cpp + crt.cpp + 0 + 0 + + + 7 + 88 + 1 + 0 + 0 + 0 + ../../components/cplusplus/crt_init.c + crt_init.c + 0 + 0 + + + + + DeviceDrivers + 0 + 0 + 0 + 0 + + 8 + 89 + 1 + 0 + 0 + 0 + ../../components/drivers/misc/pin.c + pin.c + 0 + 0 + + + 8 + 90 + 1 + 0 + 0 + 0 + ../../components/drivers/i2c/i2c_core.c + i2c_core.c + 0 + 0 + + + 8 + 91 + 1 + 0 + 0 + 0 + ../../components/drivers/i2c/i2c_dev.c + i2c_dev.c + 0 + 0 + + + 8 + 92 + 1 + 0 + 0 + 0 + ../../components/drivers/i2c/i2c-bit-ops.c + i2c-bit-ops.c + 0 + 0 + + + 8 + 93 + 1 + 0 + 0 + 0 + ../../components/drivers/sdio/block_dev.c + block_dev.c + 0 + 0 + + + 8 + 94 + 1 + 0 + 0 + 0 + ../../components/drivers/sdio/mmcsd_core.c + mmcsd_core.c + 0 + 0 + + + 8 + 95 + 1 + 0 + 0 + 0 + ../../components/drivers/sdio/sd.c + sd.c + 0 + 0 + + + 8 + 96 + 1 + 0 + 0 + 0 + ../../components/drivers/sdio/sdio.c + sdio.c + 0 + 0 + + + 8 + 97 + 1 + 0 + 0 + 0 + ../../components/drivers/sdio/mmc.c + mmc.c + 0 + 0 + + + 8 + 98 + 1 + 0 + 0 + 0 + ../../components/drivers/serial/serial.c + serial.c + 0 + 0 + + + 8 + 99 + 1 + 0 + 0 + 0 + ../../components/drivers/rtc/rtc.c + rtc.c + 0 + 0 + + + 8 + 100 + 1 + 0 + 0 + 0 + ../../components/drivers/mtd/mtd_nand.c + mtd_nand.c + 0 + 0 + + + 8 + 101 + 1 + 0 + 0 + 0 + ../../components/drivers/spi/spi_core.c + spi_core.c + 0 + 0 + + + 8 + 102 + 1 + 0 + 0 + 0 + ../../components/drivers/spi/spi_dev.c + spi_dev.c + 0 + 0 + + + 8 + 103 + 1 + 0 + 0 + 0 + ../../components/drivers/spi/enc28j60.c + enc28j60.c + 0 + 0 + + + 8 + 104 + 1 + 0 + 0 + 0 + ../../components/drivers/src/completion.c + completion.c + 0 + 0 + + + 8 + 105 + 1 + 0 + 0 + 0 + ../../components/drivers/src/dataqueue.c + dataqueue.c + 0 + 0 + + + 8 + 106 + 1 + 0 + 0 + 0 + ../../components/drivers/src/pipe.c + pipe.c + 0 + 0 + + + 8 + 107 + 1 + 0 + 0 + 0 + ../../components/drivers/src/ringbuffer.c + ringbuffer.c + 0 + 0 + + + 8 + 108 + 1 + 0 + 0 + 0 + ../../components/drivers/src/waitqueue.c + waitqueue.c + 0 + 0 + + + 8 + 109 + 1 + 0 + 0 + 0 + ../../components/drivers/src/workqueue.c + workqueue.c + 0 + 0 + + + + + pthreads + 0 + 0 + 0 + 0 + + 9 + 110 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/mqueue.c + mqueue.c + 0 + 0 + + + 9 + 111 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/pthread.c + pthread.c + 0 + 0 + + + 9 + 112 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/pthread_attr.c + pthread_attr.c + 0 + 0 + + + 9 + 113 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/pthread_barrier.c + pthread_barrier.c + 0 + 0 + + + 9 + 114 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/pthread_cond.c + pthread_cond.c + 0 + 0 + + + 9 + 115 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/pthread_mutex.c + pthread_mutex.c + 0 + 0 + + + 9 + 116 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/pthread_rwlock.c + pthread_rwlock.c + 0 + 0 + + + 9 + 117 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/pthread_spin.c + pthread_spin.c + 0 + 0 + + + 9 + 118 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/pthread_tls.c + pthread_tls.c + 0 + 0 + + + 9 + 119 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/sched.c + sched.c + 0 + 0 + + + 9 + 120 + 1 + 0 + 0 + 0 + ../../components/libc/pthreads/semaphore.c + semaphore.c + 0 + 0 + + + 9 + 121 + 1 + 0 + 0 + 0 + ../../components/libc/time/clock_time.c + clock_time.c + 0 + 0 + + + 9 + 122 + 1 + 0 + 0 + 0 + ../../components/libc/time/posix_sleep.c + posix_sleep.c + 0 + 0 + + + + + libc + 0 + 0 + 0 + 0 + + 10 + 123 + 1 + 0 + 0 + 0 + ../../components/libc/compilers/armlibc/libc.c + libc.c + 0 + 0 + + + 10 + 124 + 1 + 0 + 0 + 0 + ../../components/libc/compilers/armlibc/libc_syms.c + libc_syms.c + 0 + 0 + + + 10 + 125 + 1 + 0 + 0 + 0 + ../../components/libc/compilers/armlibc/mem_std.c + mem_std.c + 0 + 0 + + + 10 + 126 + 1 + 0 + 0 + 0 + ../../components/libc/compilers/armlibc/stdio.c + stdio.c + 0 + 0 + + + 10 + 127 + 1 + 0 + 0 + 0 + ../../components/libc/compilers/armlibc/stubs.c + stubs.c + 0 + 0 + + + 10 + 128 + 1 + 0 + 0 + 0 + ../../components/libc/compilers/armlibc/time.c + time.c + 0 + 0 + + + + + finsh + 0 + 0 + 0 + 0 + + 11 + 129 + 1 + 0 + 0 + 0 + ../../components/finsh/shell.c + shell.c + 0 + 0 + + + 11 + 130 + 1 + 0 + 0 + 0 + ../../components/finsh/symbol.c + symbol.c + 0 + 0 + + + 11 + 131 + 1 + 0 + 0 + 0 + ../../components/finsh/cmd.c + cmd.c + 0 + 0 + + + 11 + 132 + 1 + 0 + 0 + 0 + ../../components/finsh/msh.c + msh.c + 0 + 0 + + + 11 + 133 + 1 + 0 + 0 + 0 + ../../components/finsh/msh_cmd.c + msh_cmd.c + 0 + 0 + + + 11 + 134 + 1 + 0 + 0 + 0 + ../../components/finsh/msh_file.c + msh_file.c + 0 + 0 + + + 11 + 135 + 1 + 0 + 0 + 0 + ../../components/finsh/finsh_compiler.c + finsh_compiler.c + 0 + 0 + + + 11 + 136 + 1 + 0 + 0 + 0 + ../../components/finsh/finsh_error.c + finsh_error.c + 0 + 0 + + + 11 + 137 + 1 + 0 + 0 + 0 + ../../components/finsh/finsh_heap.c + finsh_heap.c + 0 + 0 + + + 11 + 138 + 1 + 0 + 0 + 0 + ../../components/finsh/finsh_init.c + finsh_init.c + 0 + 0 + + + 11 + 139 + 1 + 0 + 0 + 0 + ../../components/finsh/finsh_node.c + finsh_node.c + 0 + 0 + + + 11 + 140 + 1 + 0 + 0 + 0 + ../../components/finsh/finsh_ops.c + finsh_ops.c + 0 + 0 + + + 11 + 141 + 1 + 0 + 0 + 0 + ../../components/finsh/finsh_parser.c + finsh_parser.c + 0 + 0 + + + 11 + 142 + 1 + 0 + 0 + 0 + ../../components/finsh/finsh_var.c + finsh_var.c + 0 + 0 + + + 11 + 143 + 1 + 0 + 0 + 0 + ../../components/finsh/finsh_vm.c + finsh_vm.c + 0 + 0 + + + 11 + 144 + 1 + 0 + 0 + 0 + ../../components/finsh/finsh_token.c + finsh_token.c + 0 + 0 + + + + + lwIP + 0 + 0 + 0 + 0 + + 12 + 145 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/arch/sys_arch.c + sys_arch.c + 0 + 0 + + + 12 + 146 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/api/api_lib.c + api_lib.c + 0 + 0 + + + 12 + 147 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/api/api_msg.c + api_msg.c + 0 + 0 + + + 12 + 148 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/api/err.c + err.c + 0 + 0 + + + 12 + 149 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/api/netbuf.c + netbuf.c + 0 + 0 + + + 12 + 150 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/api/netdb.c + netdb.c + 0 + 0 + + + 12 + 151 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/api/netifapi.c + netifapi.c + 0 + 0 + + + 12 + 152 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/api/sockets.c + sockets.c + 0 + 0 + + + 12 + 153 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/api/tcpip.c + tcpip.c + 0 + 0 + + + 12 + 154 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/def.c + def.c + 0 + 0 + + + 12 + 155 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/dns.c + dns.c + 0 + 0 + + + 12 + 156 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/inet_chksum.c + inet_chksum.c + 0 + 0 + + + 12 + 157 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/init.c + init.c + 0 + 0 + + + 12 + 158 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/ip.c + ip.c + 0 + 0 + + + 12 + 159 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/memp.c + memp.c + 0 + 0 + + + 12 + 160 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/netif.c + netif.c + 0 + 0 + + + 12 + 161 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/pbuf.c + pbuf.c + 0 + 0 + + + 12 + 162 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/raw.c + raw.c + 0 + 0 + + + 12 + 163 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/stats.c + stats.c + 0 + 0 + + + 12 + 164 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/sys.c + sys.c + 0 + 0 + + + 12 + 165 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/tcp.c + tcp.c + 0 + 0 + + + 12 + 166 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/tcp_in.c + tcp_in.c + 0 + 0 + + + 12 + 167 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/tcp_out.c + tcp_out.c + 0 + 0 + + + 12 + 168 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/timeouts.c + timeouts.c + 0 + 0 + + + 12 + 169 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/udp.c + udp.c + 0 + 0 + + + 12 + 170 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/netif/ethernet.c + ethernet.c + 0 + 0 + + + 12 + 171 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/netif/ethernetif.c + ethernetif.c + 0 + 0 + + + 12 + 172 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/netif/lowpan6.c + lowpan6.c + 0 + 0 + + + 12 + 173 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/ipv4/autoip.c + autoip.c + 0 + 0 + + + 12 + 174 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/ipv4/dhcp.c + dhcp.c + 0 + 0 + + + 12 + 175 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/ipv4/etharp.c + etharp.c + 0 + 0 + + + 12 + 176 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/ipv4/icmp.c + icmp.c + 0 + 0 + + + 12 + 177 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/ipv4/igmp.c + igmp.c + 0 + 0 + + + 12 + 178 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/ipv4/ip4.c + ip4.c + 0 + 0 + + + 12 + 179 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/ipv4/ip4_addr.c + ip4_addr.c + 0 + 0 + + + 12 + 180 + 1 + 0 + 0 + 0 + ../../components/net/lwip-2.0.2/src/core/ipv4/ip4_frag.c + ip4_frag.c + 0 + 0 + + + + + Filesystem + 0 + 0 + 0 + 0 + + 13 + 181 + 1 + 0 + 0 + 0 + ../../components/dfs/src/dfs.c + dfs.c + 0 + 0 + + + 13 + 182 + 1 + 0 + 0 + 0 + ../../components/dfs/src/dfs_file.c + dfs_file.c + 0 + 0 + + + 13 + 183 + 1 + 0 + 0 + 0 + ../../components/dfs/src/dfs_fs.c + dfs_fs.c + 0 + 0 + + + 13 + 184 + 1 + 0 + 0 + 0 + ../../components/dfs/src/dfs_posix.c + dfs_posix.c + 0 + 0 + + + 13 + 185 + 1 + 0 + 0 + 0 + ../../components/dfs/filesystems/elmfat/dfs_elm.c + dfs_elm.c + 0 + 0 + + + 13 + 186 + 1 + 0 + 0 + 0 + ../../components/dfs/filesystems/elmfat/ff.c + ff.c + 0 + 0 + + + diff --git a/bsp/lpc54608-LPCXpresso/project.uvprojx b/bsp/lpc54608-LPCXpresso/project.uvprojx index c61f567ea7..4814893b17 100644 --- a/bsp/lpc54608-LPCXpresso/project.uvprojx +++ b/bsp/lpc54608-LPCXpresso/project.uvprojx @@ -1,42 +1,46 @@ + 2.1 +
### uVision Project, (C) Keil Software
+ rtthread-lpc546xx 0x4 ARM-ADS + 5060750::V5.06 update 6 (build 750)::ARMCC 0 LPC54608J512ET180:M4 NXP - Keil.LPC54000_DFP.2.5.0 - http://www.keil.com/pack/ + NXP.LPC54608_DFP.2.3.0 + http://mcuxpresso.nxp.com/cmsis_pack/repo/ IROM(0x00000000,0x00080000) IRAM(0x20000000,0x00028000) IRAM2(0x04000000,0x00008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE - - + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0LPC5460x_512 -FS00 -FL080000 -FP0($$Device:LPC54608J512ET180$Flash\LPC5460x_512.FLM)) 0 $$Device:LPC54608J512ET180$Device\Include\LPC54608.h - - - - - - - - - + + + + + + + + + $$Device:LPC54608J512ET180$SVD\LPC54608.svd 0 0 - - - - - + + + + + 0 0 @@ -58,8 +62,8 @@ 0 0 - - + + 0 0 0 @@ -68,8 +72,8 @@ 0 0 - - + + 0 0 0 @@ -78,15 +82,15 @@ 0 0 - - + + 0 0 0 0 0 - + 0 @@ -100,8 +104,8 @@ 0 0 3 - - + + 1 @@ -135,10 +139,10 @@ 1 BIN\UL2CM3.DLL "" () - - - - + + + + 0 @@ -171,7 +175,7 @@ 0 0 "Cortex-M4" - + 0 0 0 @@ -303,7 +307,7 @@ 0x8000 - + 1 @@ -320,6 +324,7 @@ 0 0 1 + 0 0 0 0 @@ -331,7 +336,7 @@ --library_interface=armcc --library_type=standardlib --diag_suppress=66,1296,186 SDK_DEBUGCONSOLE=0, CPU_LPC54608, CORE_M4, CPU_LPC54608J512ET180=1, RT_USING_ARM_LIBC - + SDK_2.2_LPCXpresso54608/sdmmc_2.1.2/inc;SDK_2.2_LPCXpresso54608/sdmmc_2.1.2/src;SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers;SDK_2.2_LPCXpresso54608/devices/LPC54608/utilities;SDK_2.2_LPCXpresso54608/CMSIS/Include;SDK_2.2_LPCXpresso54608/devices/LPC54608;drivers;applications;.;../../include;../../libcpu/arm/cortex-m4;../../libcpu/arm/common;../../components/cplusplus;../../components/drivers/include;../../components/drivers/include;../../components/drivers/include;../../components/drivers/include;../../components/drivers/include;../../components/drivers/include;../../components/drivers/spi;../../components/drivers/include;../../components/drivers/include;../../components/libc/pthreads;../../components/libc/time;../../components/libc/compilers/armlibc;../../components/finsh;../../components/net/lwip-2.0.2/src;../../components/net/lwip-2.0.2/src/include;../../components/net/lwip-2.0.2/src/include/ipv4;../../components/net/lwip-2.0.2/src/arch/include;../../components/net/lwip-2.0.2/src/include/netif;../../components/net/lwip-2.0.2/src/include/posix;../../components/dfs/include;../../components/dfs/filesystems/elmfat @@ -347,10 +352,10 @@ 0 0 - - - - + + + + @@ -362,13 +367,13 @@ 0 0x00000000 0x02000000 - + .\LPC54608J512_flash.scf - - + + --keep *.o(RTMSymTab) --keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab) - - + + @@ -381,302 +386,216 @@ 1 SDK_2.2_LPCXpresso54608/sdmmc_2.1.2/src/fsl_sd.c - - fsl_sdmmc.c 1 SDK_2.2_LPCXpresso54608/sdmmc_2.1.2/src/fsl_sdmmc.c - - fsl_host.c 1 SDK_2.2_LPCXpresso54608/sdmmc_2.1.2/src/fsl_host.c - - fsl_sd_event.c 1 SDK_2.2_LPCXpresso54608/sdmmc_2.1.2/src/fsl_sd_event.c - - fsl_adc.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_adc.c - - fsl_clock.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_clock.c - - fsl_common.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_common.c - - fsl_crc.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_crc.c - - fsl_ctimer.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_ctimer.c - - fsl_dma.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_dma.c - - fsl_dmic.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_dmic.c - - fsl_dmic_dma.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_dmic_dma.c - - fsl_eeprom.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_eeprom.c - - fsl_emc.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_emc.c - - fsl_enet.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_enet.c - - fsl_flashiap.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_flashiap.c - - fsl_flexcomm.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_flexcomm.c - - fsl_fmc.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_fmc.c - - fsl_fmeas.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_fmeas.c - - fsl_gint.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_gint.c - - fsl_gpio.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_gpio.c - - fsl_i2c.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_i2c.c - - fsl_i2c_dma.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_i2c_dma.c - - fsl_i2s.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_i2s.c - - fsl_i2s_dma.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_i2s_dma.c - - fsl_inputmux.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_inputmux.c - - fsl_lcdc.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_lcdc.c - - fsl_mcan.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_mcan.c - - fsl_mrt.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_mrt.c - - fsl_pint.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_pint.c - - fsl_power.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_power.c - - fsl_reset.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_reset.c - - fsl_rit.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_rit.c - - fsl_rtc.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_rtc.c - - fsl_sctimer.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_sctimer.c - - fsl_sdif.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_sdif.c - - fsl_spi.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_spi.c - - fsl_spi_dma.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_spi_dma.c - - fsl_spifi.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_spifi.c - - fsl_spifi_dma.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_spifi_dma.c - - fsl_usart.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_usart.c - - fsl_usart_dma.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_usart_dma.c - - fsl_utick.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/drivers/fsl_utick.c - - fsl_wwdt.c 1 @@ -692,15 +611,11 @@ 2 SDK_2.2_LPCXpresso54608/devices/LPC54608/arm/startup_LPC54608.s - - system_LPC54608.c 1 SDK_2.2_LPCXpresso54608/devices/LPC54608/system_LPC54608.c - - keil_lib_power.lib 4 @@ -716,78 +631,56 @@ 1 drivers/board.c - - clock_config.c 1 drivers/clock_config.c - - drt_mpu.c 1 drivers/drt_mpu.c - - drv_emac.c 1 drivers/drv_emac.c - - drv_ft5406.c 1 drivers/drv_ft5406.c - - drv_i2c.c 1 drivers/drv_i2c.c - - drv_lcd.c 1 drivers/drv_lcd.c - - drv_sd.c 1 drivers/drv_sd.c - - drv_sdram.c 1 drivers/drv_sdram.c - - drv_sram.c 1 drivers/drv_sram.c - - drv_uart.c 1 drivers/drv_uart.c - - fsl_phy.c 1 @@ -803,15 +696,11 @@ 1 applications/application.c - - mnt.c 1 applications/mnt.c - - startup.c 1 @@ -827,106 +716,76 @@ 1 ../../src/clock.c - - components.c 1 ../../src/components.c - - device.c 1 ../../src/device.c - - idle.c 1 ../../src/idle.c - - ipc.c 1 ../../src/ipc.c - - irq.c 1 ../../src/irq.c - - kservice.c 1 ../../src/kservice.c - - mem.c 1 ../../src/mem.c - - memheap.c 1 ../../src/memheap.c - - mempool.c 1 ../../src/mempool.c - - module.c 1 ../../src/module.c - - object.c 1 ../../src/object.c - - scheduler.c 1 ../../src/scheduler.c - - signal.c 1 ../../src/signal.c - - thread.c 1 ../../src/thread.c - - timer.c 1 @@ -942,29 +801,21 @@ 1 ../../libcpu/arm/cortex-m4/cpuport.c - - context_rvds.S 2 ../../libcpu/arm/cortex-m4/context_rvds.S - - backtrace.c 1 ../../libcpu/arm/common/backtrace.c - - div0.c 1 ../../libcpu/arm/common/div0.c - - showmem.c 1 @@ -980,29 +831,21 @@ 8 ../../components/cplusplus/Mutex.cpp - - Semaphore.cpp 8 ../../components/cplusplus/Semaphore.cpp - - Thread.cpp 8 ../../components/cplusplus/Thread.cpp - - crt.cpp 8 ../../components/cplusplus/crt.cpp - - crt_init.c 1 @@ -1012,165 +855,182 @@ DeviceDrivers + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + pin.c 1 ../../components/drivers/misc/pin.c - - i2c_core.c 1 ../../components/drivers/i2c/i2c_core.c - - i2c_dev.c 1 ../../components/drivers/i2c/i2c_dev.c - - i2c-bit-ops.c 1 ../../components/drivers/i2c/i2c-bit-ops.c - - block_dev.c 1 ../../components/drivers/sdio/block_dev.c - - mmcsd_core.c 1 ../../components/drivers/sdio/mmcsd_core.c - - sd.c 1 ../../components/drivers/sdio/sd.c - - sdio.c 1 ../../components/drivers/sdio/sdio.c - - mmc.c 1 ../../components/drivers/sdio/mmc.c - - serial.c 1 ../../components/drivers/serial/serial.c - - rtc.c 1 ../../components/drivers/rtc/rtc.c - - mtd_nand.c 1 ../../components/drivers/mtd/mtd_nand.c - - spi_core.c 1 ../../components/drivers/spi/spi_core.c - - spi_dev.c 1 ../../components/drivers/spi/spi_dev.c - - enc28j60.c 1 ../../components/drivers/spi/enc28j60.c - - completion.c 1 ../../components/drivers/src/completion.c - - dataqueue.c 1 ../../components/drivers/src/dataqueue.c - - pipe.c 1 ../../components/drivers/src/pipe.c - - ringbuffer.c 1 ../../components/drivers/src/ringbuffer.c - - waitqueue.c 1 ../../components/drivers/src/waitqueue.c - - workqueue.c 1 ../../components/drivers/src/workqueue.c - - - - - - - - - - - - pthreads @@ -1180,85 +1040,61 @@ 1 ../../components/libc/pthreads/mqueue.c - - pthread.c 1 ../../components/libc/pthreads/pthread.c - - pthread_attr.c 1 ../../components/libc/pthreads/pthread_attr.c - - pthread_barrier.c 1 ../../components/libc/pthreads/pthread_barrier.c - - pthread_cond.c 1 ../../components/libc/pthreads/pthread_cond.c - - pthread_mutex.c 1 ../../components/libc/pthreads/pthread_mutex.c - - pthread_rwlock.c 1 ../../components/libc/pthreads/pthread_rwlock.c - - pthread_spin.c 1 ../../components/libc/pthreads/pthread_spin.c - - pthread_tls.c 1 ../../components/libc/pthreads/pthread_tls.c - - sched.c 1 ../../components/libc/pthreads/sched.c - - semaphore.c 1 ../../components/libc/pthreads/semaphore.c - - clock_time.c 1 ../../components/libc/time/clock_time.c - - posix_sleep.c 1 @@ -1274,36 +1110,26 @@ 1 ../../components/libc/compilers/armlibc/libc.c - - libc_syms.c 1 ../../components/libc/compilers/armlibc/libc_syms.c - - mem_std.c 1 ../../components/libc/compilers/armlibc/mem_std.c - - stdio.c 1 ../../components/libc/compilers/armlibc/stdio.c - - stubs.c 1 ../../components/libc/compilers/armlibc/stubs.c - - time.c 1 @@ -1319,106 +1145,76 @@ 1 ../../components/finsh/shell.c - - symbol.c 1 ../../components/finsh/symbol.c - - cmd.c 1 ../../components/finsh/cmd.c - - msh.c 1 ../../components/finsh/msh.c - - msh_cmd.c 1 ../../components/finsh/msh_cmd.c - - msh_file.c 1 ../../components/finsh/msh_file.c - - finsh_compiler.c 1 ../../components/finsh/finsh_compiler.c - - finsh_error.c 1 ../../components/finsh/finsh_error.c - - finsh_heap.c 1 ../../components/finsh/finsh_heap.c - - finsh_init.c 1 ../../components/finsh/finsh_init.c - - finsh_node.c 1 ../../components/finsh/finsh_node.c - - finsh_ops.c 1 ../../components/finsh/finsh_ops.c - - finsh_parser.c 1 ../../components/finsh/finsh_parser.c - - finsh_var.c 1 ../../components/finsh/finsh_var.c - - finsh_vm.c 1 ../../components/finsh/finsh_vm.c - - finsh_token.c 1 @@ -1434,246 +1230,176 @@ 1 ../../components/net/lwip-2.0.2/src/arch/sys_arch.c - - api_lib.c 1 ../../components/net/lwip-2.0.2/src/api/api_lib.c - - api_msg.c 1 ../../components/net/lwip-2.0.2/src/api/api_msg.c - - err.c 1 ../../components/net/lwip-2.0.2/src/api/err.c - - netbuf.c 1 ../../components/net/lwip-2.0.2/src/api/netbuf.c - - netdb.c 1 ../../components/net/lwip-2.0.2/src/api/netdb.c - - netifapi.c 1 ../../components/net/lwip-2.0.2/src/api/netifapi.c - - sockets.c 1 ../../components/net/lwip-2.0.2/src/api/sockets.c - - tcpip.c 1 ../../components/net/lwip-2.0.2/src/api/tcpip.c - - def.c 1 ../../components/net/lwip-2.0.2/src/core/def.c - - dns.c 1 ../../components/net/lwip-2.0.2/src/core/dns.c - - inet_chksum.c 1 ../../components/net/lwip-2.0.2/src/core/inet_chksum.c - - init.c 1 ../../components/net/lwip-2.0.2/src/core/init.c - - ip.c 1 ../../components/net/lwip-2.0.2/src/core/ip.c - - memp.c 1 ../../components/net/lwip-2.0.2/src/core/memp.c - - netif.c 1 ../../components/net/lwip-2.0.2/src/core/netif.c - - pbuf.c 1 ../../components/net/lwip-2.0.2/src/core/pbuf.c - - raw.c 1 ../../components/net/lwip-2.0.2/src/core/raw.c - - stats.c 1 ../../components/net/lwip-2.0.2/src/core/stats.c - - sys.c 1 ../../components/net/lwip-2.0.2/src/core/sys.c - - tcp.c 1 ../../components/net/lwip-2.0.2/src/core/tcp.c - - tcp_in.c 1 ../../components/net/lwip-2.0.2/src/core/tcp_in.c - - tcp_out.c 1 ../../components/net/lwip-2.0.2/src/core/tcp_out.c - - timeouts.c 1 ../../components/net/lwip-2.0.2/src/core/timeouts.c - - udp.c 1 ../../components/net/lwip-2.0.2/src/core/udp.c - - ethernet.c 1 ../../components/net/lwip-2.0.2/src/netif/ethernet.c - - ethernetif.c 1 ../../components/net/lwip-2.0.2/src/netif/ethernetif.c - - lowpan6.c 1 ../../components/net/lwip-2.0.2/src/netif/lowpan6.c - - autoip.c 1 ../../components/net/lwip-2.0.2/src/core/ipv4/autoip.c - - dhcp.c 1 ../../components/net/lwip-2.0.2/src/core/ipv4/dhcp.c - - etharp.c 1 ../../components/net/lwip-2.0.2/src/core/ipv4/etharp.c - - icmp.c 1 ../../components/net/lwip-2.0.2/src/core/ipv4/icmp.c - - igmp.c 1 ../../components/net/lwip-2.0.2/src/core/ipv4/igmp.c - - ip4.c 1 ../../components/net/lwip-2.0.2/src/core/ipv4/ip4.c - - ip4_addr.c 1 ../../components/net/lwip-2.0.2/src/core/ipv4/ip4_addr.c - - ip4_frag.c 1 @@ -1689,36 +1415,26 @@ 1 ../../components/dfs/src/dfs.c - - dfs_file.c 1 ../../components/dfs/src/dfs_file.c - - dfs_fs.c 1 ../../components/dfs/src/dfs_fs.c - - dfs_posix.c 1 ../../components/dfs/src/dfs_posix.c - - dfs_elm.c 1 ../../components/dfs/filesystems/elmfat/dfs_elm.c - - ff.c 1 @@ -1729,9 +1445,11 @@ + - - - + + + +