[bsp] add ck802 bsp

This commit is contained in:
liang yongxiang 2018-06-05 14:36:29 +08:00
parent 4e937887f6
commit b085393cde
81 changed files with 20215 additions and 405 deletions

275
bsp/ck802/.config Normal file
View File

@ -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

30
bsp/ck802/Kconfig Normal file
View File

@ -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

84
bsp/ck802/README.md Normal file
View File

@ -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)

14
bsp/ck802/SConscript Normal file
View File

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

35
bsp/ck802/SConstruct Normal file
View File

@ -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)

View File

@ -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')

View File

@ -0,0 +1,33 @@
/*
* File : clock.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-10-10 Tanek first version
*/
#include <rtthread.h>
int main(void)
{
return 0;
}
/*@}*/

View File

@ -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')

60
bsp/ck802/drivers/board.c Normal file
View File

@ -0,0 +1,60 @@
/*
* File : board.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2018, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-08-10 Urey first implementation
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "csi_core.h"
#include "pinmux.h"
extern int __bss_end__;
#define SYS_HEAP_BEGIN (&__bss_end__)
#include "core_ck802.h"
/**
* This function will initial CK802 board.
*/
void rt_hw_board_init(void)
{
phobos_ioreuse_initial();
/* NVIC Configuration */
drv_nvic_init(2);
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#ifdef RT_USING_CONSOLE
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#ifdef RT_USING_HEAP
rt_system_heap_init((void *)SYS_HEAP_BEGIN, (void *)CK802_IRAM_END);
#endif
}
/*@}*/

32
bsp/ck802/drivers/board.h Normal file
View File

@ -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__ */

View File

@ -0,0 +1,81 @@
/*
* File : board_coretimer.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-01-01 Urey first version
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "board_coretimer.h"
#include <stdint.h>
static inline unsigned int readreg32(volatile unsigned int *addr)
{
return *(volatile unsigned int *)addr;
}
static inline void writereg32(unsigned int b, volatile unsigned int *addr)
{
*(volatile unsigned int *)addr = b;
}
void CKTimerInit(uint32_t timer_id, uint32_t freq)
{
uint32_t reg;
writereg32(APB_DEFAULT_FREQ / freq, CORET_RVR);
writereg32(0, CORET_CVR);
reg = readreg32(CORET_CSR);
reg |= CORETIM_TXCONTROL_ENABLE;
reg |= CORETIM_TXCONTROL_INTMASK;
writereg32(reg, CORET_CSR);
return;
}
void CKTimerClear(uint32_t timer_id)
{
uint32_t reg;
reg = readreg32(CORET_CSR);
reg |= ~CORETIM_TXCONTROL_MODE;
writereg32(reg, CORET_CSR);
}
uint32_t CKTimer_CurrentValue(void)
{
return readreg32(CORET_CVR);
}
void __attribute__((isr)) SysTick_Handler(void)
{
CKTimerClear(0x1);
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}

View File

@ -0,0 +1,52 @@
/*
* File : board_coretimer.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-01-01 Urey first version
*/
#ifndef _BOARD_CORETIMER_H_
#define _BOARD_CORETIMER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#define CK_TIMER_BASE (0xE000E000)
#define CORET_CSR (volatile unsigned int *)(CK_TIMER_BASE + 0x10)
#define CORET_RVR (volatile unsigned int *)(CK_TIMER_BASE + 0x14)
#define CORET_CVR (volatile unsigned int *)(CK_TIMER_BASE + 0x18)
#define CORET_CALIB (volatile unsigned int *)(CK_TIMER_BASE + 0x1c)
/*
* define the bits for TxControl
*/
#define CORETIM_TXCONTROL_ENABLE (1UL << 0)
#define CORETIM_TXCONTROL_INTMASK (1UL << 1)
#define CORETIM_TXCONTROL_MODE (1UL << 16)
#ifdef __cplusplus
}
#endif
#endif /* _BOARD_CORETIMER_H_ */

View File

@ -0,0 +1,273 @@
/*
* File : board_uart.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2018, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-09-23 Urey first implementation
*/
#include <rtthread.h>
#ifdef RT_USING_CONSOLE
#include <rthw.h>
#include <rtdevice.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "board.h"
#include "soc.h"
#include "dw_usart.h"
#include "drv_usart.h"
#include "pin_name.h"
#include "pinmux.h"
#if CONFIG_USART
struct
{
uint32_t base;
uint32_t irq;
} const sg_usart_config[CONFIG_USART_NUM] =
{
{ CSKY_UART0_BASE, UART0_IRQn },
{ CSKY_UART1_BASE, UART1_IRQn },
{ CSKY_UART2_BASE, UART2_IRQn },
{ CSKY_UART3_BASE, UART3_IRQn }
};
typedef struct
{
pin_t tx;
pin_t rx;
uint16_t cfg_idx; //idx of sg_usart_config[]
uint16_t function;
} usart_pin_map_t;
const static usart_pin_map_t s_usart_pin_map[] =
{
{
PA0_TXD0_PWM0_XX_SIROUT0,
PA1_RXD0_PWM1_XX_SIRIN0,
0,
0
},
{
PA10_TXD1_PWM1_XX_SIROUT1,
PA11_RXD1_PWM2_XX_SIRIN1,
1,
0
},
{
PA23_TXD2_PWM5_XX_SIROUT2,
PA22_RXD2_PWM4_XX_SIRIN2,
2,
0
},
{
PA26_TXD3_PWMFAULT_XX_SIROUT3,
PA27_RXD3_PWM0_XX_SIRIN3,
3,
0
}
};
int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq)
{
uint32_t idx;
for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++)
{
if (s_usart_pin_map[idx].tx == tx && s_usart_pin_map[idx].rx == rx)
{
*base = sg_usart_config[s_usart_pin_map[idx].cfg_idx].base;
*irq = sg_usart_config[s_usart_pin_map[idx].cfg_idx].irq;
/*pinmux*/
pin_mux(s_usart_pin_map[idx].tx, s_usart_pin_map[idx].function);
pin_mux(s_usart_pin_map[idx].rx, s_usart_pin_map[idx].function);
return s_usart_pin_map[idx].cfg_idx;
}
}
return -1;
}
#endif
#ifdef RT_USING_UART1
#define UART_TXD1 PA10_TXD1_PWM1_XX_SIROUT1
#define UART_RXD1 PA11_RXD1_PWM2_XX_SIRIN1
static usart_handle_t uart1_handle;
static struct rt_serial_device serial1;
/*
static void usart1_event_cb(uint32_t event, void *cb_arg)
{
switch (event)
{
case USART_EVENT_SEND_COMPLETE:
rt_hw_serial_isr(&serial1,RT_SERIAL_EVENT_TX_DONE);
break;
case USART_EVENT_RECEIVED:
rt_hw_serial_isr(&serial1,RT_SERIAL_EVENT_RX_IND);
break;
default:
break;
}
}
*/
__attribute__((isr)) void USART1_IRQHandler(void)
{
rt_hw_serial_isr(&serial1,RT_SERIAL_EVENT_RX_IND);
}
#endif
/*
* UART interface
*/
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
int ret;
usart_handle_t uart;
uint32_t bauds;
usart_mode_e mode;
usart_parity_e parity;
usart_stop_bits_e stopbits;
usart_data_bits_e databits;
RT_ASSERT(serial != RT_NULL);
uart = (usart_handle_t)serial->parent.user_data;
RT_ASSERT(uart != RT_NULL);
/* set baudrate parity...*/
bauds = cfg->baud_rate;
mode = USART_MODE_ASYNCHRONOUS;
if (cfg->parity == PARITY_EVEN)
parity = USART_PARITY_EVEN;
else if (cfg->parity == PARITY_ODD)
parity = USART_PARITY_ODD;
else
parity = USART_PARITY_NONE;
stopbits = USART_STOP_BITS_1 ;
databits = USART_DATA_BITS_8;
ret = csi_usart_config(uart, SYSTEM_CLOCK, bauds, USART_MODE_ASYNCHRONOUS, parity, stopbits, databits);
if (ret < 0)
{
return -RT_ERROR;
}
return RT_EOK;
}
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
usart_handle_t uart;
RT_ASSERT(serial != RT_NULL);
uart = (usart_handle_t)serial->parent.user_data;
RT_ASSERT(uart != RT_NULL);
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
/* Disable the UART Interrupt */
dw_usart_clr_int_flag(uart,IER_RDA_INT_ENABLE);
break;
case RT_DEVICE_CTRL_SET_INT:
/* Enable the UART Interrupt */
dw_usart_set_int_flag(uart,IER_RDA_INT_ENABLE);
break;
}
return (RT_EOK);
}
static int uart_putc(struct rt_serial_device *serial, char c)
{
usart_handle_t uart;
RT_ASSERT(serial != RT_NULL);
uart = (usart_handle_t)serial->parent.user_data;
RT_ASSERT(uart != RT_NULL);
dw_usart_putchar(uart,c);
return (1);
}
static int uart_getc(struct rt_serial_device *serial)
{
uint8_t ch;
usart_handle_t uart;
RT_ASSERT(serial != RT_NULL);
uart = (usart_handle_t)serial->parent.user_data;
RT_ASSERT(uart != RT_NULL);
if (!dw_usart_getchar_no_poll(uart, &ch))
{
return (int)(ch);
}
else
{
return -1;
}
}
const struct rt_uart_ops _uart_ops =
{
uart_configure,
uart_control,
uart_putc,
uart_getc,
};
int rt_hw_usart_init(void)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
#ifdef RT_USING_UART1
serial1.ops = & _uart_ops;
serial1.config = config;
serial1.config.bufsz = 2048;
serial1.config.baud_rate = 115200;
uart1_handle = csi_usart_initialize(UART_TXD1, UART_RXD1, NULL/*usart1_event_cb*/,
(void *) 0);
rt_hw_serial_register(&serial1,
"uart1",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
uart1_handle);
#endif
return 0;
}
INIT_BOARD_EXPORT(rt_hw_usart_init);
#endif

View File

@ -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 */

174
bsp/ck802/drivers/isr.c Normal file
View File

@ -0,0 +1,174 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file isr.c
* @brief source file for the interrupt server route
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <drv_common.h>
#include "config.h"
#include "soc.h"
extern void dw_usart_irqhandler(int32_t idx);
extern void dw_timer_irqhandler(int32_t idx);
extern void dw_gpio_irqhandler(int32_t idx);
extern void dw_iic_irqhandler(int32_t idx);
extern void ck_rtc_irqhandler(int32_t idx);
extern void dw_spi_irqhandler(int32_t idx);
extern void dw_wdt_irqhandler(int32_t idx);
extern void ck_dma_irqhandler(int32_t idx);
extern void ck_aes_irqhandler(int32_t idx);
extern void ck_sha_irqhandler(int32_t idx);
#ifdef CONFIG_KERNEL_FREERTOS
extern void CKTimer1Isr(void);
extern void CKPendSVIsr(void);
#endif
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
__attribute__((isr)) void CORET_IRQHandler(void)
{
readl(0xE000E010);
}
#if defined(CONFIG_USART)
/*
__attribute__((isr)) void USART0_IRQHandler(void)
{
dw_usart_irqhandler(0);
}
__attribute__((isr)) void USART1_IRQHandler(void)
{
dw_usart_irqhandler(1);
}
__attribute__((isr)) void USART2_IRQHandler(void)
{
dw_usart_irqhandler(2);
}
__attribute__((isr)) void USART3_IRQHandler(void)
{
dw_usart_irqhandler(3);
}
*/
#endif
#if defined(CONFIG_TIMER)
__attribute__((isr)) void TIMA0_IRQHandler(void)
{
dw_timer_irqhandler(0);
}
__attribute__((isr)) void TIMA1_IRQHandler(void)
{
dw_timer_irqhandler(1);
}
__attribute__((isr)) void TIMB0_IRQHandler(void)
{
dw_timer_irqhandler(2);
}
__attribute__((isr)) void TIMB1_IRQHandler(void)
{
dw_timer_irqhandler(3);
}
#endif
#if defined(CONFIG_GPIO)
__attribute__((isr)) void GPIOA_IRQHandler(void)
{
dw_gpio_irqhandler(0);
}
__attribute__((isr)) void GPIOB_IRQHandler(void)
{
dw_gpio_irqhandler(1);
}
#endif
#if defined(CONFIG_IIC)
__attribute__((isr)) void I2C0_IRQHandler(void)
{
dw_iic_irqhandler(0);
}
__attribute__((isr)) void I2C1_IRQHandler(void)
{
dw_iic_irqhandler(1);
}
#endif
#if defined(CONFIG_RTC)
__attribute__((isr)) void RTC_IRQHandler(void)
{
ck_rtc_irqhandler(0);
}
#endif
#if defined(CONFIG_AES)
__attribute__((isr)) void AES_IRQHandler(void)
{
ck_aes_irqhandler(0);
}
#endif
#if defined(CONFIG_SHA)
__attribute__((isr)) void SHA_IRQHandler(void)
{
ck_sha_irqhandler(0);
}
#endif
#if defined(CONFIG_SPI) && defined(CONFIG_GPIO)
__attribute__((isr)) void SPI0_IRQHandler(void)
{
dw_spi_irqhandler(0);
}
__attribute__((isr)) void SPI1_IRQHandler(void)
{
dw_spi_irqhandler(1);
}
#endif
#if defined(CONFIG_WDT)
__attribute__((isr)) void WDT_IRQHandler(void)
{
dw_wdt_irqhandler(0);
}
#endif
#if defined(CONFIG_DMAC)
__attribute__((isr)) void DMAC_IRQHandler(void)
{
ck_dma_irqhandler(0);
}
#endif

View File

@ -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

158
bsp/ck802/drivers/pinmux.c Normal file
View File

@ -0,0 +1,158 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pinmux.c
* @brief source file for the pinmux
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdint.h>
#include "pinmux.h"
#include "pin_name.h"
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
/*******************************************************************************
* function: phobos_ioreuse_inital
*
* description:
* initial phobos_pinmux
*******************************************************************************/
void phobos_ioreuse_initial(void)
{
unsigned int value;
/* gpio data source select */
value = readl(PHOBOS_GIPO0_PORTCTL_REG);
value |= GPIO0_REUSE_EN;
writel(value, PHOBOS_GIPO0_PORTCTL_REG);
value = readl(PHOBOS_GIPO1_PORTCTL_REG);
value |= GPIO1_REUSE_EN;
writel(value, PHOBOS_GIPO1_PORTCTL_REG);
/* reuse function select */
value = readl(PHOBOS_IOMUX0L_REG);
value |= IOMUX0L_FUNCTION_SEL;
writel(value, PHOBOS_IOMUX0L_REG);
value = readl(PHOBOS_IOMUX0H_REG);
value |= IOMUX1L_FUNCTION_SEL;
writel(value, PHOBOS_IOMUX0H_REG);
value = readl(PHOBOS_IOMUX1L_REG);
value |= IOMUX1L_FUNCTION_SEL;
writel(value, PHOBOS_IOMUX1L_REG);
}
void phobos_pwm_ioreuse(void)
{
unsigned int value;
/* gpio data source select */
value = readl(PHOBOS_GIPO0_PORTCTL_REG);
value |= PWM_GPIO0_REUSE_EN;
writel(value, PHOBOS_GIPO0_PORTCTL_REG);
/* reuse function select */
value = readl(PHOBOS_IOMUX0L_REG);
value |= PWM_IOMUX0L_FUNCTION_SEL;
writel(value, PHOBOS_IOMUX0L_REG);
}
int32_t pin_mux(pin_name_t pin, uint16_t function)
{
unsigned int val = 0;
unsigned int reg_val = 0;
uint8_t offset;
if (function > 3)
{
if (pin < PB0_ADC0_SDA0_PWM5_XX)
{
offset = pin;
/* gpio data source select */
val = readl(PHOBOS_GIPO0_PORTCTL_REG);
val &= ~(1 << offset);
writel(val, PHOBOS_GIPO0_PORTCTL_REG);
return 0;
}
else if (pin >= PB0_ADC0_SDA0_PWM5_XX)
{
offset = pin - 32;
/* gpio data source select */
val = readl(PHOBOS_GIPO1_PORTCTL_REG);
val &= ~(1 << offset);
writel(val, PHOBOS_GIPO1_PORTCTL_REG);
return 0;
}
else
{
return -1;
}
}
if (pin >= PB0_ADC0_SDA0_PWM5_XX)
{
offset = pin - 32;
/* gpio data source select */
val = readl(PHOBOS_GIPO1_PORTCTL_REG);
val |= (1 << offset);
writel(val, PHOBOS_GIPO1_PORTCTL_REG);
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(PHOBOS_IOMUX1L_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, PHOBOS_IOMUX1L_REG);
return 0;
}
offset = pin;
/* gpio data source select */
val = readl(PHOBOS_GIPO0_PORTCTL_REG);
val |= (1 << offset);
writel(val, PHOBOS_GIPO0_PORTCTL_REG);
if (pin >= PA16_SPI1CLK_PWMTRIG1_XX_XX)
{
offset = pin - 16;
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(PHOBOS_IOMUX0H_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, PHOBOS_IOMUX0H_REG);
return 0;
}
reg_val = (0x3 << (offset * 2));
/* reuse function select */
val = readl(PHOBOS_IOMUX0L_REG);
val &= ~(reg_val);
val |= (function << (2 * offset));
writel(val, PHOBOS_IOMUX0L_REG);
return 0;
}

220
bsp/ck802/drivers/pinmux.h Normal file
View File

@ -0,0 +1,220 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file pinmux.h
* @brief Header file for the pinmux
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef PHOBOS_PINMUX_H
#define PHOBOS_PINMUX_H
#include <stdint.h>
#include "pin_name.h"
void phobos_ioreuse_initial(void);
int32_t pin_mux(pin_name_t pin, uint16_t function);
/* IOMUX0L function definition */
#define PA0_UART0_TX 0x00000000
#define PA0_PWM_CH0 0x00000001
#define PA0_UART0_SIROUT 0x00000003
#define PA1_UART0_RX 0x00000000
#define PA1_PWM_CH1 0x00000004
#define PA1_UART0_SIRIN 0x0000000C
#define PA2_UART0_CTS 0x00000000
#define PA2_PWM_CH2 0x00000010
#define PA2_SPI0_CLK 0x00000020
#define PA3_UART0_TRS 0x00000000
#define PA3_PWM_CH3 0x00000040
#define PA3_SPI0_TX 0x00000080
#define PA4_I2C0_SCL 0x00000000
#define PA4_PWM_CH4 0x00000100
#define PA4_SPI0_RX 0x00000200
#define PA5_I2C0_SDA 0x00000000
#define PA5_PWM_CH5 0x00000400
#define PA5_SPI0_CS 0x00000800
#define PA6_SPI0_CLK 0x00000000
#define PA6_ETB_TRIG0 0x00001000
#define PA6_I2C0_SCL 0x00002000
#define PA7_SPI_TX 0x00000000
#define PA7_ETB_TRIG1 0x00004000
#define PA7_I2C0_SDA 0x00008000
#define PA8_SPI0_TX 0x00000000
#define PA8_PWM_FAULT 0x00010000
#define PA8_I2C1_SCL 0x00020000
#define PA9_SPI0_CS 0x00000000
#define PA9_PWM_CH0 0x00040000
#define PA9_I2C1_SDA 0x00080000
#define PA10_UART1_TX 0x00000000
#define PA10_PWM_CH1 0x00100000
#define PA10_UART1_SIROUT 0x00300000
#define PA11_UART1_RX 0x00000000
#define PA11_PWM_CH2 0x00400000
#define PA11_UART1_SIRIN 0x00C00000
#define PA12_UART1_CTS 0x00000000
#define PA12_PWM_CH3 0x01000000
#define PA12_SPI1_CLK 0x02000000
#define PA13_UART1_RTS 0x00000000
#define PA13_PWM_CH4 0x04000000
#define PA13_SPI1_TX 0x08000000
#define PA14_I2C1_SCL 0x00000000
#define PA14_PWM_CH5 0x10000000
#define PA14_SPI1_RX 0x20000000
#define PA15_I2C1_SDA 0x00000000
#define PA15_ETB_TRIG0 0x40000000
#define PA15_SPI1_CS0 0x80000000
/* IOMUX0H function definition */
#define PA16_SPI1_CLK 0x00000000
#define PA16_ETB_TRIG1 0x00000001
#define PA17_SPI1_TX 0x00000000
#define PA17_PWM_FAULT 0x00000004
#define PA18_SPI1_RX 0x00000000
#define PA18_PWM_CH0 0x00000010
#define PA19_SPI1_CS0 0x00000000
#define PA19_PWM_CH1 0x00000040
#define PA20_UART2_RX 0x00000000
#define PA20_PWM_CH2 0x00000100
#define PA21_SPI1_CS2 0x00000000
#define PA21_PWM_CH3 0x00000400
#define PA22_UART2_RX 0x00000000
#define PA22_PWM_CH4 0x00001000
#define PA22_UART2_SIRI 0x00003000
#define PA23_UART2_TX 0x00000000
#define PA23_PWM_CH5 0x00004000
#define PA23_UART2_SIROUT 0x0000C000
#define PA24_UART2_CTS 0x00000000
#define PA24_ETB_TRIG0 0x00010000
#define PA24_SPI1_CS1 0x00020000
#define PA25_UART2_RTS 0x00000000
#define PA25_ETB_TRIG1 0x00040000
#define PA25_SPI1_CS2 0x00080000
#define PA26_UART3_TX 0x00000000
#define PA26_PWM_FAULT 0x00100000
#define PA26_UART3_SIROUT 0x00300000
#define PA27_UART3_RX 0x00000000
#define PA27_PWM_CH0 0x00400000
#define PA27_UART3_SIRIN 0x00C00000
#define PA28_I2S_MCLK 0x00000000
#define PA28_PWM_CH1 0x01000000
#define PA29_I2S_SCLK 0x00000000
#define PA29_PWM_CH2 0x04000000
#define PA30_I2S_WSCLK 0x00000000
#define PA30_PWM_CH3 0x10000000
#define PA31_I2S_SDA 0x00000000
#define PA31_I2C0_SCL 0x40000000
#define PA31_PWM_CH4 0x80000000
/* IOMUX1L function definition */
#define PB0_ADC0 0x00000000
#define PB0_I2C0_SDA 0x00000001
#define PB0_PWM_CH5 0x00000002
#define PB1_ADC1 0x00000000
#define PB1_I2C1_SCL 0x00000004
#define PB1_USI_SCLK 0x00000008
#define PB2_ADC2 0x00000000
#define PB2_I2C1_SDA 0x00000010
#define PB2_USI_SD0 0x00000020
#define PB3_ADC3 0x00000000
#define PB3_SPI1_CLK 0x00000040
#define PB3_USI_SD1 0x00000080
#define PB4_ADC4 0x00000000
#define PB4_SPI1_TX 0x00000100
#define PB4_USI_NSS 0x00000200
#define PB5_ADC5 0x00000000
#define PB5_SPI1_RX 0x00000400
#define PB5_USI_SCLK 0x00000800
#define PB6_ADC6 0x00000000
#define PB6_SPI1_CS0 0x00001000
#define PB6_USI_SD0 0x00002000
#define PB7_ADC7 0x00000000
#define PB7_SPI1_CS1 0x00004000
#define PB7_USI_SD1 0x00008000
#define PB8_ETB_TRIG0 0x00000000
#define PB8_SPI1_CS2 0x00010000
#define PB8_USI_NSS 0x00020000
#define PB9_ETB_TRIG1 0x00000000
#define PB9_UART3_CTS 0x00040000
#define PB10_PWM_FAULT 0x00000000
#define PB10_UART3_RTS 0x00100000
/* flag as identification */
#define GPIO_SET_BIT0 0x00000001
#define GPIO_SET_BIT1 0x00000002
#define GPIO_SET_BIT2 0x00000004
#define GPIO_SET_BIT3 0x00000008
#define GPIO_SET_BIT4 0x00000010
#define GPIO_SET_BIT5 0x00000020
#define GPIO_SET_BIT6 0x00000040
#define GPIO_SET_BIT7 0x00000080
#define GPIO_SET_BIT8 0x00000100
#define GPIO_SET_BIT9 0x00000200
#define GPIO_SET_BIT10 0x00000400
#define GPIO_SET_BIT11 0x00000800
#define GPIO_SET_BIT12 0x00001000
#define GPIO_SET_BIT13 0x00002000
#define GPIO_SET_BIT14 0x00004000
#define GPIO_SET_BIT15 0x00008000
#define GPIO_SET_BIT16 0x00010000
#define GPIO_SET_BIT17 0x00020000
#define GPIO_SET_BIT18 0x00040000
#define GPIO_SET_BIT19 0x00080000
#define GPIO_SET_BIT20 0x00100000
#define GPIO_SET_BIT21 0x00200000
#define GPIO_SET_BIT22 0x00400000
#define GPIO_SET_BIT23 0x00800000
#define GPIO_SET_BIT24 0x01000000
#define GPIO_SET_BIT25 0x02000000
#define GPIO_SET_BIT26 0x04000000
#define GPIO_SET_BIT27 0x08000000
#define GPIO_SET_BIT28 0x10000000
#define GPIO_SET_BIT29 0x20000000
#define GPIO_SET_BIT30 0x40000000
#define GPIO_SET_BIT31 0x80000000
/******************************************************************************
* phobos gpio control and gpio reuse function
* selecting regester adddress
******************************************************************************/
#define PHOBOS_GIPO0_PORTCTL_REG 0x50018008
#define PHOBOS_GIPO1_PORTCTL_REG 0x60018008
#define PHOBOS_IOMUX0L_REG 0x50018100
#define PHOBOS_IOMUX0H_REG 0x50018104
#define PHOBOS_IOMUX1L_REG 0x50018108
/*************basic gpio reuse v1.0********************************************
* UART0(PA0,PA1)
* UART1(PA10,PA11)
* UART2(PA22,PA23)
* UART3(PA26,PA27)
* IIS(PA24,PA25,PA26,PA27)
* SPI1(PA16,PA17,PA18)
* IIC0(PA4,PA5)
******************************************************************************/
#define GPIO0_REUSE_EN (GPIO_SET_BIT0|GPIO_SET_BIT1|GPIO_SET_BIT4|GPIO_SET_BIT5|GPIO_SET_BIT6|GPIO_SET_BIT9|GPIO_SET_BIT10|GPIO_SET_BIT11|GPIO_SET_BIT16|GPIO_SET_BIT17|GPIO_SET_BIT18|GPIO_SET_BIT22|GPIO_SET_BIT23|GPIO_SET_BIT26|GPIO_SET_BIT27)
#define GPIO1_REUSE_EN (GPIO_SET_BIT0)
#define IOMUX0L_FUNCTION_SEL (PA0_UART0_TX|PA1_UART0_RX|PA4_I2C0_SCL|PA5_I2C0_SDA|PA6_ETB_TRIG0|PA9_PWM_CH0|PA10_UART1_TX|PA11_UART1_RX)
#define IOMUX0H_FUNCTION_SEL (PA16_SPI1_CLK|PA17_SPI1_TX|PA18_SPI1_RX|PA22_UART2_RX|PA23_UART2_TX|PA26_UART3_TX|PA27_UART3_RX)
#define IOMUX1L_FUNCTION_SEL (PB0_ADC0)
#define PWM_GPIO0_REUSE_EN (GPIO0_REUSE_EN|GPIO_SET_BIT0|GPIO_SET_BIT1|GPIO_SET_BIT2|GPIO_SET_BIT12|GPIO_SET_BIT13|GPIO_SET_BIT14)
#define PWM_IOMUX0L_FUNCTION_SEL (IOMUX0L_FUNCTION_SEL|PA0_PWM_CH0|PA1_PWM_CH1|PA2_PWM_CH2|PA12_PWM_CH3|PA13_PWM_CH4|PA14_PWM_CH5)
#endif /* PHOBOS_PINMUX_H */

318
bsp/ck802/drivers/soc.h Normal file
View File

@ -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 */

View File

@ -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;
}

226
bsp/ck802/gcc_csky.ld Normal file
View File

@ -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_*) }
}

View File

@ -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')

View File

@ -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;
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_aes.h
* @brief header file for aes driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CK_AES_H_
#define _CK_AES_H_
#include <stdio.h>
#include "drv_aes.h"
#include "soc.h"
#define AES_LITTLE_ENDIAN 0x00000100
#define AES_MAX_KEY_LENGTH 32
#define AES_IT_DATAINT 0x4
#define AES_IT_KEYINT 0x2
#define AES_IT_BUSY 0x1
#define AES_IT_ALL 0x7
#define AES_CRYPTO_KEYEXP 0x2
#define AES_WORK_ENABLE_OFFSET 0
#define AES_INT_ENABLE_OFFSET 2
#define AES_MODE_OFFSET 3
#define AES_KEY_LEN_OFFSET 4
#define AES_OPCODE_OFFSET 6
typedef struct {
__IOM uint32_t datain[4]; /* Offset: 0x000 (R/W) Data input 0~127 */
__IOM uint32_t key[8]; /* Offset: 0x010 (R/W) Key 0~255 */
__IOM uint32_t iv[4]; /* Offset: 0x030 (R/W) Initial Vector: 0~127 */
__IOM uint32_t ctrl; /* Offset: 0x040 (R/W) AES Control Register */
__IOM uint32_t state; /* Offset: 0x044 (R/W) AES State Register */
__IOM uint32_t dataout[4]; /* Offset: 0x048 (R/W) Data Output 0~31 */
} ck_aes_reg_t;
#endif

View File

@ -0,0 +1,277 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_crc.c
* @brief CSI Source File for CRC Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdio.h>
#include "drv_crc.h"
#include "ck_crc.h"
#define ERR_CRC(errno) (CSI_DRV_ERRNO_CRC_BASE | errno)
#define CRC_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_CRC(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
crc_event_cb_t cb;
crc_status_t status;
} ck_crc_priv_t;
static ck_crc_priv_t crc_handle[CONFIG_CRC_NUM];
/* Driver Capabilities */
static const crc_capabilities_t driver_capabilities = {
.ROHC = 1, /* ROHC mode */
.MAXIM = 1, /* MAXIM mode */
.X25 = 1, /* X25 mode */
.CCITT = 1, /* CCITT mode */
.USB = 1, /* USB mode */
.IBM = 1, /* IBM mode */
.MODBUS = 1 /* MODBUS mode */
};
//
// Functions
//
static ck_crc_reg_t *crc_reg = NULL;
static int32_t crc_set_mode(crc_mode_e mode, crc_standard_crc_e standard)
{
if (mode == CRC_MODE_CRC16) {
switch (standard) {
case CRC_STANDARD_CRC_MODBUS:
crc_reg->CRC_SEL = 0x0;
crc_reg->CRC_INIT = 0xffff;
break;
case CRC_STANDARD_CRC_IBM:
crc_reg->CRC_SEL = 0x0;
crc_reg->CRC_INIT = 0x0;
break;
case CRC_STANDARD_CRC_MAXIM:
crc_reg->CRC_SEL = 0x4;
crc_reg->CRC_INIT = 0x0;
break;
case CRC_STANDARD_CRC_USB:
crc_reg->CRC_SEL = 0x4;
crc_reg->CRC_INIT = 0xffff;
break;
case CRC_STANDARD_CRC_CCITT:
crc_reg->CRC_SEL = 0x1;
crc_reg->CRC_INIT = 0x0;
break;
case CRC_STANDARD_CRC_X25:
crc_reg->CRC_SEL = 0x5;
crc_reg->CRC_INIT = 0xffff;
break;
default:
return ERR_CRC(EDRV_PARAMETER);
}
} else if (mode == CRC_MODE_CRC8) {
switch (standard) {
case CRC_STANDARD_CRC_MAXIM:
crc_reg->CRC_SEL = 0x2;
crc_reg->CRC_INIT = 0x0;
break;
case CRC_STANDARD_CRC_ROHC:
crc_reg->CRC_SEL = 0x3;
crc_reg->CRC_INIT = 0xff;
break;
default:
return ERR_CRC(EDRV_PARAMETER);
}
} else {
return ERR_CRC(EDRV_PARAMETER);
}
return 0;
}
static int32_t crc_set_data(uint32_t data)
{
crc_reg->CRC_DATA = data;
return 0;
}
static int32_t crc_get_data(uint32_t *data)
{
*data = crc_reg->CRC_DATA;
return 0;
}
int32_t __attribute__((weak)) target_get_crc_count(void)
{
return 0;
}
int32_t __attribute__((weak)) target_get_crc(int32_t idx, uint32_t *base)
{
return NULL;
}
/**
\brief get crc handle count.
\return crc handle count
*/
int32_t csi_crc_get_instance_count(void)
{
return target_get_crc_count();
}
/**
\brief Initialize CRC Interface. 1. Initializes the resources needed for the CRC interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_crc_get_handle_count()
\param[in] cb_event Pointer to \ref crc_event_cb_t
\return return crc handle if success
*/
crc_handle_t csi_crc_initialize(int32_t idx, crc_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_CRC_NUM) {
return NULL;
}
/* obtain the crc information */
uint32_t base = 0u;
int32_t real_idx = target_get_crc(idx, &base);
if (real_idx != idx) {
return NULL;
}
ck_crc_priv_t *crc_priv = &crc_handle[idx];
crc_reg = (ck_crc_reg_t *)(crc_priv->base);
crc_priv->base = base;
crc_priv->cb = cb_event;
crc_priv->status.busy = 0;
return (crc_handle_t)crc_priv;
}
/**
\brief De-initialize CRC Interface. stops operation and releases the software resources used by the interface
\param[in] handle crc handle to operate.
\return error code
*/
int32_t csi_crc_uninitialize(crc_handle_t handle)
{
CRC_NULL_PARAM_CHK(handle);
ck_crc_priv_t *crc_priv = handle;
crc_priv->cb = NULL;
return 0;
}
/**
\brief Get driver capabilities.
\param[in] handle crc handle to operate.
\return \ref crc_capabilities_t
*/
crc_capabilities_t csi_crc_get_capabilities(crc_handle_t handle)
{
return driver_capabilities;
}
/**
\brief config crc mode.
\param[in] handle crc handle to operate.
\param[in] mode \ref crc_mode_e
\param[in] standard \ref crc_standard_crc_e
\return error code
*/
int32_t csi_crc_config(crc_handle_t handle, crc_mode_e mode, crc_standard_crc_e standard)
{
CRC_NULL_PARAM_CHK(handle);
/* set the crc mode */
uint32_t ret = crc_set_mode(mode, standard);
return ret;
}
/**
\brief calculate crc.
\param[in] handle crc handle to operate.
\param[in] in Pointer to the input data
\param[out] out Pointer to the result.
\param[in] len intpu data len.
\return error code
*/
int32_t csi_crc_calculate(crc_handle_t handle, const void *in, void *out, uint32_t len)
{
CRC_NULL_PARAM_CHK(handle);
CRC_NULL_PARAM_CHK(in);
CRC_NULL_PARAM_CHK(out);
if (len <= 0) {
return ERR_CRC(EDRV_PARAMETER);
}
ck_crc_priv_t *crc_priv = handle;
crc_reg = (ck_crc_reg_t *)(crc_priv->base);
crc_priv->status.busy = 1;
/* put the data int the register */
uint8_t cur;
uint8_t *p = (uint8_t *)in;
for (cur=0; cur<len - 3; cur += 4, p+=4) {
crc_set_data(p[0]
| (p[1] << 8)
| (p[2] << 16)
| (p[3] << 24));
}
uint32_t data = 0;
uint8_t i;
if (cur < len) {
for (i=0; i<len-cur; i++) {
data |= (p[cur + i] << (i*8));
}
crc_set_data(data);
}
crc_get_data((uint32_t *)out);
crc_priv->status.busy = 0;
return 0;
}
/**
\brief Get CRC status.
\param[in] handle crc handle to operate.
\return CRC status \ref crc_status_t
*/
crc_status_t csi_crc_get_status(crc_handle_t handle)
{
ck_crc_priv_t *crc_priv = handle;
return crc_priv->status;
}

View File

@ -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

View File

@ -0,0 +1,517 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_dmac.c
* @brief CSI Source File for DMAC Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdbool.h>
#include "ck_dmac.h"
#include "csi_core.h"
#include "drv_dmac.h"
#include "soc.h"
#define ERR_DMA(errno) (CSI_DRV_ERRNO_DMA_BASE | errno)
typedef struct {
uint32_t base;
uint32_t irq;
dma_event_cb_t cb_event;
uint8_t ch_num;
} ck_dma_priv_t;
static ck_dma_priv_t dma_instance[CONFIG_DMAC_NUM];
static const dma_capabilities_t dma_capabilities = {
.unalign_addr = 1, ///< support for unalign address transfer when memory is source
};
static volatile dma_status_e status[CK_DMA_MAXCHANNEL] = {DMA_STATE_FREE, DMA_STATE_FREE};
static volatile uint8_t ch_opened[CK_DMA_MAXCHANNEL] = {0, 0};
static int32_t ck_dma_set_channel(ck_dma_reg_t *addr, uint32_t source, uint32_t dest, uint32_t size)
{
uint32_t temp = addr->CHCTRLA;
temp &= 0xff000fff;
temp |= (size << 12);
addr->SAR = source;
addr->DAR = dest ;
addr->CHCTRLA = temp;
return 0;
}
static int32_t ck_dma_set_transfertype(ck_dma_reg_t *addr, dma_trans_type_e transtype)
{
uint32_t temp = addr->CHCTRLB;
temp &= 0xffffff7f;
if (transtype >= DMA_PERH2PERH) {
return ERR_DMA(EDRV_PARAMETER);
}
if (transtype == DMA_MEM2MEM) {
temp |= (transtype << 7);
} else {
temp |= (1 << 7);
}
addr->CHCTRLB = temp;
return 0;
}
static int32_t ck_dma_set_addrinc(ck_dma_reg_t *addr, enum_addr_state_e src_addrinc, enum_addr_state_e dst_addrinc)
{
if ((src_addrinc != DMA_ADDR_INCREMENT && src_addrinc != DMA_ADDR_DECREMENT && src_addrinc != DMA_ADDR_NOCHANGE) ||
(dst_addrinc != DMA_ADDR_INCREMENT && dst_addrinc != DMA_ADDR_DECREMENT && dst_addrinc != DMA_ADDR_NOCHANGE)) {
return ERR_DMA(EDRV_PARAMETER);
}
uint32_t temp = addr->CHCTRLA;
temp &= 0xffffff0f;
temp |= (src_addrinc << 6);
temp |= (dst_addrinc << 4);
addr->CHCTRLA = temp;
return 0;
}
static int32_t ck_dma_set_transferwidth(ck_dma_reg_t *addr, dma_datawidth_e src_width, dma_datawidth_e dst_width)
{
if ((src_width != DMA_DATAWIDTH_SIZE8 && src_width != DMA_DATAWIDTH_SIZE16 && src_width != DMA_DATAWIDTH_SIZE32) ||
(dst_width != DMA_DATAWIDTH_SIZE8 && dst_width != DMA_DATAWIDTH_SIZE16 && dst_width != DMA_DATAWIDTH_SIZE32)) {
return ERR_DMA(EDRV_PARAMETER);
}
uint32_t temp = addr->CHCTRLA;
temp &= 0xfffffff0;
temp |= (src_width - 1) << 2;
temp |= dst_width - 1;
addr->CHCTRLA = temp;
return 0;
}
static int32_t ck_dma_set_burstlength(ck_dma_reg_t *addr, uint8_t burstlength)
{
uint32_t temp = addr->CHCTRLA;
temp &= 0xfffff0ff;
temp |= (burstlength << 8);
addr->CHCTRLA = temp;
return 0;
}
/**
\brief Set software or hardware handshaking.
\param[in] addr pointer to dma register.
\return error code
*/
static int32_t ck_dma_set_handshaking(ck_dma_reg_t *addr, dma_handshaking_select_e handshaking)
{
uint32_t temp = addr->CHCTRLB;
temp &= 0xfffffeff;
temp |= (handshaking << 8);
addr->CHCTRLB = temp;
return 0;
}
static int ck_dma_assign_hdhs_interface(ck_dma_reg_t *addr, ckenum_dma_device_e device)
{
if (device < 0 || device >= CKENUM_DMA_MEMORY) {
return ERR_DMA(EDRV_PARAMETER);
}
addr->CHCTRLB &= 0xffffe1ff;
addr->CHCTRLB |= (device << 9);
return 0;
}
void ck_dma_irqhandler(int32_t idx)
{
ck_dma_priv_t *dma_priv = &dma_instance[idx];
ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base);
/*
* StatusInt_temp contain the information that which types of interrupr are
* requested.
*/
int32_t count = 0;
uint32_t temp = 0;
for (count = 0; count < dma_priv->ch_num; count++) {
addr = (ck_dma_reg_t *)(dma_priv->base + count * 0x30);
temp = addr->CHINTS;
if (temp != 0) {
break;
}
}
/* If Tfr interrupt is requested */
if (temp == CK_DMA_TFR) {
status[count] = DMA_STATE_DONE;
addr->CHINTC = temp;
if (dma_priv->cb_event) {
dma_priv->cb_event(DMA_EVENT_TRANSFER_DONE, count);
}
}
/* If Err interrput is requested */
if (temp == CK_DMA_ERR) {
status[count] = DMA_STATE_ERROR;
addr->CHINTC = temp;
if (dma_priv->cb_event) {
dma_priv->cb_event(DMA_EVENT_TRANSFER_ERROR, count);
}
}
}
int32_t __attribute__((weak)) target_get_dmac_count(void)
{
return 0;
}
int32_t __attribute__((weak)) target_get_dmac(uint32_t idx, uint32_t *base, uint32_t *irq)
{
return NULL;
}
/**
\brief get dma instance count.
\return dma instance count
*/
int32_t csi_dma_get_instance_count(void)
{
return target_get_dmac_count();
}
/**
\brief Initialize DMA Interface. 1. Initializes the resources needed for the DMA interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_dma_get_instance_count()
\return pointer to dma instances
*/
dmac_handle_t csi_dma_initialize(int32_t idx)
{
if (idx < 0 || idx >= CONFIG_DMAC_NUM) {
return NULL;
}
uint32_t base = 0u;
uint32_t irq = 0u;
int32_t real_idx = target_get_dmac(idx, &base, &irq);
if (real_idx != idx) {
return NULL;
}
ck_dma_priv_t *dma_priv = &dma_instance[idx];
dma_priv->base = base;
dma_priv->irq = irq;
dma_priv->ch_num = CK_DMA_MAXCHANNEL;
drv_nvic_enable_irq(dma_priv->irq);
uint8_t count = 0u;
for (count = 0; count < dma_priv->ch_num; count++) {
ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base + count * 0x30);
addr->CHINTM = CK_DMA_MASK;
addr->CHINTC = CK_DMA_INTC;
}
return (dmac_handle_t)dma_priv;
}
/**
\brief De-initialize DMA Interface. stops operation and releases the software resources used by the interface
\param[in] handle damc handle to operate.
\return error code
*/
int32_t csi_dma_uninitialize(dmac_handle_t handle)
{
if (handle == NULL) {
return ERR_DMA(EDRV_PARAMETER);
}
ck_dma_priv_t *dma_priv = handle;
ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base);
uint8_t count;
for (count = 0; count < dma_priv->ch_num; count++) {
addr = (ck_dma_reg_t *)(dma_priv->base + count * 0x30);
addr->CHINTM = CK_DMA_MASK;
addr->CHINTC = CK_DMA_INTC;
}
drv_nvic_disable_irq(dma_priv->irq);
return 0;
}
/**
\brief Get driver capabilities.
\param[in] handle damc handle to operate.
\return \ref dma_capabilities_t
*/
dma_capabilities_t csi_dma_get_capabilities(dmac_handle_t handle)
{
return dma_capabilities;
}
/**
\brief get one free dma channel
\param[in] handle damc handle to operate.
\param[in] ch channel num. if -1 then allocate a free channal in this dma
\return -1 - no channel can be used, other - channel index
*/
int32_t csi_dma_alloc_channel(dmac_handle_t handle, int32_t ch)
{
ck_dma_priv_t *dma_priv = handle;
if (handle == NULL || ch > dma_priv->ch_num) {
return ERR_DMA(EDRV_PARAMETER);
}
uint8_t ch_num = 0;
ck_dma_reg_t *addr = NULL;
if (ch == -1) { // alloc a free channal
for (ch_num = 0; ch_num < dma_priv->ch_num; ch_num++) {
addr = (ck_dma_reg_t *)(dma_priv->base + ch_num * 0x30);
if (ch_opened[ch_num] != 0x1) {
ch_opened[ch_num] = 1;
break;
}
}
if (ch_num >= dma_priv->ch_num) {
return -1;
}
} else { //alloc a fixed channel
addr = (ck_dma_reg_t *)(dma_priv->base + ch * 0x30);
if (ch_opened[ch] == 0x1) {
return ERR_DMA(EDRV_BUSY);
}
ch_opened[ch] = 1;
ch_num = ch;
}
addr->CHINTC = CK_DMA_INTC;
addr->CHINTM &= ~CK_DMA_MASK;
status[ch_num] = DMA_STATE_READY;
return ch_num;
}
/**
\brief release dma channel and related resources
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return error code
*/
int32_t csi_dma_release_channel(dmac_handle_t handle, int32_t ch)
{
ck_dma_priv_t *dma_priv = handle;
if (handle == NULL || ch >= dma_priv->ch_num || ch < 0) {
return ERR_DMA(EDRV_PARAMETER);
}
ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base + ch * 0x30);
status[ch] = DMA_STATE_FREE;
ch_opened[ch] = 0;
addr->CHINTC = CK_DMA_INTC;
addr->CHINTM = CK_DMA_MASK;
return 0;
}
/**
\brief
\param[in] handle damc handle to operate.
\param[in] ch channel num. if -1 then allocate a free channal in this dma
\param[in] psrcaddr dma transfer source address
\param[in] pstdaddr dma transfer source address
\param[in] length dma transfer length
\param[in] config dma transfer configure
\param[in] cb_event Pointer to \ref dma_event_cb_t
\return error code
*/
int32_t csi_dma_config(dmac_handle_t handle, int32_t ch,
void *psrcaddr, void *pstdaddr,
uint32_t length, dma_config_t *config, dma_event_cb_t cb_event)
{
ck_dma_priv_t *dma_priv = handle;
if (handle == NULL || ch >= dma_priv->ch_num || config == NULL) {
return ERR_DMA(EDRV_PARAMETER);
}
if (ch == -1) { //alloc a free channel
ch = csi_dma_alloc_channel(handle, -1);
if (ch < 0) {
return ERR_DMA(EDRV_BUSY);
}
}
dma_priv->cb_event = cb_event;
ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base + ch * 0x30);
/* Initializes corresponding channel registers */
if ((length * config->src_tw) % config->dst_tw != 0) {
return ERR_DMA(EDRV_PARAMETER);
}
int32_t ret = ck_dma_set_transferwidth(addr, config->src_tw, config->dst_tw);
if (ret) {
return ret;
}
int32_t grouplen = ((length * config->src_tw / config->dst_tw) - 1) % 16;
ck_dma_set_burstlength(addr, grouplen);
ret = ck_dma_set_transfertype(addr, config->type);
if (ret < 0) {
return ret;
}
if (config->type == DMA_MEM2MEM) {
ck_dma_set_handshaking(addr, DMA_HANDSHAKING_SOFTWARE);
ret = ck_dma_set_addrinc(addr , config->src_inc, config->dst_inc);
} else if (config->type == DMA_MEM2PERH) {
ck_dma_set_handshaking(addr, DMA_HANDSHAKING_HARDWARE);
ret = ck_dma_set_addrinc(addr , config->src_inc, config->dst_inc);
if (ret) {
return ret;
}
ret = ck_dma_assign_hdhs_interface(addr, config->hs_if);
if (ret) {
return ret;
}
} else if (config->type == DMA_PERH2MEM) {
ck_dma_set_handshaking(addr, DMA_HANDSHAKING_HARDWARE);
ret = ck_dma_set_addrinc(addr , config->src_inc, config->dst_inc);
if (ret) {
return ret;
}
ret = ck_dma_assign_hdhs_interface(addr, config->hs_if);
if (ret) {
return ret;
}
}
ck_dma_set_channel(addr, (uint32_t)psrcaddr, (uint32_t)pstdaddr, length);
status[ch] = DMA_STATE_READY;
return 0;
}
/**
\brief start generate dma signal.
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return error code
*/
int32_t csi_dma_start(dmac_handle_t handle, int32_t ch)
{
ck_dma_priv_t *dma_priv = handle;
if (handle == NULL || ch >= dma_priv->ch_num || ch < 0) {
return ERR_DMA(EDRV_PARAMETER);
}
status[ch] = DMA_STATE_BUSY;
ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base + ch * 0x30);
addr->CHCTRLB |= CK_DMA_INT_EN; // interrupt enable
addr->CHEN |= CK_DMA_CH_EN;
return 0;
}
/**
\brief Stop generate dma signal.
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return error code
*/
int32_t csi_dma_stop(dmac_handle_t handle, int32_t ch)
{
if (handle == NULL) {
return ERR_DMA(EDRV_PARAMETER);
}
ck_dma_priv_t *dma_priv = handle;
if (ch >= dma_priv->ch_num || ch < 0) {
return ERR_DMA(EDRV_PARAMETER);
}
status[ch] = DMA_STATE_DONE;
ck_dma_reg_t *addr = (ck_dma_reg_t *)(dma_priv->base + ch * 0x30);
addr->CHCTRLB &= ~CK_DMA_INT_EN; // interrupt disable
addr->CHEN &= ~CK_DMA_CH_EN;
return 0;
}
/**
\brief Get DMA status.
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return DMA status \ref dma_status_t
*/
dma_status_e csi_dma_get_status(dmac_handle_t handle, int32_t ch)
{
if (handle == NULL) {
return ERR_DMA(EDRV_PARAMETER);
}
ck_dma_priv_t *dma_priv = handle;
if (ch >= dma_priv->ch_num || ch < 0) {
return ERR_DMA(EDRV_PARAMETER);
}
return status[ch];
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_dmac.h
* @brief header file for DMAC Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef __CK_DMA_H
#define __CK_DMA_H
#include <stdio.h>
#include "soc.h"
#define CK_DMA_MAXCHANNEL 2
#define CK_DMA_INT_EN 1
#define CK_DMA_CH_EN 1
#define CK_DMA_TFR 0x0002
#define CK_DMA_ERR 0x0001
#define CK_DMA_INTC 0x03
#define CK_DMA_MASK 0x03
typedef enum {
DMA_ADDR_INCREMENT = 0,
DMA_ADDR_DECREMENT = 1,
DMA_ADDR_NOCHANGE = 2
} enum_addr_state_e;
typedef enum {
DMA_DATAWIDTH_SIZE8 = 1,
DMA_DATAWIDTH_SIZE16 = 2,
DMA_DATAWIDTH_SIZE32 = 4
} dma_datawidth_e;
typedef enum {
DMA_HANDSHAKING_HARDWARE = 0,
DMA_HANDSHAKING_SOFTWARE = 1,
} dma_handshaking_select_e;
typedef enum {
DMA_PRIORITY0 = 0,
DMA_PRIORITY1 = 1,
DMA_PRIOTITY2 = 2,
DMA_PRIOTITY3 = 3
} dma_priority_t;
typedef struct {
__IOM uint32_t SAR; /* offset: 0x00 (R/W) Channel Source Address Register */
__IOM uint32_t DAR; /* offset: 0x04 (R/W) Channel Destination Address Register */
__IOM uint32_t CHCTRLA; /* offset: 0x08 (R/W) Channel Control Register A */
__IOM uint32_t CHCTRLB; /* offset: 0x0C (R/W) Channel Control Register B */
__IOM uint8_t CHINTM:2; /* offset: 0x10 (R/W) Channel Interrupt Mask Register */
uint8_t RESERVED0[3];
__IM uint8_t CHINTS:2; /* offset: 0x14 (R/ ) Channel Interrupt Status Register */
uint8_t RESERVED1[3];
__IOM uint8_t CHINTC:2; /* offset: 0x18 (R/W) Channel Interrupt Clear Register */
uint8_t RESERVED2[3];
__IOM uint8_t CHSREQ:1; /* offset: 0x1C (R/W) Channel Software Request Register */
uint8_t RESERVED3[3];
__IOM uint8_t CHEN:1; /* offset: 0x20 (R/W) Channel Enable Register */
uint8_t RESERVED4[3];
} ck_dma_reg_t;
#endif /* __CK_DMA_H */

View File

@ -0,0 +1,288 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_eflash.c
* @brief CSI Source File for Embedded Flash Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdio.h>
#include "drv_eflash.h"
#include "ck_eflash.h"
#define ERR_EFLASH(errno) (CSI_DRV_ERRNO_EFLASH_BASE | errno)
#define EFLASH_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_EFLASH(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
eflash_info eflashinfo;
eflash_event_cb_t cb;
eflash_status_t status;
} ck_eflash_priv_t;
static ck_eflash_priv_t eflash_handle[CONFIG_EFLASH_NUM];
/* Driver Capabilities */
static const eflash_capabilities_t driver_capabilities = {
.event_ready = 1, /* event_ready */
.data_width = 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
.erase_chip = 0 /* erase_chip */
};
//
// Functions
//
static int32_t eflash_program_word(eflash_handle_t handle, uint32_t dstaddr, uint32_t *srcbuf, uint32_t len)
{
ck_eflash_priv_t *eflash_priv = handle;
uint32_t fbase = eflash_priv->base;
uint32_t i;
for (i = 0; i < len; i++) {
*(volatile uint32_t *)(fbase + 0x04) = dstaddr;
*(volatile uint32_t *)(fbase + 0x1c) = *srcbuf;
*(volatile uint32_t *)(fbase + 0x18) = 1;
srcbuf++;
dstaddr += 4;
}
return (i << 2);
}
int32_t __attribute__((weak)) target_get_eflash_count(void)
{
return 0;
}
int32_t __attribute__((weak)) target_get_eflash(int32_t idx, uint32_t *base, eflash_info *info)
{
return NULL;
}
/**
\brief get eflash handle count.
\return eflash handle count
*/
int32_t csi_eflash_get_instance_count(void)
{
return target_get_eflash_count();
}
/**
\brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_eflash_get_instance_count()
\param[in] cb_event Pointer to \ref eflash_event_cb_t
\return pointer to eflash handle
*/
eflash_handle_t csi_eflash_initialize(int32_t idx, eflash_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_EFLASH_NUM) {
return NULL;
}
/* obtain the eflash information */
uint32_t base = 0u;
eflash_info info;
int32_t real_idx = target_get_eflash(idx, &base, &info);
if (real_idx != idx) {
return NULL;
}
ck_eflash_priv_t *eflash_priv = &eflash_handle[idx];
eflash_priv->base = base;
eflash_priv->eflashinfo.start = info.start;
eflash_priv->eflashinfo.end = info.end;
eflash_priv->eflashinfo.sector_count = info.sector_count;
/* initialize the eflash context */
eflash_priv->cb = cb_event;
eflash_priv->status.busy = 0;
eflash_priv->status.error = 0U;
eflash_priv->eflashinfo.sector_size = EFLASH_SECTOR_SIZE;
eflash_priv->eflashinfo.page_size = EFLASH_PAGE_SIZE;
eflash_priv->eflashinfo.program_unit = EFLASH_PROGRAM_UINT;
eflash_priv->eflashinfo.erased_value = EFLASH_ERASED_VALUE;
return (eflash_handle_t)eflash_priv;
}
/**
\brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface
\param[in] handle eflash handle to operate.
\return error code
*/
int32_t csi_eflash_uninitialize(eflash_handle_t handle)
{
EFLASH_NULL_PARAM_CHK(handle);
ck_eflash_priv_t *eflash_priv = handle;
eflash_priv->cb = NULL;
return 0;
}
/**
\brief Get driver capabilities.
\param[in] eflash handle to operate.
\return \ref eflash_capabilities_t
*/
eflash_capabilities_t csi_eflash_get_capabilities(eflash_handle_t handle)
{
return driver_capabilities;
}
/**
\brief Read data from Flash.
\param[in] handle eflash handle to operate.
\param[in] addr Data address.
\param[out] data Pointer to a buffer storing the data read from Flash.
\param[in] cnt Number of data items to read.
\return number of data items read or error code
*/
int32_t csi_eflash_read(eflash_handle_t handle, uint32_t addr, void *data, uint32_t cnt)
{
EFLASH_NULL_PARAM_CHK(handle);
EFLASH_NULL_PARAM_CHK(data);
EFLASH_NULL_PARAM_CHK(cnt);
if (!IS_EFLASH_ADDR(addr) || !(IS_EFLASH_ADDR(addr + cnt -1))) {
return ERR_EFLASH(EDRV_PARAMETER);
}
volatile uint8_t *src_addr = (uint8_t *)addr;
ck_eflash_priv_t *eflash_priv = handle;
if (eflash_priv->status.busy) {
return ERR_EFLASH(EDRV_BUSY);
}
eflash_priv->status.error = 0U;
int i;
for (i = 0; i < cnt; i++) {
*((uint8_t *)data + i) = *(src_addr + i);
}
return i;
}
/**
\brief Program data to Flash.
\param[in] handle eflash handle to operate.
\param[in] addr Data address.
\param[in] data Pointer to a buffer containing the data to be programmed to Flash..
\param[in] cnt Number of data items to program.
\return number of data items programmed or error code
*/
int32_t csi_eflash_program(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt)
{
EFLASH_NULL_PARAM_CHK(handle);
EFLASH_NULL_PARAM_CHK(data);
EFLASH_NULL_PARAM_CHK(cnt);
if (!IS_EFLASH_ADDR(addr) || !(IS_EFLASH_ADDR(addr + cnt -1))) {
return ERR_EFLASH(EDRV_PARAMETER);
}
ck_eflash_priv_t *eflash_priv = handle;
if ((addr & 0x3) || ((uint32_t)data & 0x3) || (cnt & 0x3)) {
return ERR_EFLASH(EDRV_PARAMETER);
}
if (eflash_priv->status.busy) {
return ERR_EFLASH(EDRV_BUSY);
}
eflash_priv->status.busy = 1U;
eflash_priv->status.error = 0U;
uint32_t ret = eflash_program_word(handle, addr, (uint32_t *)data, cnt >> 2);
eflash_priv->status.busy = 0U;
return ret;
}
/**
\brief Erase Flash Sector.
\param[in] handle eflash handle to operate.
\param[in] addr Sector address
\return error code
*/
int32_t csi_eflash_erase_sector(eflash_handle_t handle, uint32_t addr)
{
EFLASH_NULL_PARAM_CHK(handle);
if (!IS_EFLASH_ADDR(addr)) {
return ERR_EFLASH(EDRV_PARAMETER);
}
addr = addr & ~(EFLASH_SECTOR_SIZE - 1);
ck_eflash_priv_t *eflash_priv = handle;
uint32_t fbase = eflash_priv->base;
if (eflash_priv->status.busy) {
return ERR_EFLASH(EDRV_BUSY);
}
eflash_priv->status.busy = 1U;
eflash_priv->status.error = 0U;
*(volatile uint32_t *)(fbase + 0x4) = addr;
*(volatile uint32_t *)(fbase + 0x10) = 0x1;
eflash_priv->status.busy = 0U;
return 0;
}
/**
\brief Erase complete Flash.
\param[in] handle eflash handle to operate.
\return error code
*/
int32_t csi_eflash_erase_chip(eflash_handle_t handle)
{
EFLASH_NULL_PARAM_CHK(handle);
return ERR_EFLASH(EDRV_UNSUPPORTED);
}
/**
\brief Get Flash information.
\param[in] handle eflash handle to operate.
\return Pointer to Flash information \ref eflash_info
*/
eflash_info *csi_eflash_get_info(eflash_handle_t handle)
{
ck_eflash_priv_t *eflash_priv = handle;
eflash_info *eflash_info = &(eflash_priv->eflashinfo);
return eflash_info;
}
/**
\brief Get EFLASH status.
\param[in] handle eflash handle to operate.
\return EFLASH status \ref eflash_status_t
*/
eflash_status_t csi_eflash_get_status(eflash_handle_t handle)
{
ck_eflash_priv_t *eflash_priv = handle;
return eflash_priv->status;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,427 @@
/****************************************************************************
* csky/hardware/bsp/common/ethernet_enc28j60/ethernet_enc28j60.h
*
* Copyright (C) 2016 The YunOS Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
****************************************************************************/
#ifndef _ETHERNET_ENC28J60_H__
#define _ETHERNET_ENC28J60_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/* ****** ETH ****** */
#define ETH_HEADER_LEN 14
/* values of certain bytes: */
#define ETHTYPE_ARP_H_V 0x08
#define ETHTYPE_ARP_L_V 0x06
#define ETHTYPE_IP_H_V 0x08
#define ETHTYPE_IP_L_V 0x00
/* byte positions in the ethernet frame:
Ethernet type field (2bytes): */
#define ETH_TYPE_H_P 12
#define ETH_TYPE_L_P 13
#define ETH_DST_MAC 0
#define ETH_SRC_MAC 6
/* ******* ARP ******* */
#define ETH_ARP_OPCODE_REPLY_H_V 0x0
#define ETH_ARP_OPCODE_REPLY_L_V 0x02
#define ETHTYPE_ARP_L_V 0x06
/* arp.dst.ip */
#define ETH_ARP_DST_IP_P 0x26
/* arp.opcode */
#define ETH_ARP_OPCODE_H_P 0x14
#define ETH_ARP_OPCODE_L_P 0x15
/* arp.src.mac */
#define ETH_ARP_SRC_MAC_P 0x16
#define ETH_ARP_SRC_IP_P 0x1c
#define ETH_ARP_DST_MAC_P 0x20
#define ETH_ARP_DST_IP_P 0x26
/* ******* IP ******* */
#define IP_HEADER_LEN 20
/* ip.src */
#define IP_SRC_P 0x1a
#define IP_DST_P 0x1e
#define IP_HEADER_LEN_VER_P 0xe
#define IP_CHECKSUM_P 0x18
#define IP_TTL_P 0x16
#define IP_FLAGS_P 0x14
#define IP_P 0xe
#define IP_TOTLEN_H_P 0x10
#define IP_TOTLEN_L_P 0x11
#define IP_PROTO_P 0x17
#define IP_PROTO_ICMP_V 1
#define IP_PROTO_TCP_V 6
/* 17=0x11 */
#define IP_PROTO_UDP_V 17
/* ******* ICMP ******* */
#define ICMP_TYPE_ECHOREPLY_V 0
#define ICMP_TYPE_ECHOREQUEST_V 8
#define ICMP_TYPE_P 0x22
#define ICMP_CHECKSUM_P 0x24
/* ******* UDP ******* */
#define UDP_HEADER_LEN 8
#define UDP_SRC_PORT_H_P 0x22
#define UDP_SRC_PORT_L_P 0x23
#define UDP_DST_PORT_H_P 0x24
#define UDP_DST_PORT_L_P 0x25
#define UDP_LEN_H_P 0x26
#define UDP_LEN_L_P 0x27
#define UDP_CHECKSUM_H_P 0x28
#define UDP_CHECKSUM_L_P 0x29
#define UDP_DATA_P 0x2a
/* ******* TCP ******* */
#define TCP_SRC_PORT_H_P 0x22
#define TCP_SRC_PORT_L_P 0x23
#define TCP_DST_PORT_H_P 0x24
#define TCP_DST_PORT_L_P 0x25
/* the tcp seq number is 4 bytes 0x26-0x29 */
#define TCP_SEQ_H_P 0x26
#define TCP_SEQACK_H_P 0x2a
/* flags: SYN=2 */
#define TCP_FLAGS_P 0x2f
#define TCP_FLAGS_SYN_V 2
#define TCP_FLAGS_FIN_V 1
#define TCP_FLAGS_PUSH_V 8
#define TCP_FLAGS_SYNACK_V 0x12
#define TCP_FLAGS_ACK_V 0x10
#define TCP_FLAGS_PSHACK_V 0x18
/* plain len without the options: */
#define TCP_HEADER_LEN_PLAIN 20
#define TCP_HEADER_LEN_P 0x2e
#define TCP_CHECKSUM_H_P 0x32
#define TCP_CHECKSUM_L_P 0x33
#define TCP_OPTIONS_P 0x36
/* ENC28J60 Control Registers
Control register definitions are a combination of address,
bank number, and Ethernet/MAC/PHY indicator bits.
- Register address (bits 0-4)
- Bank number (bits 5-6)
- MAC/PHY indicator (bit 7) */
#define ADDR_MASK 0x1F
#define BANK_MASK 0x60
#define SPRD_MASK 0x80
/* All-bank registers */
#define EIE 0x1B
#define EIR 0x1C
#define ESTAT 0x1D
#define ECON2 0x1E
#define ECON1 0x1F
/* Bank 0 registers */
#define ERDPTL (0x00|0x00)
#define ERDPTH (0x01|0x00)
#define EWRPTL (0x02|0x00)
#define EWRPTH (0x03|0x00)
#define ETXSTL (0x04|0x00)
#define ETXSTH (0x05|0x00)
#define ETXNDL (0x06|0x00)
#define ETXNDH (0x07|0x00)
#define ERXSTL (0x08|0x00)
#define ERXSTH (0x09|0x00)
#define ERXNDL (0x0A|0x00)
#define ERXNDH (0x0B|0x00)
#define ERXRDPTL (0x0C|0x00)
#define ERXRDPTH (0x0D|0x00)
#define ERXWRPTL (0x0E|0x00)
#define ERXWRPTH (0x0F|0x00)
#define EDMASTL (0x10|0x00)
#define EDMASTH (0x11|0x00)
#define EDMANDL (0x12|0x00)
#define EDMANDH (0x13|0x00)
#define EDMADSTL (0x14|0x00)
#define EDMADSTH (0x15|0x00)
#define EDMACSL (0x16|0x00)
#define EDMACSH (0x17|0x00)
/* Bank 1 registers */
#define EHT0 (0x00|0x20)
#define EHT1 (0x01|0x20)
#define EHT2 (0x02|0x20)
#define EHT3 (0x03|0x20)
#define EHT4 (0x04|0x20)
#define EHT5 (0x05|0x20)
#define EHT6 (0x06|0x20)
#define EHT7 (0x07|0x20)
#define EPMM0 (0x08|0x20)
#define EPMM1 (0x09|0x20)
#define EPMM2 (0x0A|0x20)
#define EPMM3 (0x0B|0x20)
#define EPMM4 (0x0C|0x20)
#define EPMM5 (0x0D|0x20)
#define EPMM6 (0x0E|0x20)
#define EPMM7 (0x0F|0x20)
#define EPMCSL (0x10|0x20)
#define EPMCSH (0x11|0x20)
#define EPMOL (0x14|0x20)
#define EPMOH (0x15|0x20)
#define EWOLIE (0x16|0x20)
#define EWOLIR (0x17|0x20)
#define ERXFCON (0x18|0x20)
#define EPKTCNT (0x19|0x20)
/* Bank 2 registers */
#define MACON1 (0x00|0x40|0x80)
#define MACON2 (0x01|0x40|0x80)
#define MACON3 (0x02|0x40|0x80)
#define MACON4 (0x03|0x40|0x80)
#define MABBIPG (0x04|0x40|0x80)
#define MAIPGL (0x06|0x40|0x80)
#define MAIPGH (0x07|0x40|0x80)
#define MACLCON1 (0x08|0x40|0x80)
#define MACLCON2 (0x09|0x40|0x80)
#define MAMXFLL (0x0A|0x40|0x80)
#define MAMXFLH (0x0B|0x40|0x80)
#define MAPHSUP (0x0D|0x40|0x80)
#define MICON (0x11|0x40|0x80)
#define MICMD (0x12|0x40|0x80)
#define MIREGADR (0x14|0x40|0x80)
#define MIWRL (0x16|0x40|0x80)
#define MIWRH (0x17|0x40|0x80)
#define MIRDL (0x18|0x40|0x80)
#define MIRDH (0x19|0x40|0x80)
/* Bank 3 registers */
#define MAADR1 (0x00|0x60|0x80)
#define MAADR0 (0x01|0x60|0x80)
#define MAADR3 (0x02|0x60|0x80)
#define MAADR2 (0x03|0x60|0x80)
#define MAADR5 (0x04|0x60|0x80)
#define MAADR4 (0x05|0x60|0x80)
#define EBSTSD (0x06|0x60)
#define EBSTCON (0x07|0x60)
#define EBSTCSL (0x08|0x60)
#define EBSTCSH (0x09|0x60)
#define MISTAT (0x0A|0x60|0x80)
#define EREVID (0x12|0x60)
#define ECOCON (0x15|0x60)
#define EFLOCON (0x17|0x60)
#define EPAUSL (0x18|0x60)
#define EPAUSH (0x19|0x60)
/* PHY registers */
#define PHCON1 0x00
#define PHSTAT1 0x01
#define PHHID1 0x02
#define PHHID2 0x03
#define PHCON2 0x10
#define PHSTAT2 0x11
#define PHIE 0x12
#define PHIR 0x13
#define PHLCON 0x14
/* ENC28J60 ERXFCON Register Bit Definitions */
#define ERXFCON_UCEN 0x80
#define ERXFCON_ANDOR 0x40
#define ERXFCON_CRCEN 0x20
#define ERXFCON_PMEN 0x10
#define ERXFCON_MPEN 0x08
#define ERXFCON_HTEN 0x04
#define ERXFCON_MCEN 0x02
#define ERXFCON_BCEN 0x01
/* ENC28J60 EIE Register Bit Definitions */
#define EIE_INTIE 0x80
#define EIE_PKTIE 0x40
#define EIE_DMAIE 0x20
#define EIE_LINKIE 0x10
#define EIE_TXIE 0x08
#define EIE_WOLIE 0x04
#define EIE_TXERIE 0x02
#define EIE_RXERIE 0x01
#define EIE_ALLCLOSE 0xff
/* ENC28J60 EIR Register Bit Definitions */
#define EIR_PKTIF 0x40
#define EIR_DMAIF 0x20
#define EIR_LINKIF 0x10
#define EIR_TXIF 0x08
#define EIR_WOLIF 0x04
#define EIR_TXERIF 0x02
#define EIR_RXERIF 0x01
#define EIR_ALLINTS 0x7b /* All interrupts */
/* ENC28J60 ESTAT Register Bit Definitions */
#define ESTAT_INT 0x80
#define ESTAT_LATECOL 0x10
#define ESTAT_RXBUSY 0x04
#define ESTAT_TXABRT 0x02
#define ESTAT_CLKRDY 0x01
/* ENC28J60 ECON2 Register Bit Definitions */
#define ECON2_AUTOINC 0x80
#define ECON2_PKTDEC 0x40
#define ECON2_PWRSV 0x20
#define ECON2_VRPS 0x08
/* ENC28J60 ECON1 Register Bit Definitions */
#define ECON1_TXRST 0x80
#define ECON1_RXRST 0x40
#define ECON1_DMAST 0x20
#define ECON1_CSUMEN 0x10
#define ECON1_TXRTS 0x08
#define ECON1_RXEN 0x04
#define ECON1_BSEL1 0x02
#define ECON1_BSEL0 0x01
/* ENC28J60 MACON1 Register Bit Definitions */
#define MACON1_LOOPBK 0x10
#define MACON1_TXPAUS 0x08
#define MACON1_RXPAUS 0x04
#define MACON1_PASSALL 0x02
#define MACON1_MARXEN 0x01
/* ENC28J60 MACON2 Register Bit Definitions */
#define MACON2_MARST 0x80
#define MACON2_RNDRST 0x40
#define MACON2_MARXRST 0x08
#define MACON2_RFUNRST 0x04
#define MACON2_MATXRST 0x02
#define MACON2_TFUNRST 0x01
/* ENC28J60 MACON3 Register Bit Definitions */
#define MACON3_PADCFG2 0x80
#define MACON3_PADCFG1 0x40
#define MACON3_PADCFG0 0x20
#define MACON3_TXCRCEN 0x10
#define MACON3_PHDRLEN 0x08
#define MACON3_HFRMLEN 0x04
#define MACON3_FRMLNEN 0x02
#define MACON3_FULDPX 0x01
/* ENC28J60 MICMD Register Bit Definitions */
#define MICMD_MIISCAN 0x02
#define MICMD_MIIRD 0x01
/* ENC28J60 MISTAT Register Bit Definitions */
#define MISTAT_NVALID 0x04
#define MISTAT_SCAN 0x02
#define MISTAT_BUSY 0x01
/* ENC28J60 PHY PHCON1 Register Bit Definitions */
#define PHCON1_PRST 0x8000
#define PHCON1_PLOOPBK 0x4000
#define PHCON1_PPWRSV 0x0800
#define PHCON1_PDPXMD 0x0100
/* ENC28J60 PHY PHSTAT1 Register Bit Definitions */
#define PHSTAT1_PFDPX 0x1000
#define PHSTAT1_PHDPX 0x0800
#define PHSTAT1_LLSTAT 0x0004
#define PHSTAT1_JBSTAT 0x0002
/* ENC28J60 PHY PHCON2 Register Bit Definitions */
#define PHCON2_FRCLINK 0x4000
#define PHCON2_TXDIS 0x2000
#define PHCON2_JABBER 0x0400
#define PHCON2_HDLDIS 0x0100
/* ENC28J60 PHY PHIE Register Bit Definitions */
#define PHIE_PLNKIE 0x0010
#define PHIE_PGEIE 0x0002
/* ENC28J60 Packet Control Byte Bit Definitions */
#define PKTCTRL_PHUGEEN 0x08
#define PKTCTRL_PPADEN 0x04
#define PKTCTRL_PCRCEN 0x02
#define PKTCTRL_POVERRIDE 0x01
/* SPI operation codes */
#define ENC28J60_READ_CTRL_REG 0x00
#define ENC28J60_READ_BUF_MEM 0x3A
#define ENC28J60_WRITE_CTRL_REG 0x40
#define ENC28J60_WRITE_BUF_MEM 0x7A
#define ENC28J60_BIT_FIELD_SET 0x80
#define ENC28J60_BIT_FIELD_CLR 0xA0
#define ENC28J60_SOFT_RESET 0xFF
/* The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata
buffer boundaries applied to internal 8K ram
the entire available packet buffer space is allocated
start with recbuf at 0/ */
#define RXSTART_INIT 0x0
/* receive buffer end */
#define RXSTOP_INIT (0x1FFF-0x0600-1)
/* start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (~1500 bytes) */
#define TXSTART_INIT (0x1FFF-0x0600)
/* stp TX buffer at end of mem */
#define TXSTOP_INIT 0x1FFF
/* max frame length which the conroller will accept: */
#define MAX_FRAMELEN 1518 /* (note: maximum ethernet frame length would be 1518) */
void enc28j60_spi_cs_status_change(int status);
#if 1//defined CONFIG_PHOBOS_GENERAL
#define PA5_A8 15
#define PA1 12
#define ENC28J60_CSL() enc28j60_spi_cs_status_change(0); //yunos_bsp_gpio_set_value(20, GPIO_VALUE_LOW); /* SPI_CS_LOW */
#define ENC28J60_CSH() enc28j60_spi_cs_status_change(1); //yunos_bsp_gpio_set_value(20, GPIO_VALUE_HIGH); /* SPI_CS_HIGH */
#else
#define PA5_A8 47
#define ENC28J60_CSL() enc28j60_spi_cs_status_change(0); //yunos_bsp_gpio_set_value(44, GPIO_VALUE_LOW); /* SPI_CS_LOW */
#define ENC28J60_CSH() enc28j60_spi_cs_status_change(1); //yunos_bsp_gpio_set_value(44, GPIO_VALUE_HIGH); /* SPI_CS_HIGH */
#endif
typedef struct _spi_net_ops_t {
int (*init)(const uint8_t *macaddr);
int (*recv)(uint8_t *, uint16_t);
int (*send)(uint8_t *, uint16_t);
int (*reset)(void);
int (*irq_enable)(int);
int (*set_macaddr)(const uint8_t *macaddr);
int (*get_link_status)(void);
} net_ops_t;
enum enc28j60_reset {
RST_ENC28J60_ALL,
RST_ENC28J60_TX,
RST_ENC28J60_RX
};
int yunos_bsp_enc28j60_init(const uint8_t *macaddr);
int yunos_bsp_enc28j60_reset(void);
int yunos_bsp_enc28j60_get_link_status(void);
int yunos_bsp_enc28j60_set_irq_enable(int enable);
int yunos_bsp_enc28j60_get_interrupt_status(void);
int yunos_bsp_enc28j60_set_interrupt_status(int status);
//int yunos_bsp_enc28j60_set_interrupt(gpio_interrupt_t interrupt_cb);
int yunos_bsp_enc28j60_get_pkt_cnt(void);
int yunos_bsp_enc28j60_net_init(void);
int yunos_bsp_enc28j60_set_macaddr(const uint8_t *macaddr);
net_ops_t *yunos_bsp_spi_net_get_ctrl_ops(void);
int yunos_bsp_enc28j60_handle_int_error(int status);
int yunos_bsp_enc28j60_send_start(uint16_t len);
void yunos_bsp_enc28j60_send_data(uint8_t *packet, uint16_t len);
void yunos_bsp_enc28j60_send_end(void);
int yunos_bsp_enc28j60_recv_start(uint16_t maxlen);
int yunos_bsp_enc28j60_recv_data(uint8_t *packet, uint16_t len);
void yunos_bsp_enc28j60_recv_end(void);
void yunos_bsp_enc28j60_hard_reset(void);
#ifdef __cplusplus
}
#endif
#endif /* _ETHERNET_ENC28J60_H__ */

View File

@ -0,0 +1,528 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_gpio.c
* @brief CSI Source File for GPIO Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdbool.h>
#include <stdio.h>
#include "csi_core.h"
#include "drv_gpio.h"
#include "dw_gpio.h"
#define ERR_GPIO(errno) (CSI_DRV_ERRNO_GPIO_BASE | errno)
#define GPIO_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_GPIO(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base; ///< handle register base
uint32_t irq; ///< irq of this handle
uint32_t pin_num; ///< pin number of this handle
uint32_t cb; ///< callback function
gpio_mode_e mode; ///< gpio mode
gpio_direction_e dir; ///< gpio direction
uint32_t mask; ///< gpio mask bit
uint32_t value; ///< gpio value
} dw_gpio_priv_t;
typedef struct {
gpio_port_handle_t handle;
uint8_t idx;
pin_t pin_name;
} dw_gpio_pin_priv_t;
static dw_gpio_priv_t gpio_handle[CONFIG_GPIO_NUM];
static dw_gpio_pin_priv_t gpio_pin_handle[CONFIG_GPIO_PIN_NUM];
/* Driver Capabilities */
static const gpio_capabilities_t driver_capabilities = {
.interrupt_mode = 1, /* intrrupt mode */
.pull_mode = 1 /* pull mode */
};
//
// Functions
//
static dw_gpio_reg_t *gpio_reg = NULL;
static dw_gpio_control_reg_t *gpio_control_reg = NULL;
static int32_t gpio_set_direction(
void *port,
gpio_direction_e direction
)
{
dw_gpio_priv_t *gpio_priv = port;
if (direction == GPIO_DIRECTION_INPUT) {
gpio_reg->SWPORT_DDR &= (~gpio_priv->mask);
} else if (direction == GPIO_DIRECTION_OUTPUT) {
gpio_reg->SWPORT_DDR |= gpio_priv->mask;
} else {
return ERR_GPIO(EDRV_PARAMETER);
}
return 0;
}
/*
* Read the statu of the Port choosed.
* Parameters:
* port: use to choose a I/O port among Port A, B, or C.
* return: the value of the corresponding Port.
*/
int32_t gpio_read(uint32_t *value)
{
*value = gpio_control_reg->EXT_PORTA;
return 0;
}
/*
* Write an output value to corresponding Port.
* Parameters:
* port: use to choose a I/O port among Port A, B, or C.
* output: value that will be written to the corresponding Port.
* return: SUCCESS
*/
static int32_t gpio_write(void *port, uint32_t mask)
{
dw_gpio_priv_t *gpio_priv = port;
uint32_t value = gpio_reg->SWPORT_DR;
value &= ~(mask);
value |= gpio_priv->value;
gpio_reg->SWPORT_DR = value;
return 0;
}
/**
* Configure a GPIO gpio_set_irq_mode.
* @param[in] pin the addr store the pin num.
* @param[in] _irqmode the irqmode of gpio
* @return zero on success. -1 on falure.
*/
static int32_t gpio_set_irq_mode(gpio_pin_handle_t pin, gpio_irq_mode_e irq_mode)
{
dw_gpio_pin_priv_t *gpio_pin_priv = pin;
uint32_t offset = gpio_pin_priv->idx;
uint32_t mask = 1 << offset;
switch (irq_mode) {
/* rising edge interrupt mode */
case GPIO_IRQ_MODE_RISING_EDGE:
gpio_control_reg->INTTYPE_LEVEL |= mask;
gpio_control_reg->INT_POLARITY |= mask;
break;
/* falling edge interrupt mode */
case GPIO_IRQ_MODE_FALLING_EDGE:
gpio_control_reg->INTTYPE_LEVEL |= mask;
gpio_control_reg->INT_POLARITY &= (~mask);
break;
/* low level interrupt mode */
case GPIO_IRQ_MODE_LOW_LEVEL:
gpio_control_reg->INTTYPE_LEVEL &= (~mask);
gpio_control_reg->INT_POLARITY &= (~mask);
break;
/* high level interrupt mode */
case GPIO_IRQ_MODE_HIGH_LEVEL:
gpio_control_reg->INTTYPE_LEVEL &= (~mask);
gpio_control_reg->INT_POLARITY |= mask;
break;
/* double edge interrupt mode */
case GPIO_IRQ_MODE_DOUBLE_EDGE:
return ERR_GPIO(EDRV_UNSUPPORTED);
default:
return ERR_GPIO(EDRV_PARAMETER);
}
return 0;
}
/*
* Clear one or more interrupts of PortA.
* Parameters:
* pinno:
* return: SUCCESS.
*/
static void gpio_irq_clear(uint32_t idx)
{
gpio_control_reg->PORTA_EOI = idx;
}
/*
* Enable one or more interrupts of PortA.
* Parameters:
* pinno:
* return: SUCCESS.
*/
static void gpio_irq_enable(gpio_pin_handle_t pin)
{
dw_gpio_pin_priv_t *gpio_pin_priv = pin;
uint32_t offset = gpio_pin_priv->idx;
uint32_t val = gpio_control_reg->INTEN;
val |= (1 << offset);
gpio_control_reg->INTEN = val;
}
/*
* Disable one or more interrupts of PortA.
* Parameters:
* pinno:
* return: SUCCESS.
*/
static void gpio_irq_disable(gpio_pin_handle_t pin)
{
dw_gpio_pin_priv_t *gpio_pin_priv = pin;
uint32_t offset = gpio_pin_priv->idx;
uint32_t val = gpio_control_reg->INTEN;
val &= ~(1 << offset);
gpio_control_reg->INTEN = val;
}
void dw_gpio_irqhandler(int idx)
{
dw_gpio_priv_t *gpio_priv = &gpio_handle[idx];
uint32_t value = gpio_control_reg->INTSTATUS;
uint8_t i;
/* find the interrput pin */
for (i = 0; i < 32; i++) {
if (value == (1 << i)) {
break;
}
}
uint32_t offset = i;
uint32_t pin_idx = offset;
for (i = 0; i < idx; i++) {
pin_idx += gpio_handle[i].pin_num;
}
gpio_pin_handle_t pin = (gpio_pin_handle_t) &gpio_pin_handle[pin_idx];
/* execute the callback function */
if ((gpio_event_cb_t)(gpio_priv->cb)) {
((gpio_event_cb_t)(gpio_priv->cb))(pin);
}
gpio_irq_clear(value); //clear the gpio interrupt
}
int32_t __attribute__((weak)) target_gpio_port_init(port_name_t port, uint32_t *base, uint32_t *irq, uint32_t *pin_num)
{
return -1;
}
/**
\brief Initialize GPIO module. 1. Initializes the resources needed for the GPIO handle 2.registers event callback function
3.get gpio_port_handle
\param[in] port port_name.
\param[in] cb_event Pointer to \ref gpio_event_cb_t
\return gpio_port_handle
*/
gpio_port_handle_t csi_gpio_port_initialize(port_name_t port, gpio_event_cb_t cb_event)
{
uint32_t i;
dw_gpio_priv_t *gpio_priv;
for (i = 0; i <= port; i++) {
/* obtain the gpio port information */
uint32_t base = 0u;
uint32_t pin_num;
uint32_t irq;
uint32_t idx = target_gpio_port_init(i, &base, &irq, &pin_num);
if (idx < 0 || idx >= CONFIG_GPIO_NUM) {
return NULL;
}
gpio_priv = &gpio_handle[idx];
gpio_priv->base = base;
gpio_priv->irq = irq;
gpio_priv->pin_num = pin_num;
}
gpio_reg = (dw_gpio_reg_t *)(gpio_priv->base);
gpio_control_reg = (dw_gpio_control_reg_t *)(gpio_priv->base + 0x30);
gpio_priv->cb = (uint32_t)cb_event;
drv_nvic_enable_irq(gpio_priv->irq);
return (gpio_port_handle_t)gpio_priv;
}
/**
\brief De-initialize GPIO handle. stops operation and releases the software resources used by the handle
\param[in] handle gpio port handle to operate.
\return error code
*/
int32_t csi_gpio_port_uninitialize(gpio_port_handle_t handle)
{
GPIO_NULL_PARAM_CHK(handle);
dw_gpio_priv_t *gpio_priv = handle;
gpio_priv->cb = NULL;
drv_nvic_disable_irq(gpio_priv->irq);
return 0;
}
/**
\brief Get driver capabilities.
\param[in] handle instance to operate.
\return \ref gpio_capabilities_t
*/
gpio_capabilities_t csi_gpio_get_io_capabilities(gpio_port_handle_t handle)
{
return driver_capabilities;
}
/**
\brief config multiple pin within one handle
\param[in] handle gpio port handle to operate.
\param[in] mask the bitmask to identify which bits in the handle should be included (0 - ignore)
\param[in] mode \ref gpio_mode_e
\param[in] dir \ref gpio_direction_e
\return error code
*/
int32_t csi_gpio_port_config(gpio_port_handle_t handle, uint32_t mask, gpio_mode_e mode, gpio_direction_e dir)
{
if (mask < 0) {
return ERR_GPIO(EDRV_PARAMETER);
}
GPIO_NULL_PARAM_CHK(handle);
dw_gpio_priv_t *gpio_priv = handle;
/*config the gpio mode direction mask bits */
gpio_priv->mode = mode;
gpio_priv->dir = dir;
gpio_priv->mask = mask;
uint32_t ret = gpio_set_direction(gpio_priv, dir);
return ret;
}
/**
\brief Write value to the handle(write value to multiple pins on one handle at the same time)
\param[in] handle gpio port handle to operate.
\param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
\param[in] value the value to be set
\return error code
*/
int32_t csi_gpio_port_write(gpio_port_handle_t handle, uint32_t mask, uint32_t value)
{
if (mask < 0 || value < 0) {
return ERR_GPIO(EDRV_PARAMETER);
}
GPIO_NULL_PARAM_CHK(handle);
uint32_t port_value = mask & value;
dw_gpio_priv_t *gpio_priv = handle;
gpio_priv->value = port_value;
gpio_write(gpio_priv, mask);
return 0;
}
/**
\brief Read the current value on the handle(read value of multiple pins on one handle at the same time)
\param[in] handle gpio port handle to operate.
\param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
\param[out] value an integer with each bit corresponding to an associated handle pin setting
\return error code
*/
int32_t csi_gpio_port_read(gpio_port_handle_t handle, uint32_t mask, uint32_t *value)
{
if (mask < 0) {
return ERR_GPIO(EDRV_PARAMETER);
}
GPIO_NULL_PARAM_CHK(handle);
GPIO_NULL_PARAM_CHK(value);
uint32_t port_value = 0;
gpio_read(&port_value);
*value = (mask & port_value);
return 0;
}
int32_t __attribute__((weak)) target_gpio_pin_init(pin_t gpio_pin, uint32_t *port_idx)
{
return -1;
}
/**
\brief Initialize GPIO handle.
\param[in] gpio_pin Pointer to the pin_t.
\return gpio_pin_handle
*/
gpio_pin_handle_t csi_gpio_pin_initialize(pin_t gpio_pin)
{
/* obtain the gpio pin information */
uint32_t port_idx;
uint32_t pin_idx = target_gpio_pin_init(gpio_pin, &port_idx);
dw_gpio_pin_priv_t *gpio_pin_priv = &(gpio_pin_handle[pin_idx]);
gpio_pin_priv->handle = (gpio_port_handle_t)&gpio_handle[port_idx];
uint32_t idx = pin_idx;
uint32_t i;
for (i = 0; i < port_idx; i++) {
idx = pin_idx - (gpio_handle[i].pin_num);
}
gpio_pin_priv->idx = idx;
return (gpio_pin_handle_t)gpio_pin_priv;
}
/**
\brief config pin
\param[in] pin gpio pin handle to operate.
\param[in] mode \ref gpio_mode_e
\param[in] dir \ref gpio_direction_e
\return error code
*/
int32_t csi_gpio_pin_config(gpio_pin_handle_t pin,
gpio_mode_e mode,
gpio_direction_e dir)
{
GPIO_NULL_PARAM_CHK(pin);
/* config the gpio pin mode direction mask bits */
dw_gpio_pin_priv_t *gpio_pin_priv = pin;
dw_gpio_priv_t *gpio_priv = gpio_pin_priv->handle;
gpio_priv->mode = mode;
gpio_priv->dir = dir;
gpio_priv->mask = 1 << gpio_pin_priv->idx;
uint32_t ret = gpio_set_direction(gpio_priv, dir);
if(ret) {
return ret;
}
return 0;
}
/**
\brief Set one or zero to the selected GPIO pin.
\param[in] pin gpio pin handle to operate.
\param[in] value the value to be set
\return error code
*/
int32_t csi_gpio_pin_write(gpio_pin_handle_t pin, bool value)
{
GPIO_NULL_PARAM_CHK(pin);
if (value < 0) {
return ERR_GPIO(EDRV_PARAMETER);
}
dw_gpio_pin_priv_t *gpio_pin_priv = pin;
dw_gpio_priv_t *gpio_priv = gpio_pin_priv->handle;
uint8_t offset = gpio_pin_priv->idx;
uint32_t port_value = value << offset;
gpio_priv->value = port_value;
gpio_write(gpio_priv, (1 << offset));
return 0;
}
/**
\brief Get the value of selected GPIO pin.
\param[in] pin gpio pin handle to operate.
\param[out] value buf to store the pin value
\return error code
*/
int32_t csi_gpio_pin_read(gpio_pin_handle_t pin, bool *value)
{
GPIO_NULL_PARAM_CHK(pin);
if (value <= 0) {
return ERR_GPIO(EDRV_PARAMETER);
}
dw_gpio_pin_priv_t *gpio_pin_priv = pin;
uint32_t port_value;
uint8_t offset = gpio_pin_priv->idx;
gpio_read(&port_value);
*value = (port_value & (1 << offset)) >> offset;
return 0;
}
/**
\brief set GPIO interrupt mode.
\param[in] pin gpio pin handle to operate.
\param[in] mode the irq mode to be set
\param[in] enable the enable flag
\return error code
*/
int32_t csi_gpio_pin_irq_set(gpio_pin_handle_t pin, gpio_irq_mode_e mode, bool enable)
{
GPIO_NULL_PARAM_CHK(pin);
uint32_t ret = 0;
if (enable) {
ret = gpio_set_irq_mode(pin, mode);
if (ret) {
return ret;
}
gpio_irq_enable(pin);
} else {
gpio_irq_disable(pin);
}
return ret;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_pwm.h
* @brief header file for pwm driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef __CK_PWM_H
#define __CK_PWM_H
#include <stdio.h>
#include "soc.h"
typedef enum {
CKENUM_PWM_CH0 = 0,
CKENUM_PWM_CH1 = 1,
CKENUM_PWM_CH2 = 2,
CKENUM_PWM_CH3 = 3,
CKENUM_PWM_CH4 = 4,
CKENUM_PWM_CH5 = 5,
CKENUM_PWM_CH6 = 6,
CKENUM_PWM_CH7 = 7,
CKENUM_PWM_CH8 = 8,
CKENUM_PWM_CH9 = 9,
CKENUM_PWM_CH10 = 10,
CKENUM_PWM_CH11 = 11
} CKENUM_PWM_CHANNEL;
typedef enum {
CKENUM_PWM_COUNT_UP = 0,
CKENUM_PWM_COUNT_UP_DOWN = 1
} CKENUM_PWM_COUNTER_MODE;
typedef struct {
__IOM uint32_t PWMCFG; /* Offset: 0x000 (R/W) PWM configure register */
__IOM uint32_t PWMINVERTTRIG; /* Offset: 0x004 (R/W) PWM signal is inverted register */
__IOM uint32_t PWM01TRIG; /* Offset: 0x008 (R/W) contain the trigger generate compare value */
__IOM uint32_t PWM23TRIG; /* Offset: 0x00C (R/W) contain the trigger generate compare value */
__IOM uint32_t PWM45TRIG; /* Offset: 0x010 (N/A) contain the trigger generate compare value */
__IOM uint32_t PWMINTEN1; /* Offset: 0x014 (R/W) interrupt enable */
__IM uint32_t PWMINTEN2; /* Offset: 0x018 (N/A) interrupt enable */
__IOM uint32_t PWMRIS1; /* Offset: 0x01C (R/ ) raw interrupt status */
__IOM uint32_t PWMRIS2; /* Offset: 0x020 (N/A) raw interrupt status */
__IOM uint32_t PWMIC1; /* Offset: 0x024 (R/W) interrupt clear */
__IOM uint32_t PWMIC2; /* Offset: 0x028 (R/W) interrupt clear */
__IOM uint32_t PWMIS1; /* Offset: 0x02C (R/W) interrupt status */
__IOM uint32_t PWMIS2; /* Offset: 0x030 (R/W) interrupt status */
__IOM uint32_t PWMCTL; /* Offset: 0x034 (R/W) configure the pwm generation blocks */
__IOM uint32_t PWM01LOAD; /* Offset: 0x038 (R/W) contain the load value of the PWM count */
__IOM uint32_t PWM23LOAD; /* Offset: 0x03C (R/W) contain the load value of the PWM count */
__IOM uint32_t PWM45LOAD; /* Offset: 0x040 (N/A) contain the load value of the PWM count */
__IM uint32_t PWM01COUNT; /* Offset: 0x044 (R/ ) contain the current value of the PWM count */
__IM uint32_t PWM23COUNT; /* Offset: 0x048 (R/ ) contain the current value of the PWM count */
__IOM uint32_t PWM45COUNT; /* Offset: 0x04C (N/A) contain the current value of the PWM count */
__IOM uint32_t PWM0CMP; /* Offset: 0x050 (R/W) contain a value to be compared against the counter */
__IOM uint32_t PWM1CMP; /* Offset: 0x054 (R/W) contain a value to be compared against the counter */
__IOM uint32_t PWM2CMP; /* Offset: 0x058 (R/W) contain a value to be compared against the counter */
__IOM uint32_t PWM3CMP; /* Offset: 0x05C (N/A) contain a value to be compared against the counter */
__IOM uint32_t PWM4CMP; /* Offset: 0x060 (N/A) contain a value to be compared against the counter */
__IOM uint32_t PWM5CMP; /* Offset: 0x064 (N/A) contain a value to be compared against the counter */
__IOM uint32_t PWM01DB; /* Offset: 0x068 (R/W) contain the number of clock ticks to delay */
__IOM uint32_t PWM23DB; /* Offset: 0x06C (R/W) contain the number of clock ticks to delayr */
__IOM uint32_t PWM45DB; /* Offset: 0x070 (N/A) contain the number of clock ticks to delay */
__IOM uint32_t CAPCTL; /* Offset: 0x074 (R/W) input capture control */
__IOM uint32_t CAPINTEN; /* Offset: 0x078 (R/W) input capture interrupt enable */
__IM uint32_t CAPRIS; /* Offset: 0x07C (R/ ) input capture raw interrupt status */
__IOM uint32_t CAPIC; /* Offset: 0x080 (R/W) input capture interrupt clear */
__IM uint32_t CAPIS; /* Offset: 0x084 (R/ ) input capture interrupt status */
__IM uint32_t CAP01T; /* Offset: 0x088 (R/ ) input capture count value */
__IM uint32_t CAP23T; /* Offset: 0x08C (R/ ) input capture count value */
__IOM uint32_t CAP45T; /* Offset: 0x090 (N/A) input capture count value */
__IOM uint32_t CAP01MATCH; /* Offset: 0x094 (R/W) input capture match value */
__IOM uint32_t CAP23MATCH; /* Offset: 0x098 (R/W) input capture match value */
__IOM uint32_t CAP45MATCH; /* Offset: 0x09C (N/A) input capture match value */
__IOM uint32_t TIMINTEN; /* Offset: 0x0A0 (R/W) time interrupt enable */
__IM uint32_t TIMRIS; /* Offset: 0x0A4 (R/ ) time raw interrupt stats */
__IOM uint32_t TIMIC; /* Offset: 0x0A8 (R/W) time interrupt clear */
__IM uint32_t TIMIS; /* Offset: 0x0AC (R/ ) time interrupt status */
__IOM uint32_t TIM01LOAD; /* Offset: 0x0B0 (R/W) time load value */
__IOM uint32_t TIM23LOAD; /* Offset: 0x0B4 (R/W) time load value */
__IOM uint32_t TIM45LOAD; /* Offset: 0x0B8 (N/A) time load value */
__IOM uint32_t TIM01COUNT; /* Offset: 0x0BC (R/W) time current count time */
__IOM uint32_t TIM23COUNT; /* Offset: 0x0C0 (R/W) time current count time */
__IOM uint32_t TIM45COUNT; /* Offset: 0x0C4 (R/W) time current count time */
} ck_pwm_reg_t;
#endif /* __CK_PWM_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,86 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_rsa.h
* @brief header file for rsa driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CK_RSA_H_
#define _CK_RSA_H_
#include <stdio.h>
#include "drv_rsa.h"
#include "soc.h"
#define RSA_KEY_LEN 1024
#define RSA_KEY_BYTE (RSA_KEY_LEN >> 3)
#define RSA_KEY_WORD (RSA_KEY_LEN >> 5)
#define BN_MAX_BITS ((RSA_KEY_LEN << 1) + 32)
#define BN_MAX_BYTES ((BN_MAX_BITS + 7) >> 3)
#define BN_MAX_WORDS ((BN_MAX_BYTES + 3) >> 2)
#define MAX_RSA_LP_CNT 10000
#define UINT32_TO_UINT64(data) ((uint64_t)(((uint64_t)(data)) & 0x00000000ffffffffU))
#define UINT64L_TO_UINT32(data) ((uint32_t)(((uint64_t)(data)) & 0x00000000ffffffffU))
#define UINT64H_TO_UINT32(data) ((uint32_t)((((uint64_t)(data)) >> 32) & 0x00000000ffffffffU))
#define PKCS1_PADDING 0x01
#define NO_PADDING 0x02
#define MD5_PADDING 0x00
#define SHA1_PADDING 0x01
#define MD5_HASH_SZ 16
#define SHA1_HASH_SZ 20
#define RAS_CALCULATE_Q 0x6
#define RSA_ENABLE_MODULE 0x3
#define RSA_ENDIAN_MODE 0x8
#define RSA_RESET 0x1
#define RSA_CAL_Q_DONE_OFFSET 0x5
typedef struct bignum {
uint32_t pdata[BN_MAX_WORDS];
uint32_t words;
} bignum_t;
typedef struct {
__IOM uint32_t rsa_mwid; /* Offset: 0x000 (R/W) Width of M register */
__IOM uint32_t rsa_ckid; /* Offset: 0x004 (R/W) Width of D register */
__IOM uint32_t rsa_bwid; /* Offset: 0x008 (R/W) Width of B register */
__IOM uint32_t rsa_ctrl; /* Offset: 0x00c (R/W) RSA control register */
__OM uint32_t rsa_rst; /* Offset: 0x010 (W) RSA reset register */
__IM uint32_t rsa_lp_cnt; /* Offset: 0x014 (R) Loop counter for inquiry register*/
__IM uint32_t rsa_q0; /* Offset: 0x018 (R) High-radix MM algorithm assistant register,part 1*/
__IM uint32_t rsa_q1; /* Offset: 0x01c (R) High-radix MM algorithm assistant register,part 2*/
__IOM uint32_t rsa_isr; /* Offset: 0x020 (W/R) Interrupt raw status register */
__IOM uint32_t rsa_imr; /* Offset: 0x024 (W/R) Interrupt mask register */
__IOM uint32_t rev1[54]; /* Reserve regiser */
__IOM uint32_t rsa_rfm; /* Offset: 0x100 (W/R) Register file for modulus M */
__IOM uint32_t rev2[63]; /* Reserve regiser */
__IOM uint32_t rsa_rfd; /* Offset: 0x200 (W/R) Register file for exponent D */
__IOM uint32_t rev3[63]; /* Reserve regiser */
__IOM uint32_t rsa_rfc; /* Offset: 0x300 (W/R) Register file for hard C */
__IOM uint32_t rev4[63]; /* Reserve regiser */
__IOM uint32_t rsa_rfb; /* Offset: 0x400 (W/R) Register file for data B */
__IOM uint32_t rev5[63]; /* Reserve regiser */
__IM uint32_t rsa_rfr; /* Offset: 0x500 (R) Register file for storing the result */
} ck_rsa_reg_t;
#endif

View File

@ -0,0 +1,703 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_rtc.c
* @brief CSI Source File for RTC Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdbool.h>
#include "ck_rtc.h"
#include "csi_core.h"
#include "drv_rtc.h"
#include "soc.h"
#define ERR_RTC(errno) (CSI_DRV_ERRNO_RTC_BASE | errno)
#define RTC_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_RTC(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
uint32_t irq;
rtc_event_cb_t cb_event;
struct tm rtc_base;
} ck_rtc_priv_t;
extern void mdelay(uint32_t ms);
static ck_rtc_priv_t rtc_instance[CONFIG_RTC_NUM];
static uint8_t leap_year[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static uint8_t noleap_year[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static const uint16_t g_noleap_daysbeforemonth[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
static const uint16_t g_leap_daysbeforemonth[13] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
static const rtc_capabilities_t rtc_capabilities = {
.interrupt_mode = 1, /* supports Interrupt mode */
.wrap_mode = 0 /* supports wrap mode */
};
static inline int clock_isleapyear(int year)
{
return (year % 400) ? ((year % 100) ? ((year % 4) ? 0 : 1) : 0) : 1;
}
static inline int32_t ck_rtc_enable(ck_rtc_reg_t *addr)
{
uint32_t value;
value = addr->RTC_CCR;
value |= 1 << 2;
addr->RTC_CCR = value;
return 0;
}
static inline int32_t ck_rtc_disable(ck_rtc_reg_t *addr)
{
uint32_t value;
value = addr->RTC_CCR;
value &= ~(1 << 2);
addr->RTC_CCR = value;
return 0;
}
static int ck_rtc_settime(ck_rtc_reg_t *addr, uint32_t settime)
{
if (settime < 0) {
return ERR_RTC(EDRV_PARAMETER);
}
uint64_t time = settime;
time = time * 20000000 / 16384;
time = time / 1000;
addr->RTC_CLR = (uint32_t)time;
return 0;
}
static time_t ck_rtc_readtime(ck_rtc_reg_t *addr)
{
uint64_t time = addr->RTC_CCVR ;
time = time * 16384 / 20000000;
time = time * 1000;
return (time_t)time;
}
static int clock_daysbeforemonth(int month, bool leapyear)
{
int retval = g_noleap_daysbeforemonth[month];
if (month >= 2 && leapyear) {
retval++;
}
return retval;
}
static time_t clock_calendar2utc(int year, int month, int day)
{
time_t days;
/* Years since epoch in units of days (ignoring leap years). */
days = (year - 1970) * 365;
/* Add in the extra days for the leap years prior to the current year. */
days += (year - 1969) >> 2;
/* Add in the days up to the beginning of this month. */
days += (time_t)clock_daysbeforemonth(month, clock_isleapyear(year));
/* Add in the days since the beginning of this month (days are 1-based). */
days += day - 1;
/* Then convert the seconds and add in hours, minutes, and seconds */
return days;
}
time_t _mktime(struct tm *tp)
{
time_t ret;
time_t jdn;
/* Get the EPOCH-relative julian date from the calendar year,
* month, and date
*/
jdn = clock_calendar2utc(tp->tm_year + 1900, tp->tm_mon, tp->tm_mday);
/* Return the seconds into the julian day. */
ret = ((jdn * 24 + tp->tm_hour) * 60 + tp->tm_min) * 60 + tp->tm_sec;
return ret;
}
static void clock_utc2calendar(time_t days, int *year, int *month,
int *day)
{
/* There is one leap year every four years, so we can get close with the
* following:
*/
int value = days / (4 * 365 + 1); /* Number of 4-years periods since the epoch */
days -= value * (4 * 365 + 1); /* Remaining days */
value <<= 2; /* Years since the epoch */
/* Then we will brute force the next 0-3 years */
bool leapyear;
int tmp;
for (; ;) {
/* Is this year a leap year (we'll need this later too) */
leapyear = clock_isleapyear(value + 1970);
/* Get the number of days in the year */
tmp = (leapyear ? 366 : 365);
/* Do we have that many days? */
if (days >= tmp) {
/* Yes.. bump up the year */
value++;
days -= tmp;
} else {
/* Nope... then go handle months */
break;
}
}
/* At this point, value has the year and days has number days into this year */
*year = 1970 + value;
/* Handle the month (zero based) */
int min = 0;
int max = 11;
do {
/* Get the midpoint */
value = (min + max) >> 1;
/* Get the number of days that occurred before the beginning of the month
* following the midpoint.
*/
tmp = clock_daysbeforemonth(value + 1, leapyear);
/* Does the number of days before this month that equal or exceed the
* number of days we have remaining?
*/
if (tmp > days) {
/* Yes.. then the month we want is somewhere from 'min' and to the
* midpoint, 'value'. Could it be the midpoint?
*/
tmp = clock_daysbeforemonth(value, leapyear);
if (tmp > days) {
/* No... The one we want is somewhere between min and value-1 */
max = value - 1;
} else {
/* Yes.. 'value' contains the month that we want */
break;
}
} else {
/* No... The one we want is somwhere between value+1 and max */
min = value + 1;
}
/* If we break out of the loop because min == max, then we want value
* to be equal to min == max.
*/
value = min;
} while (min < max);
/* The selected month number is in value. Subtract the number of days in the
* selected month
*/
days -= clock_daysbeforemonth(value, leapyear);
/* At this point, value has the month into this year (zero based) and days has
* number of days into this month (zero based)
*/
*month = value + 1; /* 1-based */
*day = days + 1; /* 1-based */
}
struct tm *gmtime_r(const time_t *timer, struct tm *result)
{
time_t epoch;
time_t jdn;
int year;
int month;
int day;
int hour;
int min;
int sec;
/* Get the seconds since the EPOCH */
epoch = *timer;
/* Convert to days, hours, minutes, and seconds since the EPOCH */
jdn = epoch / SEC_PER_DAY;
epoch -= SEC_PER_DAY * jdn;
hour = epoch / SEC_PER_HOUR;
epoch -= SEC_PER_HOUR * hour;
min = epoch / SEC_PER_MIN;
epoch -= SEC_PER_MIN * min;
sec = epoch;
/* Convert the days since the EPOCH to calendar day */
clock_utc2calendar(jdn, &year, &month, &day);
/* Then return the struct tm contents */
result->tm_year = (int)year - 1900; /* Relative to 1900 */
result->tm_mon = (int)month - 1; /* zero-based */
result->tm_mday = (int)day; /* one-based */
result->tm_hour = (int)hour;
result->tm_min = (int)min;
result->tm_sec = (int)sec;
return result;
}
static int ck_rtc_setmarchtime(ck_rtc_reg_t *addr, int64_t settime)
{
int64_t time = settime;
if (settime < 0 || time >= 0x8000000000000000) {
return ERR_RTC(EDRV_PARAMETER);
}
time = time * 20000 / 16384;
time += addr->RTC_CCVR;
addr->RTC_CMR = (uint32_t)time;
return 0;
}
static int32_t ck_rtc_int_enable(ck_rtc_reg_t *addr)
{
int value = addr->RTC_CCR;
value |= 1 << 0;
addr->RTC_CCR = value;
return 0;
}
static int32_t ck_rtc_int_disable(ck_rtc_reg_t *addr)
{
uint32_t value = addr->RTC_CCR;
value &= ~(1 << 0);
addr->RTC_CCR = value;
ck_rtc_setmarchtime(addr, ck_rtc_readtime(addr));
return 0;
}
void ck_rtc_irqhandler(int32_t idx)
{
ck_rtc_priv_t *rtc_priv = &rtc_instance[idx];
ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
addr->RTC_EOI;
if (rtc_priv->cb_event) {
rtc_priv->cb_event(RTC_EVENT_TIMER_INTRERRUPT);
}
}
int32_t __attribute__((weak)) target_get_rtc_count(void)
{
return 0;
}
int32_t __attribute__((weak)) target_get_rtc(uint32_t idx, uint32_t *base, uint32_t *irq)
{
return NULL;
}
/**
\brief get rtc instance count.
\return rtc instance count
*/
int32_t csi_rtc_get_instance_count(void)
{
return target_get_rtc_count();
}
/**
\brief Initialize RTC Interface. 1. Initializes the resources needed for the RTC interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_rtc_get_instance_count()
\param[in] cb_event Pointer to \ref rtc_event_cb_t
\return pointer to rtc instance
*/
rtc_handle_t csi_rtc_initialize(int32_t idx, rtc_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_RTC_NUM) {
return NULL;
}
int32_t real_idx;
uint32_t base = 0u;
uint32_t irq;
real_idx = target_get_rtc(idx, &base, &irq);
if (real_idx != idx) {
return NULL;
}
ck_rtc_priv_t *rtc_priv;
rtc_priv = &rtc_instance[idx];
rtc_priv->base = base;
rtc_priv->irq = irq;
ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
rtc_priv->cb_event = cb_event;
addr->RTC_CCR = 0;
drv_nvic_enable_irq(rtc_priv->irq);
return (rtc_handle_t)rtc_priv;
}
/**
\brief De-initialize RTC Interface. stops operation and releases the software resources used by the interface
\param[in] handle rtc handle to operate.
\return \ref execution_status
*/
int32_t csi_rtc_uninitialize(rtc_handle_t handle)
{
RTC_NULL_PARAM_CHK(handle);
ck_rtc_priv_t *rtc_priv = handle;
rtc_priv->cb_event = NULL;
drv_nvic_disable_irq(rtc_priv->irq);
return 0;
}
/**
\brief Get driver capabilities.
\param[in] handle rtc handle to operate.
\return \ref rtc_capabilities_t
*/
rtc_capabilities_t csi_rtc_get_capabilities(rtc_handle_t handle)
{
return rtc_capabilities;
}
/**
\brief Set RTC timer.
\param[in] handle rtc handle to operate.
\param[in] rtctime \ref struct tm
\return \ref execution_status
*/
int32_t csi_rtc_set_time(rtc_handle_t handle, const struct tm *rtctime)
{
RTC_NULL_PARAM_CHK(handle);
RTC_NULL_PARAM_CHK(rtctime);
ck_rtc_priv_t *rtc_priv = handle;
ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
if (rtctime->tm_year < 70 || rtctime->tm_year >= 200) {
goto error_time;
}
int32_t leap = 1;
leap = clock_isleapyear(rtctime->tm_year + 1900);
if (rtctime->tm_sec < 0 || rtctime->tm_sec >= 60) {
goto error_time;
}
if (rtctime->tm_min < 0 || rtctime->tm_min >= 60) {
goto error_time;
}
if (rtctime->tm_hour < 0 || rtctime->tm_hour >= 24) {
goto error_time;
}
if (rtctime->tm_mon < 0 || rtctime->tm_mon >= 12) {
goto error_time;
}
if (leap) {
if (rtctime->tm_mday < 1 || rtctime->tm_mday > leap_year[rtctime->tm_mon]) {
goto error_time;
}
} else {
if (rtctime->tm_mday < 1 || rtctime->tm_mday > noleap_year[rtctime->tm_mon]) {
goto error_time;
}
}
rtc_priv->rtc_base.tm_sec = rtctime->tm_sec;
rtc_priv->rtc_base.tm_min = rtctime->tm_min;
rtc_priv->rtc_base.tm_hour = rtctime->tm_hour;
rtc_priv->rtc_base.tm_mday = rtctime->tm_mday;
rtc_priv->rtc_base.tm_mon = rtctime->tm_mon;
rtc_priv->rtc_base.tm_year = rtctime->tm_year;
ck_rtc_settime(addr, 0);
return 0;
error_time:
return ERR_RTC(EDRV_RTC_TIME);
}
/**
\brief Get RTC timer.
\param[in] handle rtc handle to operate.
\param[in] rtctime \ref struct tm
\return \ref execution_status
*/
int32_t csi_rtc_get_time(rtc_handle_t handle, struct tm *rtctime)
{
RTC_NULL_PARAM_CHK(handle);
ck_rtc_priv_t *rtc_priv = handle;
ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
time_t time = ck_rtc_readtime(addr);
time = time / 1000;
time += _mktime(&(rtc_priv->rtc_base));
gmtime_r(&time, rtctime);
return 0;
}
/**
\brief Start RTC timer.
\param[in] handle rtc handle to operate.
\return \ref execution_status
*/
int32_t csi_rtc_start(rtc_handle_t handle)
{
RTC_NULL_PARAM_CHK(handle);
ck_rtc_priv_t *rtc_priv = handle;
ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
ck_rtc_enable(addr);
return 0;
}
/**
\brief Stop RTC timer.
\param[in] handle rtc handle to operate.
\return \ref execution_status
*/
int32_t csi_rtc_stop(rtc_handle_t handle)
{
RTC_NULL_PARAM_CHK(handle);
ck_rtc_priv_t *rtc_priv = handle;
ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
ck_rtc_disable(addr);
return 0;
}
/**
\brief Get RTC status.
\param[in] handle rtc handle to operate.
\return RTC status \ref rtc_status_t
*/
rtc_status_t csi_rtc_get_status(rtc_handle_t handle)
{
rtc_status_t rtc_status = {0};
if (handle == NULL) {
return rtc_status;
}
ck_rtc_priv_t *rtc_priv = handle;
ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
if (addr->RTC_RSTAT & 0x1) {
rtc_status.active = 1;
}
return rtc_status;
}
/**
\brief config RTC timer.
\param[in] handle rtc handle to operate.
\param[in] rtctime time to wake up
\return error code
*/
int32_t csi_rtc_timer_config(rtc_handle_t handle, const struct tm *rtctime)
{
RTC_NULL_PARAM_CHK(handle);
ck_rtc_priv_t *rtc_priv = handle;
ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
if (rtctime->tm_year < 70 || rtctime->tm_year >= 200) {
goto error_time;
}
int32_t leap = clock_isleapyear(rtctime->tm_year + 1900);
if (rtctime->tm_sec < 0 || rtctime->tm_sec >= 60) {
goto error_time;
}
if (rtctime->tm_min < 0 || rtctime->tm_min >= 60) {
goto error_time;
}
if (rtctime->tm_hour < 0 || rtctime->tm_hour >= 24) {
goto error_time;
}
if (rtctime->tm_mon < 0 || rtctime->tm_mon >= 12) {
goto error_time;
}
if (leap) {
if (rtctime->tm_mday < 1 || rtctime->tm_mday > leap_year[rtctime->tm_mon]) {
goto error_time;
}
} else {
if (rtctime->tm_mday < 1 || rtctime->tm_mday > noleap_year[rtctime->tm_mon]) {
goto error_time;
}
}
/* after setting RTC counter load register(RTC_CLT), loading to RTC_CCVR need two rtc clocks.
* two rtc clocks about 3ms. setting 10ms to ensure operation is completed.
*/
mdelay(10);
struct tm current_time;
int32_t ret = csi_rtc_get_time(handle, &current_time);
if (ret < 0) {
return ERR_RTC(EDRV_PARAMETER);
}
int64_t settime = 0;
settime += ((int64_t)(rtctime->tm_year) - (int64_t)(rtc_priv->rtc_base.tm_year)) * (365 + (int64_t)leap) * 24 * 3600 * 1000;
if (settime < 0) {
goto error_time;
}
if (leap) {
settime += (int64_t)(g_leap_daysbeforemonth[rtctime->tm_mon + 1] + rtctime->tm_mday - g_leap_daysbeforemonth[current_time.tm_mon + 1] - current_time.tm_mday) * 24 * 3600 * 1000;
if (settime < 0) {
goto error_time;
}
} else {
settime += (int64_t)(g_noleap_daysbeforemonth[rtctime->tm_mon + 1] + rtctime->tm_mday - g_noleap_daysbeforemonth[current_time.tm_mon + 1] - current_time.tm_mday) * 24 * 3600 * 1000;
if (settime < 0) {
goto error_time;
}
}
settime += (int64_t)(rtctime->tm_hour - current_time.tm_hour) * 3600 * 1000;
if (settime < 0) {
goto error_time;
}
settime += (int64_t)(rtctime->tm_min - current_time.tm_min) * 60 * 1000;
if (settime < 0) {
goto error_time;
}
settime += (int64_t)(rtctime->tm_sec - current_time.tm_sec) * 1000;
if (settime < 0) {
goto error_time;
}
ck_rtc_setmarchtime(addr, settime);
return 0;
error_time:
return ERR_RTC(EDRV_RTC_TIME);
}
/**
\brief disable or enable RTC timer.
\param[in] handle rtc handle to operate.
\param[in] en set 1 enable for rtc timer
\return error code
*/
int32_t csi_rtc_timer_enable(rtc_handle_t handle, uint8_t en)
{
RTC_NULL_PARAM_CHK(handle);
ck_rtc_priv_t *rtc_priv = handle;
ck_rtc_reg_t *addr = (ck_rtc_reg_t *)(rtc_priv->base);
if (en == 1) {
ck_rtc_int_enable(addr);
} else if (en == 0) {
ck_rtc_int_disable(addr);
} else {
return ERR_RTC(EDRV_PARAMETER);
}
return 0;
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_rtc.h
* @brief header file for rtc driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef __CK_RTC_H
#define __CK_RTC_H
#include <stdio.h>
#include "soc.h"
#define SEC_PER_MIN ((time_t)60)
#define SEC_PER_HOUR ((time_t)60 * SEC_PER_MIN)
#define SEC_PER_DAY ((time_t)24 * SEC_PER_HOUR)
typedef struct {
__IM uint32_t RTC_CCVR; /* Offset: 0x000 (R/ ) current count value register */
__IOM uint32_t RTC_CMR; /* Offset: 0x004 (R/W) count match register */
__IOM uint32_t RTC_CLR; /* Offset: 0x008 (R/W) count load register */
__IOM uint32_t RTC_CCR; /* Offset: 0x00c (R/W) count control register */
__IM uint32_t RTC_STAT; /* Offset: 0x010 (R/ ) interrupt status register */
__IM uint32_t RTC_RSTAT; /* Offset: 0x014 (R/ ) interrupt raw status register */
__IM uint32_t RTC_EOI; /* Offset: 0x018 (R/ ) end of interrupt register */
__IM uint32_t RTC_COMP_VERSION; /* Offset: 0x01c (R/ ) component version register */
} ck_rtc_reg_t;
#endif /* __CK_RTC_H */

View File

@ -0,0 +1,538 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_sha.c
* @brief CSI Source File for SHA Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "csi_core.h"
#include "drv_sha.h"
#include "ck_sha.h"
typedef struct {
uint32_t base;
uint32_t irq;
sha_event_cb_t cb;
sha_status_t status;
sha_mode_e mode;
sha_endian_mode_e endian;
} ck_sha_priv_t;
static ck_sha_priv_t sha_handle[CONFIG_SHA_NUM];
bool finish_flag = 0;
/* Driver Capabilities */
static const sha_capabilities_t driver_capabilities = {
.sha1 = 1, /* sha1 mode */
.sha224 = 1, /* sha224 mode */
.sha256 = 1, /* sha256 mode */
.sha384 = 1, /* sha384 mode */
.sha512 = 1, /* sha512 mode */
.sha512_224 = 1, /* sha512_224 mode */
.sha512_256 = 1, /* sha512_256 mode */
.endianmode = 1, /* endian mode */
.interruptmode = 1 /* interrupt mode */
};
#define ERR_SHA(errno) (CSI_DRV_ERRNO_SHA_BASE | errno)
#define SHA_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_SHA(EDRV_PARAMETER); \
} \
} while (0)
//
// Functions
//
ck_sha_reg_t *sha_reg = NULL;
volatile static uint8_t sha_int_flag = 1;
static int32_t sha_set_mode(sha_mode_e mode)
{
sha_reg->SHA_CON = mode;
return 0;
}
static int32_t sha_enable_interrupt(void)
{
sha_reg->SHA_CON |= 1 << SHA_INT_ENABLE_OFFSET;
return 0;
}
static int32_t sha_disable_interrupt(void)
{
sha_reg->SHA_CON &= ~(1 << SHA_INT_ENABLE_OFFSET);
return 0;
}
static void sha_clear_interrupt(void)
{
sha_reg->SHA_INTSTATE = 0;
}
static int32_t sha_enable_initial(void)
{
sha_reg->SHA_CON |= 1 << SHA_INIT_OFFSET;
return 0;
}
static int32_t sha_enable_calculate(void)
{
sha_reg->SHA_CON |= 1 << SHA_CAL_OFFSET;
return 0;
}
static int32_t sha_select_endian_mode(sha_endian_mode_e mode)
{
sha_reg->SHA_CON |= mode << SHA_ENDIAN_OFFSET;
return 0;
}
static int32_t sha_input_data(uint32_t *data, uint32_t length)
{
uint8_t i;
uint32_t *input_data = (uint32_t *) & (sha_reg->SHA_DATA1);
for (i = 0; i < length; i++) {
*(input_data + i) = *(data + i);
}
return 0;
}
static int32_t sha_get_data(sha_handle_t handle, uint32_t *data)
{
ck_sha_priv_t *sha_priv = handle;
uint8_t len;
uint8_t i;
uint32_t *result = (uint32_t *)&sha_reg->SHA_H0L;
/* according to different mode to obtain the hash result */
if (sha_priv->mode == SHA_MODE_1 || sha_priv->mode == SHA_MODE_224 || sha_priv->mode == SHA_MODE_256) {
if (sha_priv->mode == SHA_MODE_1) {
len = 5;
} else if (sha_priv->mode == SHA_MODE_224) {
len = 7;
} else if (sha_priv->mode == SHA_MODE_256) {
len = 8;
}
for (i = 0; i < len; i++) {
data[i] = *(result + i);
}
} else {
if (sha_priv->mode == SHA_MODE_384) {
len = 6;
} else if (sha_priv->mode == SHA_MODE_512) {
len = 8;
}
uint32_t *resulth = (uint32_t *)&sha_reg->SHA_H0H;
for (i = 0; i < len; i++) {
data[i << 1] = *(resulth + i);
data[(i << 1) + 1] = *(result + i);
}
}
return 0;
}
static inline void sha_reverse_order(uint8_t *pdata, int32_t length)
{
uint8_t input_data[length];
uint8_t result[length];
uint32_t tmp = 0;
int32_t i = 0;
memcpy((void *)input_data, (void *)pdata, length);
for (i = 0; i < length; i++) {
tmp = i >> 2;
tmp = tmp << 3;
result[i] = input_data[tmp + 3 - i];
}
memcpy((void *)pdata, (void *)result, length);
}
void ck_sha_irqhandler(int32_t idx)
{
sha_int_flag = 0;
sha_clear_interrupt(); //clear sha interrupt
ck_sha_priv_t *sha_priv = &sha_handle[idx];
if (finish_flag != 0) {
if (sha_priv->cb != NULL) {
sha_priv->cb(SHA_EVENT_COMPLETE); //execute the callback function
}
}
}
int32_t __attribute__((weak)) target_get_sha_count(void)
{
return 0;
}
int32_t __attribute__((weak)) target_get_sha(int32_t idx, uint32_t *base, uint32_t *irq)
{
return NULL;
}
/**
\brief get sha handle count.
\return sha handle count
*/
int32_t csi_sha_get_instance_count(void)
{
return target_get_sha_count();
}
/**
\brief Initialize SHA Interface. 1. Initializes the resources needed for the SHA interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_sha_get_instance_count()
\param[in] cb_event Pointer to \ref sha_event_cb_t
\return return sha handle if success
*/
sha_handle_t csi_sha_initialize(int32_t idx, sha_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_SHA_NUM) {
return NULL;
}
uint32_t base = 0u;
uint32_t irq;
/* obtain the sha information */
int32_t real_idx = target_get_sha(idx, &base, &irq);
if (real_idx != idx) {
return NULL;
}
ck_sha_priv_t *sha_priv = &sha_handle[idx];
sha_priv->base = base;
sha_priv->irq = irq;
/* initialize the sha context */
sha_priv->cb = cb_event;
sha_priv->status.busy = 0;
drv_nvic_enable_irq(sha_priv->irq);
return (sha_handle_t)sha_priv;
}
/**
\brief De-initialize SHA Interface. stops operation and releases the software resources used by the interface
\param[in] handle sha handle to operate.
\return error code
*/
int32_t csi_sha_uninitialize(sha_handle_t handle)
{
SHA_NULL_PARAM_CHK(handle);
ck_sha_priv_t *sha_priv = handle;
sha_priv->cb = NULL;
sha_disable_interrupt();
drv_nvic_disable_irq(sha_priv->irq);
return 0;
}
/**
\brief Get driver capabilities.
\param[in] handle sha handle to operate.
\return \ref sha_capabilities_t
*/
sha_capabilities_t csi_sha_get_capabilities(sha_handle_t handle)
{
return driver_capabilities;
}
/**
\brief config sha mode.
\param[in] handle sha handle to operate.
\param[in] mode \ref sha_mode_e
\param[in] endian \ref sha_endian_mode_e
\return error code
*/
int32_t csi_sha_config(sha_handle_t handle, sha_mode_e mode, sha_endian_mode_e endian_mode)
{
SHA_NULL_PARAM_CHK(handle);
ck_sha_priv_t *sha_priv = handle;
sha_reg = (ck_sha_reg_t *)(sha_priv->base);
/* config the sha mode */
switch (mode) {
case SHA_MODE_512_256:
case SHA_MODE_512_224:
return ERR_SHA(EDRV_UNSUPPORTED);
case SHA_MODE_1:
case SHA_MODE_224:
case SHA_MODE_256:
case SHA_MODE_384:
case SHA_MODE_512:
sha_priv->mode = mode;
break;
default:
return ERR_SHA(EDRV_PARAMETER);
}
sha_set_mode(mode);
/*config the sha endian mode */
if (endian_mode == SHA_ENDIAN_MODE_LITTLE) {
sha_priv->endian = endian_mode;
sha_select_endian_mode(endian_mode);
} else if (endian_mode == SHA_ENDIAN_MODE_BIG) {
sha_priv->endian = endian_mode;
sha_select_endian_mode(endian_mode);
} else {
return ERR_SHA(EDRV_PARAMETER);
}
sha_enable_interrupt();
return 0;
}
/**
\brief start the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\return error code
*/
int32_t csi_sha_starts(sha_handle_t handle, void *context)
{
SHA_NULL_PARAM_CHK(handle);
ck_sha_priv_t *sha_priv = handle;
sha_enable_initial();
sha_priv->status.busy = 1;
return 0;
}
/**
\brief updata the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\param[in] input Pointer to the Source data
\param[in] len the data len
\return error code
*/
static uint8_t sha_buffer[128];
static uint32_t total[2] = {0x0};
static uint32_t last_left = 0;
int32_t csi_sha_update(sha_handle_t handle, void *context, const void *input, uint32_t len)
{
SHA_NULL_PARAM_CHK(handle);
SHA_NULL_PARAM_CHK(input);
if (len <= 0) {
return ERR_SHA(EDRV_PARAMETER);
}
ck_sha_priv_t *sha_priv = handle;
sha_reg = (ck_sha_reg_t *)(sha_priv->base);
uint32_t block_size;
uint32_t left_len = 0;
if (sha_priv->mode < 4) {
block_size = 64;
left_len = len & 0x3f;
} else {
block_size = 128;
left_len = len & 0x7f;
}
uint32_t left = total[0] & (block_size - 1);
uint32_t fill = block_size - left;
total[0] += len;
total[0] &= 0xffffffff;
uint32_t word_left = total[0] & 0x3;
uint8_t *p = (uint8_t *)input;
/* when the text is not aligned by block and len > fill */
if (left && len >= fill) {
if (last_left && sha_priv->endian == SHA_ENDIAN_MODE_LITTLE) {
uint32_t i;
for (i = 0; i < 4 - last_left; i++) {
if (finish_flag) {
*(sha_buffer + 3 - last_left - i) = *((uint8_t *)p + 3 - last_left - i);
} else {
*(sha_buffer + left + 3 - last_left - i) = *((uint8_t *)p + 3 - last_left - i);
}
}
fill = fill - 4 + last_left;
p = (p + 4 - last_left);
}
if (last_left) {
memcpy((void *)(sha_buffer + left + 4 - last_left), p, fill);
} else {
memcpy((void *)(sha_buffer + left), p, fill);
}
/* set the input data */
sha_input_data((uint32_t *)sha_buffer, block_size >> 2);
sha_enable_calculate();
while (sha_int_flag);
sha_int_flag = 1;
p += fill;
len -= fill;
left = 0;
}
/* calculate the hash by block */
while (len >= block_size) {
sha_input_data((uint32_t *)p, block_size >> 2);
sha_enable_calculate();
while (sha_int_flag);
sha_int_flag = 1;
p += block_size;
len -= block_size;
}
/* when the text is not aligned by block and len < fill */
if (len > 0) {
if (sha_priv->endian == SHA_ENDIAN_MODE_BIG || word_left == 0) {
memcpy((void *)(sha_buffer + left), p, len);
} else {
memcpy((void *)(sha_buffer + left), p, len + 4 - word_left);
last_left = word_left;
}
}
sha_priv->status.busy = 0;
return 0;
}
static unsigned char sha_padding[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/**
\brief finish the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\param[out] output Pointer to the dest data
\return error code
*/
static uint32_t total_length;
int32_t csi_sha_finish(sha_handle_t handle, void *context, void *output)
{
SHA_NULL_PARAM_CHK(handle);
SHA_NULL_PARAM_CHK(output);
ck_sha_priv_t *sha_priv = handle;
uint32_t block_size;
if (sha_priv->mode < 4) {
block_size = 64;
} else {
block_size = 128;
}
total_length = total[0] << 3;
uint32_t last = total[0] & (block_size - 1);
uint32_t padn = (last < block_size) ? (block_size - last) : (block_size + block_size - last);
uint32_t left = total[0] & 0x3;
uint8_t temp_data[4];
uint32_t j;
/*calculate the final word*/
for (j = 0; j < 4; j++) {
temp_data[j] = (total_length >> (8 * j)) & 0xff;
}
/* group the final package according to the endian mode */
if (sha_priv->endian == SHA_ENDIAN_MODE_BIG) {
memset(sha_padding, 0x0, sizeof(sha_padding));
sha_padding[0] = 0x80;
for (j = 0; j < 4; j++) {
sha_padding[padn - 4 + j] = temp_data[3 - j];
}
} else {
memset(sha_padding, 0x0, sizeof(sha_padding));
sha_padding[3 - left] = 0x80;
for (j = 0; j < 4; j++) {
sha_padding[padn - 4 + j] = temp_data[j];
}
}
finish_flag = 1;
csi_sha_update(handle, NULL, sha_padding, padn);
/* get the hash result */
sha_get_data(handle, (uint32_t *)output);
uint8_t *p = output;
/* convert the data endian according the sha mode */
if (sha_priv->mode == SHA_MODE_1) {
sha_reverse_order(p, 20);
} else if (sha_priv->mode == SHA_MODE_224) {
sha_reverse_order(p, 28);
} else if (sha_priv->mode == SHA_MODE_256) {
sha_reverse_order(p, 32);
} else if (sha_priv->mode == SHA_MODE_512) {
sha_reverse_order(p, 64);
} else if (sha_priv->mode == SHA_MODE_384) {
sha_reverse_order(p, 48);
}
total[0] = 0;
memset(sha_buffer, 0, sizeof(sha_buffer));
memset(sha_padding, 0, sizeof(sha_padding));
last_left = 0;
finish_flag = 0;
return 0;
}
/**
\brief Get SHA status.
\param[in] handle sha handle to operate.
\return SHA status \ref sha_status_t
*/
sha_status_t csi_sha_get_status(sha_handle_t handle)
{
ck_sha_priv_t *sha_priv = handle;
return sha_priv->status;
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_sha.h
* @brief header file for sha driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CK_SHA_H_
#define _CK_SHA_H_
#include <stdio.h>
#include "drv_sha.h"
#include "soc.h"
#define SHA_INIT_OFFSET 3
#define SHA_INT_ENABLE_OFFSET 4
#define SHA_ENDIAN_OFFSET 5
#define SHA_CAL_OFFSET 6
typedef struct {
__IOM uint32_t SHA_CON; /* Offset: 0x000 (R/W) Control register */
__IOM uint32_t SHA_INTSTATE; /* Offset: 0x004 (R/W) Instatus register */
__IOM uint32_t SHA_H0L; /* Offset: 0x008 (R/W) H0L register */
__IOM uint32_t SHA_H1L; /* Offset: 0x00c (R/W) H1L register */
__IOM uint32_t SHA_H2L; /* Offset: 0x010 (R/W) H2L register */
__IOM uint32_t SHA_H3L; /* Offset: 0x014 (R/W) H3L register */
__IOM uint32_t SHA_H4L; /* Offset: 0x018 (R/W) H4L register */
__IOM uint32_t SHA_H5L; /* Offset: 0x01c (R/W) H5L register */
__IOM uint32_t SHA_H6L; /* Offset: 0x020 (R/W) H6L register */
__IOM uint32_t SHA_H7L; /* Offset: 0x024 (R/W) H7L register */
__IOM uint32_t SHA_H0H; /* Offset: 0x028 (R/W) H0H register */
__IOM uint32_t SHA_H1H; /* Offset: 0x02c (R/W) H1H register */
__IOM uint32_t SHA_H2H; /* Offset: 0x030 (R/W) H2H register */
__IOM uint32_t SHA_H3H; /* Offset: 0x034 (R/W) H3H register */
__IOM uint32_t SHA_H4H; /* Offset: 0x038 (R/W) H4H register */
__IOM uint32_t SHA_H5H; /* Offset: 0x03c (R/W) H5H register */
__IOM uint32_t SHA_H6H; /* Offset: 0x040 (R/W) H6H register */
__IOM uint32_t SHA_H7H; /* Offset: 0x044 (R/W) H7H register */
__IOM uint32_t SHA_DATA1; /* Offset: 0x048 (R/W) DATA1 register */
uint32_t REV[15];
__IOM uint32_t SHA_DATA2; /* Offset: 0x088 (R/W) DATA2 register */
} ck_sha_reg_t;
#endif
typedef enum {
SHA_STATUS_START_END = 0, /* the one time count mode */
SHA_STATUS_START = 1, /* the first time of the cal */
SHA_STATUS_CONTINUE = 2, /* the middle stage of the cal */
SHA_STATUS_END = 3 /* the last time of the cal*/
} enum_sha_status;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,159 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_spi.h
* @brief header file for spi driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef __DW_SPI_H
#define __DW_SPI_H
#include <stdio.h>
#include "soc.h"
/*
* SPI register bit definitions
*/
#define DW_SPI_ENABLE 0x01
#define DW_SPI_DISABLE 0x00
#define DW_SPI_TMOD_BIT8 0x0100
#define DW_SPI_TMOD_BIT9 0x0200
#define DW_SPI_POLARITY 0x80
#define DW_SPI_PHASE 0x40
#define DW_SPI_BUSY 0x01
#define DW_SPI_TFE 0x04
#define DW_SPI_RFNE 0x08
#define DW_SPI_INT_EN 0x19
#define DW_SPI_RINT_EN 0x3e
#define DW_SPI_TINT_EN 0x3f
#define DW_SPI_INT_DISABLE 0x00
#define DW_SPI_INT_MASK_RX 0x27
#define DW_SPI_INT_MASKTX 0x3e
#define DW_SPI_RDMAE 0x1
#define DW_SPI_TDMAE 0x2
#define DW_SPI_TXFIFO_LV 0x0
#define DW_SPI_RXFIFO_LV 0x1d
#define DW_SPI_RXFIFO_NOT_EMPTY 0x08
#define DW_SPI_START_RX 0x0
#define DW_SPI_FIFO_MAX_LV 0x20
#define DW_SPI_FIFO_OVER_LV 0x18
#define DW_SPI_RXFIFO_OVERFLOW 0x08
#define DW_SPI_RXFIFO_FULL 0x10
#define DW_SPI_TXFIFO_EMPTY 0x01
#define SPI_CS_SELECTED 0x0
#define DW_SPI_IMR_TXEIM 0x01 /* Transmit FIFO Empty Interrupt Mask */
#define DW_SPI_IMR_RXFIM 0x10 /* Receive FIFO Full Interrupt Mask */
/* some infoermationgs of SPI for special MCU */
#define DW_SPI_DEFAULT_BAUDR 10000000 /* 10M */
#define DW_SPI_MAXID 0x1
#define SPI_INITIALIZED ((uint8_t)(1U)) // SPI initalized
#define SPI_POWERED ((uint8_t)(1U<< 1)) // SPI powered on
#define SPI_CONFIGURED ((uint8_t)(1U << 2)) // SPI configured
#define SPI_DATA_LOST ((uint8_t)(1U << 3)) // SPI data lost occurred
#define SPI_MODE_FAULT ((uint8_t)(1U << 4)) // SPI mode fault occurred
typedef enum {
DWENUM_SPI_DMACR_RXE = 0,
DWENUM_SPI_DMACR_TXE = 1,
} DWENUM_SPI_DMACR;
typedef enum {
DWENUM_SPI_TXRX = 0,
DWENUM_SPI_TX = 1,
DWENUM_SPI_RX = 2,
DWENUM_SPI_EERX = 3
} DWENUM_SPI_MODE;
typedef enum {
DWENUM_SPI_CLOCK_POLARITY_LOW = 0,
DWENUM_SPI_CLOCK_POLARITY_HIGH = 1
} DWENUM_SPI_POLARITY;
typedef enum {
DWENUM_SPI_CLOCK_PHASE_MIDDLE = 0,
DWENUM_SPI_CLOCK_PHASE_START = 1
} DWENUM_SPI_PHASE;
typedef enum {
DWENUM_SPI_DATASIZE_4 = 3,
DWENUM_SPI_DATASIZE_5 = 4,
DWENUM_SPI_DATASIZE_6 = 5,
DWENUM_SPI_DATASIZE_7 = 6,
DWENUM_SPI_DATASIZE_8 = 7,
DWENUM_SPI_DATASIZE_9 = 8,
DWENUM_SPI_DATASIZE_10 = 9,
DWENUM_SPI_DATASIZE_11 = 10,
DWENUM_SPI_DATASIZE_12 = 11,
DWENUM_SPI_DATASIZE_13 = 12,
DWENUM_SPI_DATASIZE_14 = 13,
DWENUM_SPI_DATASIZE_15 = 14,
DWENUM_SPI_DATASIZE_16 = 15
} DWENUM_SPI_DATAWIDTH;
typedef enum {
DWENUM_SPI_CS0 = 1,
DWENUM_SPI_CS1 = 2
} DWENUM_SPI_SLAVE;
typedef struct {
__IOM uint16_t CTRLR0; /* Offset: 0x000 (R/W) Control register 0 */
uint16_t RESERVED0;
__IOM uint16_t CTRLR1; /* Offset: 0x004 (R/W) Control register 1 */
uint16_t RESERVED1;
__IOM uint8_t SPIENR; /* Offset: 0x008 (R/W) SSI enable regiseter */
uint8_t RESERVED2[7];
__IOM uint32_t SER; /* Offset: 0x010 (R/W) Slave enable register */
__IOM uint16_t BAUDR; /* Offset: 0x014 (R/W) Baud rate select */
uint16_t RESERVED3;
__IOM uint32_t TXFTLR; /* Offset: 0x018 (R/W) Transmit FIFO Threshold Level */
__IOM uint32_t RXFTLR; /* Offset: 0x01c (R/W) Receive FIFO Threshold Level */
__IOM uint32_t TXFLR; /* Offset: 0x020 (R/W) Transmit FIFO Level register */
__IOM uint32_t RXFLR; /* Offset: 0x024 (R/W) Receive FIFO Level Register */
__IOM uint8_t SR; /* Offset: 0x028 (R/W) status register */
uint8_t RESERVED4[3];
__IOM uint32_t IMR; /* Offset: 0x02C (R/W) Interrupt Mask Register */
__IM uint32_t ISR; /* Offset: 0x030 (R/W) interrupt status register */
__IM uint32_t RISR; /* Offset: 0x034 (R/W) Raw Interrupt Status Register */
__IM uint8_t TXOICR; /* Offset: 0x038 (R/W) Transmit FIFO Overflow Interrupt Clear Register */
uint8_t RESERVED5[3];
__IM uint8_t RXOICR; /* Offset: 0x03C (R/W) Receive FIFO Overflow Interrupt Clear Register*/
uint8_t RESERVED6[3];
__IM uint8_t RXUICR; /* Offset: 0x040 (R/W) Receive FIFO Underflow Interrupt Clear Register */
uint8_t RESERVED7[3];
__IM uint8_t MSTICR; /* Offset: 0x044 (R/W) Multi-Master Interrupt Clear Register */
uint8_t RESERVED8[3];
__IM uint8_t ICR; /* Offset: 0x048 (R/W) Interrupt Clear Register */
uint8_t RESERVED9[3];
__IOM uint8_t DMACR; /* Offset: 0x04C (R/W) DMA Control Register */
uint8_t RESERVED10[3];
__IOM uint8_t DMATDLR; /* Offset: 0x050 (R/W) DMA Transmoit Data Level */
uint8_t RESERVED11[3];
__IOM uint8_t DMARDLR; /* Offset: 0x054 (R/W) DMA Receive Data Level */
uint8_t RESERVED12[3];
__IM uint32_t IDR; /* Offset: 0x058 (R/W) identification register */
uint32_t RESERVED13;
__IOM uint16_t DR; /* Offset: 0x060 (R/W) Data Register */
uint16_t RESERVED14[17];
__IOM uint8_t WR; /* Offset: 0x0A0 (R/W) SPI is Master or Slave Select Register */
} dw_spi_reg_t;
#endif /* __DW_SPI_H */

View File

@ -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;
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_timer.h
* @brief header file for timer driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef __DW_TIMER_H
#define __DW_TIMER_H
#include <stdio.h>
#include "soc.h"
/*
* define the bits for TxControl
*/
#define DW_TIMER_TXCONTROL_ENABLE (1UL << 0)
#define DW_TIMER_TXCONTROL_MODE (1UL << 1)
#define DW_TIMER_TXCONTROL_INTMASK (1UL << 2)
#define DW_TIMER_INIT_DEFAULT_VALUE 0x7ffffff
typedef struct {
__IOM uint32_t TxLoadCount; /* Offset: 0x000 (R/W) Receive buffer register */
__IM uint32_t TxCurrentValue; /* Offset: 0x004 (R) Transmission hold register */
__IOM uint8_t TxControl: 4; /* Offset: 0x008 (R/W) Clock frequency division low section register */
uint8_t RESERVED0[3];
__IM uint8_t TxEOI: 1; /* Offset: 0x00c (R) Clock frequency division high section register */
uint8_t RESERVED1[3];
__IM uint8_t TxIntStatus: 1; /* Offset: 0x010 (R) Interrupt enable register */
uint8_t RESERVED2[3];
} dw_timer_reg_t;
#endif /* __DW_TIMER_H */

View File

@ -0,0 +1,237 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file ck_trng.c
* @brief CSI Source File for TRNG Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "drv_trng.h"
#include "ck_trng.h"
#define ERR_TRNG(errno) (CSI_DRV_ERRNO_TRNG_BASE | errno)
#define TRNG_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_TRNG(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
trng_event_cb_t cb;
trng_status_t status;
} ck_trng_priv_t;
static ck_trng_priv_t trng_handle[CONFIG_TRNG_NUM];
/* Driver Capabilities */
static const trng_capabilities_t driver_capabilities = {
.lowper_mode = 1 /* low power mode */
};
//
// Functions
//
ck_trng_reg_t *trng_reg = NULL;
static int32_t trng_enable(void)
{
trng_reg->TCR |= TRNG_EN;
return 0;
}
static int32_t trng_get_data(void)
{
int data = trng_reg->TDR;
return data;
}
static int32_t trng_data_is_ready(void)
{
int flag = (trng_reg->TCR & TRNG_DATA_READY);
return flag;
}
int32_t __attribute__((weak)) target_get_trng_count(void)
{
return 0;
}
int32_t __attribute__((weak)) target_get_trng(int32_t idx, uint32_t *base)
{
return NULL;
}
/**
\brief get trng handle count.
\return trng handle count
*/
int32_t csi_trng_get_instance_count(void)
{
return target_get_trng_count();
}
/**
\brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_trng_get_instance_count()
\param[in] cb_event Pointer to \ref trng_event_cb_t
\return pointer to trng handle
*/
trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_TRNG_NUM) {
return NULL;
}
/* obtain the trng information */
uint32_t base = 0u;
int32_t real_idx = target_get_trng(idx, &base);
if (real_idx != idx) {
return NULL;
}
ck_trng_priv_t *trng_priv = &trng_handle[idx];
trng_priv->base = base;
/* initialize the trng context */
trng_reg = (ck_trng_reg_t *)(trng_priv->base);
trng_priv->cb = cb_event;
trng_priv->status.busy = 0;
trng_priv->status.data_valid = 0;
return (trng_handle_t)trng_priv;
}
/**
\brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface
\param[in] handle trng handle to operate.
\return error code
*/
int32_t csi_trng_uninitialize(trng_handle_t handle)
{
TRNG_NULL_PARAM_CHK(handle);
ck_trng_priv_t *trng_priv = handle;
trng_priv->cb = NULL;
return 0;
}
/**
\brief Get driver capabilities.
\param[in] trng handle to operate.
\return \ref trng_capabilities_t
*/
trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle)
{
return driver_capabilities;
}
/**
\brief Get data from the TRNG.
\param[in] handle trng handle to operate.
\param[out] data Pointer to buffer with data get from TRNG
\param[in] num Number of data items to obtain
\return error code
*/
int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num)
{
TRNG_NULL_PARAM_CHK(handle);
TRNG_NULL_PARAM_CHK(data);
TRNG_NULL_PARAM_CHK(num);
ck_trng_priv_t *trng_priv = handle;
trng_priv->status.busy = 1U;
trng_priv->status.data_valid = 0U;
uint8_t left_len = (uint32_t)data & 0x3;
uint32_t result = 0;
/* if the data addr is not aligned by word */
if (left_len) {
trng_enable();
while (!trng_data_is_ready());
result = trng_get_data();
/* wait the data is ready */
while (trng_data_is_ready());
if (num > (4 - left_len)) {
memcpy(data, &result, 4 - left_len);
} else {
memcpy(data, &result, num);
trng_priv->status.busy = 0U;
trng_priv->status.data_valid = 1U;
if (trng_priv->cb) {
trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
}
return 0;
}
num -= (4 - left_len);
}
uint32_t word_len = num >> 2;
left_len = num & 0x3;
/* obtain the data by word */
while (word_len--) {
trng_enable();
while (!trng_data_is_ready());
result = trng_get_data();
while (trng_data_is_ready());
*(uint32_t *)data = result;
data += 4;
}
/* if the num is not aligned by word */
if (left_len) {
trng_enable();
while (!trng_data_is_ready());
result = trng_get_data();
while (trng_data_is_ready());
memcpy(data, &result, left_len);
}
trng_priv->status.busy = 0U;
trng_priv->status.data_valid = 1U;
if (trng_priv->cb) {
trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
}
return 0;
}
/**
\brief Get TRNG status.
\param[in] handle trng handle to operate.
\return TRNG status \ref trng_status_t
*/
trng_status_t csi_trng_get_status(trng_handle_t handle)
{
ck_trng_priv_t *trng_priv = handle;
return trng_priv->status;
}

View File

@ -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

View File

@ -0,0 +1,768 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_usart.c
* @brief CSI Source File for usart Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdbool.h>
#include "csi_core.h"
#include "drv_usart.h"
#include "dw_usart.h"
#include "soc.h"
#define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno)
/*
* setting config may be accessed when the USART is not
* busy(USR[0]=0) and the DLAB bit(LCR[7]) is set.
*/
#define WAIT_USART_IDLE(addr)\
do { \
int32_t timecount = 0; \
while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\
timecount++;\
}\
if (timecount >= UART_BUSY_TIMEOUT) {\
return ERR_USART(EDRV_TIMEOUT);\
} \
} while(0)
#define USART_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_USART(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
uint32_t irq;
usart_event_cb_t cb_event; ///< Event callback
void *cb_arg;
uint32_t rx_total_num;
uint32_t tx_total_num;
uint8_t *rx_buf;
uint8_t *tx_buf;
volatile uint32_t rx_cnt;
volatile uint32_t tx_cnt;
volatile uint32_t tx_busy;
volatile uint32_t rx_busy;
} dw_usart_priv_t;
static dw_usart_priv_t usart_instance[CONFIG_USART_NUM];
static const usart_capabilities_t usart_capabilities = {
.asynchronous = 1, /* supports USART (Asynchronous) mode */
.synchronous_master = 0, /* supports Synchronous Master mode */
.synchronous_slave = 0, /* supports Synchronous Slave mode */
.single_wire = 0, /* supports USART Single-wire mode */
.event_tx_complete = 1, /* Transmit completed event */
.event_rx_timeout = 0, /* Signal receive character timeout event */
};
/**
\brief set the bautrate of usart.
\param[in] addr usart base to operate.
\param[in] baudrate.
\param[in] apbfreq the frequence of the apb.
\return error code
*/
static int32_t dw_usart_set_baudrate(dw_usart_reg_t *addr, uint32_t baudrate, uint32_t apbfreq)
{
WAIT_USART_IDLE(addr);
/* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/
uint32_t divisor = ((apbfreq * 10) / baudrate) >> 4;
if ((divisor % 10) >= 5) {
divisor = (divisor / 10) + 1;
} else {
divisor = divisor / 10;
}
addr->LCR |= LCR_SET_DLAB;
/* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/
addr->DLL = divisor & 0xff;
addr->DLH = (divisor >> 8) & 0xff;
/*
* The DLAB must be cleared after the baudrate is setted
* to access other registers.
*/
addr->LCR &= (~LCR_SET_DLAB);
return 0;
}
/**
\brief enable or disable parity.
\param[in] addr usart base to operate.
\param[in] parity ODD=8, EVEN=16, or NONE=0.
\return error code
*/
static int32_t dw_usart_set_parity(dw_usart_reg_t *addr, usart_parity_e parity)
{
WAIT_USART_IDLE(addr);
switch (parity) {
case USART_PARITY_NONE:
/*CLear the PEN bit(LCR[3]) to disable parity.*/
addr->LCR &= (~LCR_PARITY_ENABLE);
break;
case USART_PARITY_ODD:
/* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */
addr->LCR |= LCR_PARITY_ENABLE;
addr->LCR &= LCR_PARITY_ODD;
break;
case USART_PARITY_EVEN:
/* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/
addr->LCR |= LCR_PARITY_ENABLE;
addr->LCR |= LCR_PARITY_EVEN;
break;
default:
return ERR_USART(EDRV_USART_PARITY);
}
return 0;
}
/**
\brief set the stop bit.
\param[in] addr usart base to operate.
\param[in] stopbit two possible value: USART_STOP_BITS_1 and USART_STOP_BITS_2.
\return error code
*/
static int32_t dw_usart_set_stopbit(dw_usart_reg_t *addr, usart_stop_bits_e stopbit)
{
WAIT_USART_IDLE(addr);
switch (stopbit) {
case USART_STOP_BITS_1:
/* Clear the STOP bit to set 1 stop bit*/
addr->LCR &= LCR_STOP_BIT1;
break;
case USART_STOP_BITS_2:
/*
* If the STOP bit is set "1",we'd gotten 1.5 stop
* bits when DLS(LCR[1:0]) is zero, else 2 stop bits.
*/
addr->LCR |= LCR_STOP_BIT2;
break;
default:
return ERR_USART(EDRV_USART_STOP_BITS);
}
return 0;
}
/**
\brief the transmit data length,and we have four choices:5, 6, 7, and 8 bits.
\param[in] addr usart base to operate.
\param[in] databits the data length that user decides.
\return error code
*/
static int32_t dw_usart_set_databit(dw_usart_reg_t *addr, usart_data_bits_e databits)
{
WAIT_USART_IDLE(addr);
/* The word size decides by the DLS bits(LCR[1:0]), and the
* corresponding relationship between them is:
* DLS word size
* 00 -- 5 bits
* 01 -- 6 bits
* 10 -- 7 bits
* 11 -- 8 bits
*/
switch (databits) {
case USART_DATA_BITS_5:
addr->LCR &= LCR_WORD_SIZE_5;
break;
case USART_DATA_BITS_6:
addr->LCR &= 0xfd;
addr->LCR |= LCR_WORD_SIZE_6;
break;
case USART_DATA_BITS_7:
addr->LCR &= 0xfe;
addr->LCR |= LCR_WORD_SIZE_7;
break;
case USART_DATA_BITS_8:
addr->LCR |= LCR_WORD_SIZE_8;
break;
default:
return ERR_USART(EDRV_USART_DATA_BITS);
}
return 0;
}
/**
\brief get character in query mode.
\param[in] instance usart instance to operate.
\param[in] the pointer to the recieve charater.
\return error code
*/
int32_t dw_usart_getchar(usart_handle_t handle, uint8_t *ch)
{
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
while (!(addr->LSR & LSR_DATA_READY));
*ch = addr->RBR;
return 0;
}
/**
\brief get character in query mode.
\param[in] instance usart instance to operate.
\param[in] the pointer to the recieve charater.
\return error code
*/
int32_t dw_usart_getchar_no_poll(usart_handle_t handle, uint8_t *ch)
{
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
if (addr->LSR & LSR_DATA_READY)
{
*ch = addr->RBR;
return 0;
}
else
{
return -1;
}
}
int32_t dw_usart_set_int_flag(usart_handle_t handle,uint32_t flag)
{
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
addr->IER |= flag;
return 0;
}
int32_t dw_usart_clr_int_flag(usart_handle_t handle,uint32_t flag)
{
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
addr->IER &= ~flag;
return 0;
}
/**
\brief transmit character in query mode.
\param[in] instance usart instance to operate.
\param[in] ch the input charater
\return error code
*/
int32_t dw_usart_putchar(usart_handle_t handle, uint8_t ch)
{
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
while ((!(addr->LSR & DW_LSR_TRANS_EMPTY)));
if (ch == '\n')
{
addr->THR = '\r';
while ((!(addr->LSR & DW_LSR_TRANS_EMPTY))) ;
}
addr->THR = ch;
return 0;
}
/**
\brief interrupt service function for transmitter holding register empty.
\param[in] usart_priv usart private to operate.
*/
static void dw_usart_intr_threshold_empty(dw_usart_priv_t *usart_priv)
{
if (usart_priv->tx_total_num == 0) {
return;
}
uint8_t remain_txdata = usart_priv->tx_total_num - usart_priv->tx_cnt;
uint8_t txdata_num = (remain_txdata > UART_MAX_FIFO) ? UART_MAX_FIFO : remain_txdata;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
uint8_t i = 0u;
for (i = 0; i < txdata_num; i++) {
addr->THR = *((uint8_t *)usart_priv->tx_buf);
usart_priv->tx_cnt++;
usart_priv->tx_buf++;
}
if (usart_priv->tx_cnt >= usart_priv->tx_total_num) {
addr->IER &= (~IER_THRE_INT_ENABLE);
while ((!(addr->LSR & DW_LSR_TEMT)));
usart_priv->tx_cnt = 0;
usart_priv->tx_busy = 0;
usart_priv->tx_buf = NULL;
usart_priv->tx_total_num = 0;
if (usart_priv->cb_event) {
usart_priv->cb_event(USART_EVENT_SEND_COMPLETE, usart_priv->cb_arg);
}
}
}
/**
\brief interrupt service function for receiver data available.
\param[in] usart_priv usart private to operate.
*/
static void dw_usart_intr_recv_data(dw_usart_priv_t *usart_priv)
{
if (usart_priv->cb_event && (usart_priv->rx_total_num == 0)) {
usart_priv->cb_event(USART_EVENT_RECEIVED, usart_priv->cb_arg);
return;
}
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
uint8_t data = addr->RBR;
if ((usart_priv->rx_total_num == 0) || (usart_priv->rx_buf == NULL)) {
return;
}
*((uint8_t *)usart_priv->rx_buf) = data;
usart_priv->rx_cnt++;
usart_priv->rx_buf++;
if (usart_priv->rx_cnt >= usart_priv->rx_total_num) {
usart_priv->rx_cnt = 0;
usart_priv->rx_buf = NULL;
usart_priv->rx_busy = 0;
usart_priv->rx_total_num = 0;
if (usart_priv->cb_event) {
usart_priv->cb_event(USART_EVENT_RECEIVE_COMPLETE, usart_priv->cb_arg);
}
}
}
/**
\brief the interrupt service function.
\param[in] index of usart instance.
*/
void dw_usart_irqhandler(int32_t idx)
{
dw_usart_priv_t *usart_priv = &usart_instance[idx];
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
uint8_t intr_state = addr->IIR & 0xf;
switch (intr_state) {
case DW_IIR_THR_EMPTY: /* interrupt source:transmitter holding register empty */
dw_usart_intr_threshold_empty(usart_priv);
break;
case DW_IIR_RECV_DATA: /* interrupt source:receiver data available or receiver fifo trigger level reached */
dw_usart_intr_recv_data(usart_priv);
break;
default:
break;
}
}
int32_t __attribute__((weak)) target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq)
{
return -1;
}
/**
\brief Get driver capabilities.
\param[in] handle usart handle to operate.
\return \ref usart_capabilities_t
*/
usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle)
{
return usart_capabilities;
}
/**
\brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
\param[in] usart pin of tx
\param[in] usart pin of rx
\param[in] cb_event Pointer to \ref usart_event_cb_t
\return return usart handle if success
*/
usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg)
{
uint32_t base = 0u;
uint32_t irq = 0u;
int32_t idx = target_usart_init(tx, rx, &base, &irq);
if (idx < 0 || idx >= CONFIG_USART_NUM) {
return NULL;
}
dw_usart_priv_t *usart_priv = &usart_instance[idx];
usart_priv->base = base;
usart_priv->irq = irq;
usart_priv->cb_event = cb_event;
usart_priv->cb_arg = cb_arg;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
/* FIFO enable */
addr->FCR = DW_FCR_FIFOE;
// /* enable received data available */
// addr->IER = IER_RDA_INT_ENABLE;
drv_nvic_enable_irq(usart_priv->irq);
return usart_priv;
}
/**
\brief De-initialize UART Interface. stops operation and releases the software resources used by the interface
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_uninitialize(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
drv_nvic_disable_irq(usart_priv->irq);
usart_priv->cb_event = NULL;
return 0;
}
/**
\brief config usart mode.
\param[in] handle usart handle to operate.
\param[in] sysclk configured system clock.
\param[in] mode \ref usart_mode_e
\param[in] parity \ref usart_parity_e
\param[in] stopbits \ref usart_stop_bits_e
\param[in] bits \ref usart_data_bits_e
\param[in] baud configured baud
\return error code
*/
int32_t csi_usart_config(usart_handle_t handle,
uint32_t sysclk,
uint32_t baud,
usart_mode_e mode,
usart_parity_e parity,
usart_stop_bits_e stopbits,
usart_data_bits_e bits)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
/* control the data_bit of the usart*/
int32_t ret = dw_usart_set_baudrate(addr, baud, sysclk);
if (ret < 0) {
return ret;
}
/* control the parity of the usart*/
ret = dw_usart_set_parity(addr, parity);
if (ret < 0) {
return ret;
}
/* control the stopbit of the usart*/
ret = dw_usart_set_stopbit(addr, stopbits);
if (ret < 0) {
return ret;
}
ret = dw_usart_set_databit(addr, bits);
if (ret < 0) {
return ret;
}
return 0;
}
/**
\brief config usart default tx value. used in syn mode
\param[in] handle usart handle to operate.
\param[in] value default tx value
\return error code
*/
int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Start sending data to UART transmitter,(received data is ignored).
The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes.
csi_usart_get_status can indicates if transmission is still in progress or pending
\param[in] handle usart handle to operate.
\param[in] data Pointer to buffer with data to send to UART transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits,
\param[in] num Number of data items to send
\return error code
*/
int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num)
{
USART_NULL_PARAM_CHK(handle);
USART_NULL_PARAM_CHK(data);
if (num == 0) {
return ERR_USART(EDRV_PARAMETER);
}
dw_usart_priv_t *usart_priv = handle;
uint8_t *source = NULL;
source = (uint8_t *)data;
usart_priv->tx_buf = (uint8_t *)data;
usart_priv->tx_total_num = num;
usart_priv->tx_cnt = 0;
usart_priv->tx_busy = 1;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
/* enable the interrupt*/
addr->IER |= IER_THRE_INT_ENABLE;
return 0;
}
/**
\brief Abort Send data to UART transmitter
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_send(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
usart_priv->tx_cnt = usart_priv->tx_total_num;
return 0;
}
/**
\brief Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from UART receiver
\param[in] num Number of data items to receive
\return error code
*/
int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num)
{
USART_NULL_PARAM_CHK(handle);
USART_NULL_PARAM_CHK(data);
uint8_t *dest = NULL;
dw_usart_priv_t *usart_priv = handle;
dest = (uint8_t *)data;
usart_priv->rx_buf = (uint8_t *)data; // Save receive buffer usart
usart_priv->rx_total_num = num; // Save number of data to be received
usart_priv->rx_cnt = 0;
usart_priv->rx_busy = 1;
return 0;
}
/**
\brief query data from UART receiver FIFO.
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from UART receiver
\param[in] num Number of data items to receive
\return receive fifo data num
*/
int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num)
{
USART_NULL_PARAM_CHK(handle);
USART_NULL_PARAM_CHK(data);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
int32_t recv_num = 0;
while (addr->LSR & 0x1) {
*((uint8_t *)data++) = addr->RBR;
recv_num++;
if (recv_num >= num) {
break;
}
}
return recv_num;
}
/**
\brief Abort Receive data from UART receiver
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_receive(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
usart_priv->rx_cnt = usart_priv->rx_total_num;
return 0;
}
/**
\brief Start sending/receiving data to/from UART transmitter/receiver.
\param[in] handle usart handle to operate.
\param[in] data_out Pointer to buffer with data to send to USART transmitter
\param[out] data_in Pointer to buffer for data to receive from USART receiver
\param[in] num Number of data items to transfer
\return error code
*/
int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief abort sending/receiving data to/from USART transmitter/receiver.
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_transfer(usart_handle_t handle)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief Get USART status.
\param[in] handle usart handle to operate.
\return USART status \ref usart_status_t
*/
usart_status_t csi_usart_get_status(usart_handle_t handle)
{
usart_status_t usart_status;
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
uint32_t line_status_reg = addr->LSR;
usart_status.tx_busy = usart_priv->tx_busy;
usart_status.rx_busy = usart_priv->rx_busy;
if (line_status_reg & DW_LSR_BI) {
usart_status.rx_break = 1;
}
if (line_status_reg & DW_LSR_FE) {
usart_status.rx_framing_error = 1;
}
if (line_status_reg & DW_LSR_PE) {
usart_status.rx_parity_error = 1;
}
return usart_status;
}
/**
\brief control the transmit.
\param[in] handle usart handle to operate.
\param[in] enable the transmitter.
\return error code
*/
int32_t csi_usart_control_tx(usart_handle_t handle, bool enable)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief control the receive.
\param[in] handle usart handle to operate.
\param[in] enable the receive.
\return error code
*/
int32_t csi_usart_control_rx(usart_handle_t handle, bool enable)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief control the break.
\param[in] handle usart handle to operate.
\param[in] enable the break.
\return error code
*/
int32_t csi_usart_control_break(usart_handle_t handle, bool enable)
{
USART_NULL_PARAM_CHK(handle);
return ERR_USART(EDRV_UNSUPPORTED);
}
/**
\brief flush receive/send data.
\param[in] handle usart handle to operate.
\param[in] type \ref usart_flush_type_e.
\return error code
*/
int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type)
{
USART_NULL_PARAM_CHK(handle);
dw_usart_priv_t *usart_priv = handle;
dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
if (type == USART_FLUSH_WRITE) {
addr->FCR |= DW_FCR_XFIFOR;
} else if (type == USART_FLUSH_READ) {
addr->FCR |= DW_FCR_RFIFOR;
} else {
return ERR_USART(EDRV_PARAMETER);
}
return 0;
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_usart.h
* @brief header file for usart driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef __DW_USART_H
#define __DW_USART_H
#include <stdio.h>
#include "errno.h"
#include "soc.h"
#define BAUDRATE_DEFAULT 19200
#define UART_BUSY_TIMEOUT 1000000
#define UART_RECEIVE_TIMEOUT 1000
#define UART_TRANSMIT_TIMEOUT 1000
#define UART_MAX_FIFO 0x10
/* UART register bit definitions */
#define USR_UART_BUSY 0x01
#define USR_UART_TFE 0x04
#define USR_UART_RFNE 0x08
#define LSR_DATA_READY 0x01
#define LSR_THR_EMPTY 0x20
#define IER_RDA_INT_ENABLE 0x01
#define IER_THRE_INT_ENABLE 0x02
#define IIR_NO_ISQ_PEND 0x01
#define LCR_SET_DLAB 0x80 /* enable r/w DLR to set the baud rate */
#define LCR_PARITY_ENABLE 0x08 /* parity enabled */
#define LCR_PARITY_EVEN 0x10 /* Even parity enabled */
#define LCR_PARITY_ODD 0xef /* Odd parity enabled */
#define LCR_WORD_SIZE_5 0xfc /* the data length is 5 bits */
#define LCR_WORD_SIZE_6 0x01 /* the data length is 6 bits */
#define LCR_WORD_SIZE_7 0x02 /* the data length is 7 bits */
#define LCR_WORD_SIZE_8 0x03 /* the data length is 8 bits */
#define LCR_STOP_BIT1 0xfb /* 1 stop bit */
#define LCR_STOP_BIT2 0x04 /* 1.5 stop bit */
#define DW_LSR_PFE 0x80
#define DW_LSR_TEMT 0x40
#define DW_LSR_THRE 0x40
#define DW_LSR_BI 0x10
#define DW_LSR_FE 0x08
#define DW_LSR_PE 0x04
#define DW_LSR_OE 0x02
#define DW_LSR_DR 0x01
#define DW_LSR_TRANS_EMPTY 0x20
#define DW_FCR_FIFOE 0x01
#define DW_FCR_RFIFOR 0x02
#define DW_FCR_XFIFOR 0x04
#define DW_FCR_RT_FIFO_SINGLE 0x00 /* rcvr trigger 1 character in the FIFO */
#define DW_FCR_RT_FIFO_QUARTER 0x01 /* rcvr trigger FIFO 1/4 full */
#define DW_FCR_RT_FIFO_HALF 0x10 /* rcvr trigger FIFO 1/2 full */
#define DW_FCR_RT_FIFO_LESSTWO 0x11 /* rcvr trigger FIFO 2 less than full */
#define DW_FCR_TET_FIFO_EMPTY 0x00 /* tx empty trigger FIFO empty */
#define DW_FCR_TET_FIFO_TWO 0x01 /* tx empty trigger 2 characters in the FIFO */
#define DW_FCR_TET_FIFO_QUARTER 0x10 /* tx empty trigger FIFO 1/4 full */
#define DW_FCR_TET_FIFO_HALF 0x11 /* tx empty trigger FIFO 1/2 full*/
#define DW_IIR_THR_EMPTY 0x02 /* threshold empty */
#define DW_IIR_RECV_DATA 0x04 /* received data available */
typedef struct {
union {
__IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */
__OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */
__IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */
};
union {
__IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */
__IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */
};
union {
__IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */
__OM uint32_t FCR; /* Offset: 0x008 ( /W) FIFO control register */
};
__IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */
__IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem control register */
__IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */
__IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */
uint32_t RESERVED1[21];
__IOM uint32_t FAR; /* Offset: 0x070 (R/W) FIFO accesss register */
__IM uint32_t TFR; /* Offset: 0x074 (R/ ) transmit FIFO read */
__OM uint32_t RFW; /* Offset: 0x078 ( /W) receive FIFO write */
__IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */
__IM uint32_t TFL; /* Offset: 0x080 (R/ ) transmit FIFO level */
__IM uint32_t RFL; /* Offset: 0x084 (R/ ) receive FIFO level */
} dw_usart_reg_t;
#endif /* __DW_USART_H */

View File

@ -0,0 +1,267 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_wdt.c
* @brief CSI Source File for WDT Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#include <stdio.h>
#include "csi_core.h"
#include "drv_wdt.h"
#include "dw_wdt.h"
#include "soc.h"
#define ERR_WDT(errno) (CSI_DRV_ERRNO_WDT_BASE | errno)
static uint32_t timeout_ms[16] = {4, 7, 13, 26, 52, 105, 210, 419, 839, 1678, 3355, 6711,
13422, 26844, 53687, 107374
};
#define WDT_NULL_PARAM_CHK(para) \
do { \
if (para == NULL) { \
return ERR_WDT(EDRV_PARAMETER); \
} \
} while (0)
typedef struct {
uint32_t base;
uint32_t irq;
wdt_event_cb_t cb_event;
} dw_wdt_priv_t;
static dw_wdt_priv_t wdt_instance[CONFIG_WDT_NUM];
/* Driver Capabilities */
static const wdt_capabilities_t wdt_capabilities = {
.interrupt = 1, ///< supports interrupt
};
static inline void dw_wdt_enable(dw_wdt_reg_t *addr)
{
uint32_t value = addr->WDT_CR;
value |= 1 << 0;
addr->WDT_CR = value;
}
static inline void dw_wdt_disable(dw_wdt_reg_t *addr)
{
uint32_t value = addr->WDT_CR;
value &= ~(1 << 0);
addr->WDT_CR = value;
}
void dw_wdt_irqhandler(int32_t idx)
{
dw_wdt_priv_t *wdt_priv = &wdt_instance[idx];
dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
addr->WDT_EOI;
if (wdt_priv->cb_event) {
wdt_priv->cb_event(WDT_EVENT_TIMEOUT);
}
}
int32_t __attribute__((weak)) target_get_wdt_count(void)
{
return 0;
}
int32_t __attribute__((weak)) target_get_wdt(uint32_t idx, uint32_t *base, uint32_t *irq)
{
return NULL;
}
/**
\brief get wdt instance count.
\return wdt instance count
*/
int32_t csi_wdt_get_instance_count(void)
{
return target_get_wdt_count();
}
/**
\brief Initialize WDT Interface. 1. Initializes the resources needed for the WDT interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_wdt_get_instance_count()
\param[in] cb_event Pointer to \ref wdt_event_cb_t
\return pointer to wdt instance
*/
wdt_handle_t csi_wdt_initialize(int32_t idx, wdt_event_cb_t cb_event)
{
if (idx < 0 || idx >= CONFIG_WDT_NUM) {
return NULL;
}
uint32_t base = 0u;
uint32_t irq = 0u;
int32_t real_idx = target_get_wdt(idx, &base, &irq);
if (real_idx != idx) {
return NULL;
}
dw_wdt_priv_t *wdt_priv = &wdt_instance[idx];
wdt_priv->base = base;
wdt_priv->irq = irq;
wdt_priv->cb_event = cb_event;
drv_nvic_enable_irq(wdt_priv->irq);
return (wdt_handle_t)wdt_priv;
}
/**
\brief De-initialize WDT Interface. stops operation and releases the software resources used by the interface
\param[in] instance wdt instance to operate.
\return \ref execution_status
*/
int32_t csi_wdt_uninitialize(wdt_handle_t handle)
{
WDT_NULL_PARAM_CHK(handle);
dw_wdt_priv_t *wdt_priv = handle;
wdt_priv->cb_event = NULL;
drv_nvic_disable_irq(wdt_priv->irq);
return 0;
}
/**
\brief Get driver capabilities.
\param[in] wdt instance to operate.
\return \ref wdt_capabilities_t
*/
wdt_capabilities_t csi_wdt_get_capabilities(wdt_handle_t handle)
{
return wdt_capabilities;
}
/**
\brief Set the WDT value. value = (2^t*0xffff * 10^6 /freq)/10^3(t: 0 ~ 15).
\param[in] handle wdt handle to operate.
\param[in] value the timeout value(ms) \ref:timeout_ms[]
\return \ref execution_status
*/
int32_t csi_wdt_set_timeout(wdt_handle_t handle, uint32_t value)
{
WDT_NULL_PARAM_CHK(handle);
uint32_t i = 0u;
for (i = 0; i <= 15 ; i++) {
if (timeout_ms[i] == value) {
break;
}
if (i == 15) {
return ERR_WDT(EDRV_PARAMETER);
}
}
dw_wdt_priv_t *wdt_priv = handle;
dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
uint32_t config = addr->WDT_CR;
uint32_t en_stat = 0; /*origin wdt enable status*/
if ((config & 0x1) != 0) {
en_stat = 1;
}
config = 0;
addr->WDT_CR = config;
/*before configuration, must disable wdt first*/
dw_wdt_disable(addr);
i += i << 4;
addr->WDT_TORR = i;
if (en_stat == 1) {
dw_wdt_enable(addr);
csi_wdt_restart(handle);
}
return 0;
}
/**
\brief Start the WDT.
\param[in] handle wdt handle to operate.
\return \ref execution_status
*/
int32_t csi_wdt_start(wdt_handle_t handle)
{
WDT_NULL_PARAM_CHK(handle);
dw_wdt_priv_t *wdt_priv = handle;
dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
dw_wdt_enable(addr);
csi_wdt_restart(handle);
return 0;
}
/**
\brief Stop the WDT.
\param[in] handle wdt handle to operate.
\return \ref execution_status
*/
int32_t csi_wdt_stop(wdt_handle_t handle)
{
WDT_NULL_PARAM_CHK(handle);
return ERR_WDT(EDRV_UNSUPPORTED);
}
/**
\brief Restart the WDT.
\param[in] handle wdt handle to operate.
\return \ref execution_status
*/
int32_t csi_wdt_restart(wdt_handle_t handle)
{
WDT_NULL_PARAM_CHK(handle);
dw_wdt_priv_t *wdt_priv = handle;
dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
addr->WDT_CRR = DW_WDT_CRR_RESET;
return 0;
}
/**
\brief Read the WDT Current value.
\param[in] handle wdt handle to operate.
\param[in] value Pointer to the Value.
\return \ref execution_status
*/
int32_t csi_wdt_read_current_value(wdt_handle_t handle, uint32_t *value)
{
WDT_NULL_PARAM_CHK(handle);
dw_wdt_priv_t *wdt_priv = handle;
dw_wdt_reg_t *addr = (dw_wdt_reg_t *)(wdt_priv->base);
*value = addr->WDT_CCVR;
return 0;
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file dw_wdt.h
* @brief header file for wdt driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef __DW_WDT_H
#define __DW_WDT_H
#include <stdio.h>
#include "soc.h"
#define DW_WDT_CRR_RESET 0x76
typedef struct {
__IOM uint8_t WDT_CR:5; /* Offset: 0x000 (R/W) WDT control register */
uint8_t RESERVED0[3];
__IOM uint8_t WDT_TORR; /* Offset: 0x004 (R/W) WDT timeout range register */
uint8_t RESERVED1[3];
__IM uint32_t WDT_CCVR; /* Offset: 0x008 (R/ ) WDT current counter value register */
__OM uint8_t WDT_CRR:8; /* Offset: 0x00C ( /W) WDT count restart register */
uint8_t RESERVED2[3];
__IM uint8_t WDT_STAT:1; /* Offset: 0x010 (R/ ) WDT interrupt status register */
uint8_t RESERVED3[3];
__IM uint8_t WDT_EOI:1; /* Offset: 0x014 (R/ ) WDT interrupt clear register */
uint8_t RESERVED4[3];
} dw_wdt_reg_t;
#endif /* __DW_WDT_H */

View File

@ -0,0 +1,189 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_aes.h
* @brief Header File for AES Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_AES_H_
#define _CSI_AES_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
#include <drv_errno.h>
/// definition for aes handle.
typedef void *aes_handle_t;
/****** AES specific error codes *****/
typedef enum {
AES_ERROR_MODE = (EDRV_SPECIFIC + 1) , ///< Specified Mode not supported
AES_ERROR_DATA_BITS , ///< Specified number of Data bits not supported
AES_ERROR_ENDIAN ///< Specified endian not supported
} drv_aes_error_e;
/*----- AES Control Codes: Mode -----*/
typedef enum {
AES_MODE_ECB = 0, ///< ECB Mode
AES_MODE_CBC , ///< CBC Mode
AES_MODE_CFB , ///< CFB Mode
AES_MODE_OFB , ///< OFB Mode
AES_MODE_CTR ///< CTR Mode
} aes_mode_e;
/*----- AES Control Codes: Crypto Mode -----*/
typedef enum {
AES_CRYPTO_MODE_ENCRYPT = 0, ///< encrypt Mode
AES_CRYPTO_MODE_DECRYPT , ///< decrypt Mode
} aes_crypto_mode_e;
/*----- AES Control Codes: Padding Mode -----*/
typedef enum {
AES_PADDING_MODE_NO = 0, ///< NO-PADDING
AES_PADDING_MODE_ZERO , ///< ZERO-PADDING
AES_PADDING_MODE_PKCS5 ///< PKCS5-PADDING
} aes_padding_mode_e;
/*----- AES Control Codes: Mode Parameters: Key length -----*/
typedef enum {
AES_KEY_LEN_BITS_128 = 0, ///< 128 Data bits
AES_KEY_LEN_BITS_192 , ///< 192 Data bits
AES_KEY_LEN_BITS_256 ///< 256 Data bits
} aes_key_len_bits_e;
/*----- AES Control Codes: Mode Parameters: Endian -----*/
typedef enum {
AES_ENDIAN_LITTLE = 0, ///< Little Endian
AES_ENDIAN_BIG ///< Big Endian
} aes_endian_mode_e;
/**
\brief AES Status
*/
typedef struct {
uint32_t busy : 1; ///< busy flag
} aes_status_t;
/****** AES Event *****/
typedef enum {
AES_EVENT_CRYPTO_COMPLETE = 0 ///< Encrypt completed
} aes_event_e;
typedef void (*aes_event_cb_t)(aes_event_e event); ///< Pointer to \ref aes_event_cb_t : AES Event call back.
/**
\brief AES Device Driver Capabilities.
*/
typedef struct {
uint32_t ecb_mode : 1; ///< supports ECB mode
uint32_t cbc_mode : 1; ///< supports CBC mode
uint32_t cfb_mode : 1; ///< supports CFB mode
uint32_t ofb_mode : 1; ///< supports OFB mode
uint32_t ctr_mode : 1; ///< supports CTR mode
uint32_t bits_128 : 1; ///< supports 128bits key length
uint32_t bits_192 : 1; ///< supports 192bits key length
uint32_t bits_256 : 1; ///< supports 256bits key length
} aes_capabilities_t;
// Function documentation
/**
\brief get aes instance count.
\return aes handle count
*/
int32_t csi_aes_get_instance_count(void);
/**
\brief Initialize AES Interface. 1. Initializes the resources needed for the AES interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_aes_get_instance_count().
\param[in] cb_event Pointer to \ref aes_event_cb_t
\return return aes handle if success
*/
aes_handle_t csi_aes_initialize(int32_t idx, aes_event_cb_t cb_event);
/**
\brief De-initialize AES Interface. stops operation and releases the software resources used by the interface
\param[in] handle aes handle to operate.
\return error code
*/
int32_t csi_aes_uninitialize(aes_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle aes handle to operate.
\return \ref aes_capabilities_t
*/
aes_capabilities_t csi_aes_get_capabilities(aes_handle_t handle);
/**
\brief config aes mode.
\param[in] handle aes handle to operate.
\param[in] mode \ref aes_mode_e
\param[in] keylen_bits \ref aes_key_len_bits_e
\param[in] endian \ref aes_endian_mode_e
\param[in] arg Pointer to the iv address when mode is cbc_mode
\return error code
*/
int32_t csi_aes_config(aes_handle_t handle,
aes_mode_e mode,
aes_key_len_bits_e keylen_bits,
aes_endian_mode_e endian,
uint32_t arg
);
/**
\brief set crypto key.
\param[in] handle aes handle to operate.
\param[in] context aes information context(NULL when hardware implementation)
\param[in] key Pointer to the key buf
\param[in] key_len the key len
\param[in] enc \ref aes_crypto_mode_e
\return error code
*/
int32_t csi_aes_set_key(aes_handle_t handle, void *context, void *key, uint32_t key_len, aes_crypto_mode_e enc);
/**
\brief encrypt or decrypt
\param[in] handle aes handle to operate.
\param[in] context aes information context(NULL when hardware implementation)
\param[in] in Pointer to the Source data
\param[out] out Pointer to the Result data.
\param[in] len the Source data len.
\param[in] padding \ref aes_padding_mode_e.
\return error code
*/
int32_t csi_aes_crypto(aes_handle_t handle, void *context, void *in, void *out, uint32_t len, aes_padding_mode_e padding);
/**
\brief Get AES status.
\param[in] handle aes handle to operate.
\return AES status \ref aes_status_t
*/
aes_status_t csi_aes_get_status(aes_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_AES_H_ */

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_common.h
* @brief Header File for Common Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _DRV_COMMON_H_
#define _DRV_COMMON_H_
#include <stdint.h>
#include <drv_errno.h>
#include "config.h"
/** pin definition */
typedef int32_t pin_t;
/// \details driver handle
typedef void *drv_handle_t;
/**
\brief General power states
*/
typedef enum {
DRV_POWER_OFF, ///< Power off: no operation possible
DRV_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events
DRV_POWER_FULL ///< Power on: full operation at maximum performance
} drv_power_stat_e;
#endif /* _DRV_COMMON_H */

View File

@ -0,0 +1,150 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_crc.h
* @brief Header File for CRC Driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_CRC_H_
#define _CSI_CRC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_errno.h>
#include <drv_common.h>
/****** CRC specific error codes *****/
#define CRC_ERROR_MODE (EDRV_SPECIFIC + 1) ///< Specified Mode not supported
/// definition for crc handle.
typedef void *crc_handle_t;
/*----- CRC Control Codes: Mode -----*/
typedef enum {
CRC_MODE_CRC8 = 0, ///< Mode CRC8
CRC_MODE_CRC16 , ///< Mode CRC16
CRC_MODE_CRC32 ///< Mode CRC32
} crc_mode_e;
/*----- CRC Control Codes: Mode Parameters: Key length -----*/
typedef enum {
CRC_STANDARD_CRC_ROHC = 0, ///< Standard CRC RHOC
CRC_STANDARD_CRC_MAXIM , ///< Standard CRC MAXIAM
CRC_STANDARD_CRC_X25 , ///< Standard CRC X25
CRC_STANDARD_CRC_CCITT , ///< Standard CRC CCITT
CRC_STANDARD_CRC_USB , ///< Standard CRC USB
CRC_STANDARD_CRC_IBM , ///< Standard CRC IBM
CRC_STANDARD_CRC_MODBUS ///< Standard CRC MODBUS
} crc_standard_crc_e;
/**
\brief CRC Status
*/
typedef struct {
uint32_t busy : 1; ///< busy flag
} crc_status_t;
/****** CRC Event *****/
typedef enum {
CRC_EVENT_CALCULATE_COMPLETE = 0, ///< Calculate completed
} crc_event_e;
typedef void (*crc_event_cb_t)(crc_event_e event); ///< Pointer to \ref crc_event_cb_t : CRC Event call back.
/**
\brief CRC Device Driver Capabilities.
*/
typedef struct {
uint32_t ROHC : 1; ///< supports ROHC mode
uint32_t MAXIM : 1; ///< supports MAXIM mode
uint32_t X25 : 1; ///< supports X25 mode
uint32_t CCITT : 1; ///< supports CCITT mode
uint32_t USB : 1; ///< supports USB mode
uint32_t IBM : 1; ///< supports IBM mode
uint32_t MODBUS : 1; ///< supports MODBUS mode
} crc_capabilities_t;
// Function documentation
/**
\brief get crc handle count.
\return crc handle count
*/
int32_t csi_crc_get_instance_count(void);
/**
\brief Initialize CRC Interface. 1. Initializes the resources needed for the CRC interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_crc_get_handle_count()
\param[in] cb_event Pointer to \ref crc_event_cb_t
\return return crc handle if success
*/
crc_handle_t csi_crc_initialize(int32_t idx, crc_event_cb_t cb_event);
/**
\brief De-initialize CRC Interface. stops operation and releases the software resources used by the interface
\param[in] handle crc handle to operate.
\return error code
*/
int32_t csi_crc_uninitialize(crc_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle crc handle to operate.
\return \ref crc_capabilities_t
*/
crc_capabilities_t csi_crc_get_capabilities(crc_handle_t handle);
/**
\brief config crc mode.
\param[in] handle crc handle to operate.
\param[in] mode \ref crc_mode_e
\param[in] standard \ref crc_standard_crc_e
\return error code
*/
int32_t csi_crc_config(crc_handle_t handle,
crc_mode_e mode,
crc_standard_crc_e standard
);
/**
\brief calculate crc.
\param[in] handle crc handle to operate.
\param[in] in Pointer to the input data
\param[out] out Pointer to the result.
\param[in] len intpu data len.
\return error code
*/
int32_t csi_crc_calculate(crc_handle_t handle, const void *in, void *out, uint32_t len);
/**
\brief Get CRC status.
\param[in] handle crc handle to operate.
\return CRC status \ref crc_status_t
*/
crc_status_t csi_crc_get_status(crc_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_CRC_H_ */

View File

@ -0,0 +1,171 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_dmac.h
* @brief header file for dmac driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_DMA_H_
#define _CSI_DMA_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for dmac handle.
typedef void *dmac_handle_t;
/**
\brief DMA Driver Capabilities.
*/
typedef struct {
uint32_t unalign_addr : 1; ///< support for unalign address transfer when memory is source
} dma_capabilities_t;
typedef enum {
DMA_STATE_FREE = 0, ///< DMA not yet initialized or disabled
DMA_STATE_READY, ///< DMA process success and ready for use, but not start yet
DMA_STATE_BUSY, ///< DMA process is ongoing
DMA_STATE_ERROR, ///< DMA transfer error
DMA_STATE_DONE, ///< DMA transfer done
} dma_status_e;
/****** DMA specific error codes *****/
typedef enum {
EDRV_DMA_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
} dma_error_e;
/****** DMA Event *****/
typedef enum {
DMA_EVENT_TRANSFER_DONE = 0, ///< transfer complete
DMA_EVENT_TRANSFER_ERROR = 1, ///< transfer error
} dma_event_e;
typedef enum {
DMA_ADDR_INC = 0,
DMA_ADDR_DEC,
DMA_ADDR_CONSTANT
} dma_addr_inc_e;
typedef enum {
DMA_MEM2MEM = 0,
DMA_MEM2PERH,
DMA_PERH2MEM,
DMA_PERH2PERH,
} dma_trans_type_e;
typedef struct {
dma_addr_inc_e src_inc; ///< source address increment
dma_addr_inc_e dst_inc; ///< destination address increment
uint8_t src_tw; ///< source transfer width in byte
uint8_t dst_tw; ///< destination transfer width in byte
uint8_t hs_if; ///< a hardware handshaking interface
dma_trans_type_e type; ///< transfer type
} dma_config_t;
typedef void (*dma_event_cb_t)(dma_event_e event, int32_t ch); ///< Pointer to \ref dma_event_cb_t : CRC Event call back.
/**
\brief get dma instance count.
\return dma instance count
*/
int32_t csi_dma_get_instance_count(void);
/**
\brief Initialize DMA Interface. 1. Initializes the resources needed for the DMA interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_dma_get_instance_count()
\return pointer to dma instances
*/
dmac_handle_t csi_dma_initialize(int32_t idx);
/**
\brief De-initialize DMA Interface. stops operation and releases the software resources used by the interface
\param[in] handle damc handle to operate.
\return error code
*/
int32_t csi_dma_uninitialize(dmac_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle damc handle to operate.
\return \ref dma_capabilities_t
*/
dma_capabilities_t csi_dma_get_capabilities(dmac_handle_t handle);
/**
\brief get one free dma channel
\param[in] handle damc handle to operate.
\param[in] ch channel num. if -1 then allocate a free channal in this dma
\return -1 - no channel can be used, other - channel index
*/
int32_t csi_dma_alloc_channel(dmac_handle_t handle, int32_t ch);
/**
\brief release dma channel and related resources
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return error code
*/
int32_t csi_dma_release_channel(dmac_handle_t handle, int32_t ch);
/**
\brief
\param[in] handle damc handle to operate.
\param[in] ch channel num. if -1 then allocate a free channal in this dma
\param[in] psrcaddr dma transfer source address
\param[in] pstdaddr dma transfer source address
\param[in] length dma transfer length
\param[in] config dma transfer configure
\param[in] cb_event Pointer to \ref dma_event_cb_t
\return error code
*/
int32_t csi_dma_config(dmac_handle_t handle, int32_t ch,
void *psrcaddr, void *pstdaddr,
uint32_t length, dma_config_t *config, dma_event_cb_t cb_event);
/**
\brief start generate dma signal.
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return error code
*/
int32_t csi_dma_start(dmac_handle_t handle, int32_t ch);
/**
\brief Stop generate dma signal.
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return error code
*/
int32_t csi_dma_stop(dmac_handle_t handle, int32_t ch);
/**
\brief Get DMA status.
\param[in] handle damc handle to operate.
\param[in] ch channel num.
\return DMA status \ref dma_status_e
*/
dma_status_e csi_dma_get_status(dmac_handle_t handle, int32_t ch);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_DMA_H_ */

View File

@ -0,0 +1,157 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_eflash.h
* @brief header file for eflash driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_EFLASH_H_
#define _CSI_EFLASH_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for eflash handle.
typedef void *eflash_handle_t;
/**
\brief Flash information
*/
typedef struct {
uint32_t start; ///< Chip Start address
uint32_t end; ///< Chip End address (start+size-1)
uint32_t sector_count; ///< Number of sectors
uint32_t sector_size; ///< Uniform sector size in bytes (0=sector_info used)
uint32_t page_size; ///< Optimal programming page size in bytes
uint32_t program_unit; ///< Smallest programmable unit in bytes
uint8_t erased_value; ///< Contents of erased memory (usually 0xFF)
} eflash_info;
/**
\brief Flash Status
*/
typedef struct {
uint32_t busy : 1; ///< Flash busy flag
uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation)
} eflash_status_t;
/****** EFLASH Event *****/
typedef enum {
EFLASH_EVENT_READY = 0, ///< Flash Ready
EFLASH_EVENT_ERROR , ///< Read/Program/Erase Error
} eflash_event_e;
typedef void (*eflash_event_cb_t)(eflash_event_e event); ///< Pointer to \ref eflash_event_cb_t : EFLASH Event call back.
/**
\brief Flash Driver Capabilities.
*/
typedef struct {
uint32_t event_ready : 1; ///< Signal Flash Ready event
uint32_t data_width : 2; ///< Data width: 0=8-bit, 1=16-bit, 2=32-bit
uint32_t erase_chip : 1; ///< Supports EraseChip operation
} eflash_capabilities_t;
// Function documentation
/**
\brief get eflash handle count.
\return eflash handle count
*/
int32_t csi_eflash_get_instance_count(void);
/**
\brief Initialize EFLASH Interface. 1. Initializes the resources needed for the EFLASH interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_eflash_get_instance_count()
\param[in] cb_event Pointer to \ref eflash_event_cb_t
\return pointer to eflash handle
*/
eflash_handle_t csi_eflash_initialize(int32_t idx, eflash_event_cb_t cb_event);
/**
\brief De-initialize EFLASH Interface. stops operation and releases the software resources used by the interface
\param[in] handle eflash handle to operate.
\return error code
*/
int32_t csi_eflash_uninitialize(eflash_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle eflash handle to operate.
\return \ref eflash_capabilities_t
*/
eflash_capabilities_t csi_eflash_get_capabilities(eflash_handle_t handle);
/**
\brief Read data from Flash.
\param[in] handle eflash handle to operate.
\param[in] addr Data address.
\param[out] data Pointer to a buffer storing the data read from Flash.
\param[in] cnt Number of data items to read.
\return number of data items read or error code
*/
int32_t csi_eflash_read(eflash_handle_t handle, uint32_t addr, void *data, uint32_t cnt);
/**
\brief Program data to Flash.
\param[in] handle eflash handle to operate.
\param[in] addr Data address.
\param[in] data Pointer to a buffer containing the data to be programmed to Flash..
\param[in] cnt Number of data items to program.
\return number of data items programmed or error code
*/
int32_t csi_eflash_program(eflash_handle_t handle, uint32_t addr, const void *data, uint32_t cnt);
/**
\brief Erase Flash Sector.
\param[in] handle eflash handle to operate.
\param[in] addr Sector address
\return error code
*/
int32_t csi_eflash_erase_sector(eflash_handle_t handle, uint32_t addr);
/**
\brief Erase complete Flash.
\param[in] handle eflash handle to operate.
\return error code
*/
int32_t csi_eflash_erase_chip(eflash_handle_t handle);
/**
\brief Get Flash information.
\param[in] handle eflash handle to operate.
\return Pointer to Flash information \ref eflash_info
*/
eflash_info *csi_eflash_get_info(eflash_handle_t handle);
/**
\brief Get EFLASH status.
\param[in] handle eflash handle to operate.
\return EFLASH status \ref eflash_status_t
*/
eflash_status_t csi_eflash_get_status(eflash_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_EFLASH_H_ */

View File

@ -0,0 +1,116 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_errno.h
* @brief header file for error num
* @version V1.0
* @date 02. June 2017
******************************************************************************/
/******************************************************************************
* @file
* @details Error code field difination
* Error number is devided into 4 field:
* 0x8******* : 8 : means < 0
* 0x*A****** : A : means type number: bsp(1), driver(2), hal(3), app(4)...
* 0x**AB**** : AB : means module number: timer(1), rtc(2), ....
* 0x****AB** : AB : means API number: module API's definition
* 0x******AB : AB : means sub error number
* 0 ~ 0x80 is common error such as EPERM, refer to errno.h
* 0x80 ~ 0xFF is specific error, can difine in module
*
* For example 0x81020113 means:
* 1. 0x8*******: value < 0, means error happened
* 2. 0x*1******: type number is 1, means bsp error
* 3. 0x**02****: module number is 02, means RTC error
* 4. 0x****01**: module API is 01, means RTC's init
* 5. 0x******13: specific error is 0x13=19=ENODEV, means no such device
*
* For special bsp module example, you can return:
* (BSP_ERRNO_TIMER_BASE | BSP_API_RTC_INIT | EPERM) for rtc init error
* (BSP_ERRNO_TIMER_BASE | BSP_API_RTC_SETTIME | ENXIO) for rtc settime error
*
* Here list the common sub error number (0x******AB) below(0~127 defined in errno.h as standard err code):
* Code Hex Deci Meaning
* -------------------------------------------------------
* EPERM 0x01 1 Operation not permitted
* EIO 0x05 5 I/O error
* ENXIO 0x06 6 No such device or address
* ENOMEM 0x0C 12 Out of memory
* EACCES 0x0D 13 Permission denied
* EINVAL 0x16 22 Invalid argument
* ...
* SPEC_ERR_BASE 0x80 128 module special error number base
* ...
* ERRNO_MAX 0xFF -- Max sub error number
******************************************************************************/
#ifndef _DRV_ERRNO_H_
#define _DRV_ERRNO_H_
#include <errno.h>
#define ERRNO_DRV_START 0X80
/* drvier General return codes */
typedef enum {
EDRV = ERRNO_DRV_START, ///< Unspecified error
EDRV_BUSY, ///< Driver is busy
EDRV_TIMEOUT, ///< Timeout occurred
EDRV_UNSUPPORTED, ///< Operation not supported
EDRV_PARAMETER, ///< Parameter error
EDRV_SPECIFIC ///< Start of driver specific errors
} drv_common_err_e;
/** Get error type */
#define GET_ERROR_TYPE(errno) \
(error & 0xFF000000 >> 24)
/** Get error module */
#define GET_ERROR_MODULE(error) \
(error & 0x00FF0000 >> 16)
/** Get error API */
#define GET_ERROR_API(error) \
(error & 0x0000FF00 >> 8)
/** Get errno */
#define GET_ERROR_NUM(error) \
(error & 0x000000FF)
#ifndef CSI_DRV_ERRNO_BASE
/** means bsp errors */
#define CSI_DRV_ERRNO_BASE 0x81000000
#endif
/** driver module id definition*/
#define CSI_DRV_ERRNO_GPIO_BASE 0x81010000
#define CSI_DRV_ERRNO_USART_BASE 0x81020000
#define CSI_DRV_ERRNO_SPI_BASE 0x81030000
#define CSI_DRV_ERRNO_I2C_BASE 0x81040000
#define CSI_DRV_ERRNO_FLASH_BASE 0x81050000
#define CSI_DRV_ERRNO_PWM_BASE 0x81060000
#define CSI_DRV_ERRNO_RTC_BASE 0x81070000
#define CSI_DRV_ERRNO_TIMER_BASE 0x81080000
#define CSI_DRV_ERRNO_WDT_BASE 0x81090000
#define CSI_DRV_ERRNO_AES_BASE 0x810A0000
#define CSI_DRV_ERRNO_CRC_BASE 0x810B0000
#define CSI_DRV_ERRNO_RSA_BASE 0x810C0000
#define CSI_DRV_ERRNO_SHA_BASE 0x810D0000
#define CSI_DRV_ERRNO_TRNG_BASE 0x810E0000
#define CSI_DRV_ERRNO_EFLASH_BASE 0x810F0000
#define CSI_DRV_ERRNO_DMA_BASE 0x81100000
#endif /* CSI_DRV_ERRNO_H */

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,183 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_gpio.h
* @brief header file for gpio driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_GPIO_H_
#define _CSI_GPIO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include <drv_common.h>
#include <pin_name.h>
/// definition for gpio port handle.
typedef void *gpio_port_handle_t;
/// definition for gpio pin handle.
typedef void *gpio_pin_handle_t;
/****** GPIO specific error codes *****/
typedef enum {
GPIO_ERROR_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not suphandleed
GPIO_ERROR_DIRECTION, ///< Specified direction not suphandleed
GPIO_ERROR_IRQ_MODE, ///< Specified irq mode not suphandleed
} drv_gpio_error_e;
/*----- GPIO Control Codes: Mode -----*/
typedef enum {
GPIO_MODE_PULLNONE = 0, ///< pull none for input
GPIO_MODE_PULLUP , ///< pull up for input
GPIO_MODE_PULLDOWM , ///< pull down for input
GPIO_MODE_OPEN_DRAIN , ///< open drain mode for output
GPIO_MODE_PUSH_PULL ///< push-pull mode for output
} gpio_mode_e;
/*----- GPIO Control Codes: Mode Parameters: Data Bits -----*/
typedef enum {
GPIO_DIRECTION_INPUT = 0, ///< gpio as input
GPIO_DIRECTION_OUTPUT , ///< gpio as output
} gpio_direction_e;
/*----- GPIO Control Codes: Mode Parameters: Parity -----*/
typedef enum {
GPIO_IRQ_MODE_RISING_EDGE = 0, ///< interrupt mode for rising edge
GPIO_IRQ_MODE_FALLING_EDGE , ///< interrupt mode for falling edge
GPIO_IRQ_MODE_DOUBLE_EDGE , ///< interrupt mode for double edge
GPIO_IRQ_MODE_LOW_LEVEL , ///< interrupt mode for low level
GPIO_IRQ_MODE_HIGH_LEVEL , ///< interrupt mode for high level
} gpio_irq_mode_e;
/**
\brief GPIO Driver Capabilities.
*/
typedef struct {
uint32_t interrupt_mode : 1; ///< suphandles GPIO interrupt mode
uint32_t pull_mode : 1;
} gpio_capabilities_t;
typedef void (*gpio_event_cb_t)(gpio_pin_handle_t io); ///< gpio Event call back.
/**
\brief Initialize GPIO module. 1. Initializes the resources needed for the GPIO handle 2.registers event callback function
3.get gpio_port_handle
\param[in] port port_name.
\param[in] cb_event Pointer to \ref gpio_event_cb_t
\return gpio_port_handle
*/
gpio_port_handle_t csi_gpio_port_initialize(port_name_t port, gpio_event_cb_t cb_event);
/**
\brief De-initialize GPIO handle. stops operation and releases the software resources used by the handle
\param[in] handle gpio port handle to operate.
\return error code
*/
int32_t csi_gpio_port_uninitialize(gpio_port_handle_t handle);
/**
\brief Get gpio capabilities.all pins have same capabilities in one handle
\param[in] handle handle instance to operate.
\return \ref gpio_capabilities_t
*/
gpio_capabilities_t csi_gpio_get_io_capabilities(gpio_port_handle_t handle);
/**
\brief config multiple pin within one handle
\param[in] handle gpio port handle to operate.
\param[in] mask the bitmask to identify which bits in the handle should be included (0 - ignore)
\param[in] mode \ref gpio_mode_e
\param[in] dir \ref gpio_direction_e
\return error code
*/
int32_t csi_gpio_port_config(gpio_port_handle_t handle,
uint32_t mask,
gpio_mode_e mode,
gpio_direction_e dir);
/**
\brief Write value to the handle(write value to multiple pins on one handle at the same time)
\param[in] handle gpio port handle to operate.
\param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
\param[in] value the value to be set
\return error code
*/
int32_t csi_gpio_port_write(gpio_port_handle_t handle, uint32_t mask, uint32_t value);
/**
\brief Read the current value on the handle(read value of multiple pins on one handle at the same time)
\param[in] handle gpio port handle to operate.
\param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
\param[out] value an integer with each bit corresponding to an associated handle pin setting
\return error code
*/
int32_t csi_gpio_port_read(gpio_port_handle_t handle, uint32_t mask, uint32_t *value);
/**
\brief Initialize GPIO handle.
\param[in] gpio_pin Pointer to the pin_t.
\return gpio_pin_handle
*/
gpio_pin_handle_t csi_gpio_pin_initialize(pin_t gpio_pin);
/**
\brief config pin
\param[in] pin gpio pin handle to operate.
\param[in] mode \ref gpio_mode_e
\param[in] dir \ref gpio_direction_e
\return error code
*/
int32_t csi_gpio_pin_config(gpio_pin_handle_t pin,
gpio_mode_e mode,
gpio_direction_e dir);
/**
\brief Set one or zero to the selected GPIO pin.
\param[in] pin gpio pin handle to operate.
\param[in] value the value to be set
\return error code
*/
int32_t csi_gpio_pin_write(gpio_pin_handle_t pin, bool value);
/**
\brief Get the value of selected GPIO pin.
\param[in] pin gpio pin handle to operate.
\param[out] value buf to store the pin value
\return error code
*/
int32_t csi_gpio_pin_read(gpio_pin_handle_t pin, bool *value);
/**
\brief set GPIO interrupt mode.
\param[in] pin gpio pin handle to operate.
\param[in] mode the irq mode to be set
\param[in] enable the enable flag
\return error code
*/
int32_t csi_gpio_pin_irq_set(gpio_pin_handle_t pin, gpio_irq_mode_e mode, bool enable);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_GPIO_H_ */

View File

@ -0,0 +1,195 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_iic.h
* @brief header file for iic driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_IIC_H_
#define _CSI_IIC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include <drv_common.h>
/// definition for iic handle.
typedef void *iic_handle_t;
/*----- IIC Control Codes: Mode -----*/
typedef enum {
IIC_MODE_MASTER, ///< IIC Master
IIC_MODE_SLAVE ///< IIC Slave
} iic_mode_e;
/*----- IIC Control Codes: IIC Bus Speed -----*/
typedef enum {
I2C_BUS_SPEED_STANDARD = 0, ///< Standard Speed (100kHz)
I2C_BUS_SPEED_FAST = 1, ///< Fast Speed (400kHz)
I2C_BUS_SPEED_FAST_PLUS = 2, ///< Fast+ Speed ( 1MHz)
I2C_BUS_SPEED_HIGH = 3 ///< High Speed (3.4MHz)
} iic_speed_e;
/*----- IIC Control Codes: IIC Address Mode -----*/
typedef enum {
I2C_ADDRESS_7BIT = 0, ///< 7-bit address mode
I2C_ADDRESS_10BIT = 1 ///< 10-bit address mode
} iic_address_mode_e;
/**
\brief IIC Status
*/
typedef struct {
uint32_t busy : 1; ///< Transmitter/Receiver busy flag
uint32_t mode : 1; ///< Mode: 0=Slave, 1=Master
uint32_t direction : 1; ///< Direction: 0=Transmitter, 1=Receiver
uint32_t general_call : 1; ///< General Call(address 0) indication (cleared on start of next Slave operation)
uint32_t arbitration_lost : 1; ///< Master lost arbitration(in case of multi-masters) (cleared on start of next Master operation)
uint32_t bus_error : 1; ///< Bus error detected (cleared on start of next Master/Slave operation)
} iic_status_t;
/****** IIC Event *****/
typedef enum {
I2C_EVENT_TRANSFER_DONE = 0, ///< Master/Slave Transmit/Receive finished
I2C_EVENT_TRANSFER_INCOMPLETE = 1, ///< Master/Slave Transmit/Receive incomplete transfer
I2C_EVENT_SLAVE_TRANSMIT = 2, ///< Slave Transmit operation requested
I2C_EVENT_SLAVE_RECEIVE = 3, ///< Slave Receive operation requested
I2C_EVENT_ADDRESS_NACK = 4, ///< Address not acknowledged from Slave
I2C_EVENT_GENERAL_CALL = 5, ///< General Call indication
I2C_EVENT_ARBITRATION_LOST = 6, ///< Master lost arbitration
I2C_EVENT_BUS_ERROR = 7, ///< Bus error detected (START/STOP at illegal position)
I2C_EVENT_BUS_CLEAR = 8 ///< Bus clear finished
} iic_event_e;
typedef void (*iic_event_cb_t)(iic_event_e event, void *arg); ///< Pointer to \ref iic_event_cb_t : IIC Event call back.
/**
\brief IIC Driver Capabilities.
*/
typedef struct {
uint32_t address_10_bit : 1; ///< supports 10-bit addressing
} iic_capabilities_t;
/**
\brief Initialize IIC Interface specified by pins. \n
1. Initializes the resources needed for the IIC interface 2.registers event callback function
\param[in] scl scl pin of iic.
\param[in] sda sda pin of iic.
\param[in] cb_event Pointer to \ref iic_event_cb_t
\param[in] cb_arg argument for call back function
\return 0 for success, negative for error code
*/
iic_handle_t csi_iic_initialize(pin_t scl, pin_t sda, iic_event_cb_t cb_event, void *cb_arg);
/**
\brief De-initialize IIC Interface. stops operation and releases the software resources used by the interface
\param[in] handle iic handle to operate.
\return 0 for success, negative for error code
*/
int32_t csi_iic_uninitialize(iic_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle iic handle to operate.
\return \ref iic_capabilities_t
*/
iic_capabilities_t csi_iic_get_capabilities(iic_handle_t handle);
/**
\brief config iic attributes.
\param[in] handle iic handle to operate.
\param[in] mode iic mode \ref iic_mode_e. if negative, then this attribute not changed.
\param[in] speed iic speed \ref iic_speed_e. if negative, then this attribute not changed.
\param[in] addr_mode iic address mode \ref iic_address_mode_e. if negative, then this attribute not changed.
\param[in] slave_addr iic address of slave. if negative, then this attribute not changed.
\return 0 for success, negative for error code
*/
int32_t csi_iic_config(iic_handle_t handle,
iic_mode_e mode,
iic_speed_e speed,
iic_address_mode_e addr_mode,
int32_t slave_addr);
/**
\brief Start transmitting data as I2C Master.
This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
\ref csi_iic_get_status can indicates transmission status.
\param[in] handle iic handle to operate.
\param[in] data data to send to I2C Slave
\param[in] num Number of data items to send
\param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
\return 0 for success, negative for error code
*/
int32_t csi_iic_master_send(iic_handle_t handle, const void *data, uint32_t num, bool xfer_pending);
/**
\brief Start receiving data as I2C Master.
This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
\ref csi_iic_get_status can indicates transmission status.
\param[in] handle iic handle to operate.
\param[out] data Pointer to buffer for data to receive from IIC receiver
\param[in] num Number of data items to receive
\param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
\return 0 for success, negative for error code
*/
int32_t csi_iic_master_receive(iic_handle_t handle, const void *data, uint32_t num, bool xfer_pending);
/**
\brief Start transmitting data as I2C Slave.
This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
\ref csi_iic_get_status can indicates transmission status.
\param[in] handle iic handle to operate.
\param[in] data Pointer to buffer with data to transmit to I2C Master
\param[in] num Number of data items to send
\return 0 for success, negative for error code
*/
int32_t csi_iic_slave_send(iic_handle_t handle, const void *data, uint32_t num);
/**
\brief Start receiving data as I2C Slave.
This function is non-blocking,\ref iic_event_e is signaled when transfer completes or error happens.
\ref csi_iic_get_status can indicates transmission status.
\param[in] handle iic handle to operate.
\param[out] data Pointer to buffer for data to receive from I2C Master
\param[in] num Number of data items to receive
\return 0 for success, negative for error code
*/
int32_t csi_iic_slave_receive(iic_handle_t handle, const void *data, uint32_t num);
/**
\brief abort transfer.
\param[in] handle iic handle to operate.
\return 0 for success, negative for error code
*/
int32_t csi_iic_abort_transfer(iic_handle_t handle);
/**
\brief Get IIC status.
\param[in] handle iic handle to operate.
\return IIC status \ref iic_status_t
*/
iic_status_t csi_iic_get_status(iic_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_IIC_H_ */

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_pwm.h
* @brief header file for pwm driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_PWM_H_
#define _CSI_PWM_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for pwm handle.
typedef void *pwm_handle_t;
/****** PWM specific error codes *****/
typedef enum {
EDRV_PWM_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
} drv_pwm_error_e;
/**
\brief Initialize PWM Interface. 1. Initializes the resources needed for the PWM interface 2.registers event callback function
\param[in] pwm_pin pin name of pwm
\return handle pwm handle to operate.
*/
pwm_handle_t drv_pwm_initialize(pin_t pwm_pin);
/**
\brief De-initialize PWM Interface. stops operation and releases the software resources used by the interface
\param[in] handle pwm handle to operate.
\return error code
*/
int32_t drv_pwm_uninitialize(pwm_handle_t handle);
/**
\brief config pwm mode.
\param[in] handle pwm handle to operate.
\param[in] sysclk configured system clock.
\param[in] period_us the PWM period in us
\param[in] duty the PMW duty. ( 0 - 10000 represents 0% - 100% ,other values are invalid)
\return error code
*/
int32_t drv_pwm_config(pwm_handle_t handle,
uint32_t sysclk,
uint32_t period_us,
uint32_t duty);
/**
\brief start generate pwm signal.
\param[in] handle pwm handle to operate.
\return error code
*/
int32_t drv_pwm_start(pwm_handle_t handle);
/**
\brief Stop generate pwm signal.
\param[in] handle pwm handle to operate.
\return error code
*/
int32_t drv_pwm_stop(pwm_handle_t handle);
/**
\brief Get PWM status.
\param[in] handle pwm handle to operate.
\return PWM status \ref pwm_status_t
pwm_status_t drv_pwm_get_status(pwm_handle_t handle);
*/
#ifdef __cplusplus
}
#endif
#endif /* _CSI_PWM_H_ */

View File

@ -0,0 +1,222 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_rsa.h
* @brief header file for rsa driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_RSA_H_
#define _CSI_RSA_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for rsa handle.
typedef void *rsa_handle_t;
/****** RSA specific error codes *****/
typedef enum {
RSA_ERROR_DATA_BITS , ///< Specified number of Data bits not supported
RSA_ERROR_ENDIAN ///< Specified endian not supported
} drv_rsa_error_e;
/*----- RSA Control Codes: Mode Parameters: Data Bits -----*/
typedef enum {
RSA_DATA_BITS_192 = 0, ///< 192 Data bits
RSA_DATA_BITS_256 , ///< 256 Data bits
RSA_DATA_BITS_512 , ///< 512 Data bits
RSA_DATA_BITS_1024 , ///< 1024 Data bits (default)
RSA_DATA_BITS_2048 ///< 2048 Data bits
} rsa_data_bits_e;
/*----- RSA Control Codes: Mode Parameters: Endian -----*/
typedef enum {
RSA_ENDIAN_MODE_LITTLE = 0, ///< RSA Little Endian Mode
RSA_ENDIAN_MODE_BIG ///< RSA Big Endian Mode
} rsa_endian_mode_e;
typedef enum {
RSA_PADDING_MODE_PKCS1 = 1, ///< RSA PKCS1 Padding Mode
RSA_PADDING_MODE_NO , ///< RSA NO Padding Mode
RSA_PADDING_MODE_SSLV23 , ///< RSA SSLV23 Padding Mode
RSA_PADDING_MODE_PKCS1_OAEP , ///< RSA PKCS1 OAEP Padding Mode
RSA_PADDING_MODE_X931 , ///< RSA X931 Padding Mode
RSA_PADDING_MODE_PSS ///< RSA PSS Padding Mode
} rsa_padding_type_e;
typedef enum {
RSA_HASH_TYPE_MD5 = 0,
RSA_HASH_TYPE_SHA1 ,
RSA_HASH_TYPE_SHA224 ,
RSA_HASH_TYPE_SHA256 ,
RSA_HASH_TYPE_SHA384 ,
RSA_HASH_TYPE_SHA512
} rsa_hash_type_e;
/*----- RSA Control Codes: Mode Parameters: Padding mode -----*/
typedef struct {
rsa_padding_type_e padding_type;
rsa_hash_type_e hash_type;
} rsa_padding_t;
/**
\brief RSA Status
*/
typedef struct {
uint32_t busy : 1; ///< Calculate busy flag
} rsa_status_t;
/****** RSA Event *****/
typedef enum {
RSA_EVENT_ENCRYPT_COMPLETE = 0, ///< Encrypt completed
RSA_EVENT_DECRYPT_COMPLETE , ///< Decrypt completed
RSA_EVENT_SIGN_COMPLETE , ///< Sign completed
RSA_EVENT_VERIFY_COMPLETE , ///< Verify completed
} rsa_event_e;
typedef void (*rsa_event_cb_t)(rsa_event_e event); ///< Pointer to \ref rsa_event_cb_t : RSA Event call back.
/**
\brief RSA Device Driver Capabilities.
*/
typedef struct {
uint32_t bits_192 : 1; ///< supports 192bits modular length
uint32_t bits_256 : 1; ///< supports 256bits modular length
uint32_t bits_512 : 1; ///< supports 512bits modular length
uint32_t bits_1024 : 1; ///< supports 1024bits modular length
uint32_t bits_2048 : 1; ///< supports 2048bits modular length
} rsa_capabilities_t;
// Function documentation
/**
\brief get rsa handle count.
\return rsa handle count
*/
int32_t csi_rsa_get_instance_count(void);
/**
\brief Initialize RSA Interface. 1. Initializes the resources needed for the RSA interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_rsa_get_instance_count()
\param[in] cb_event Pointer to \ref rsa_event_cb_t
\return pointer to rsa handle
*/
rsa_handle_t csi_rsa_initialize(int32_t idx, rsa_event_cb_t cb_event);
/**
\brief De-initialize RSA Interface. stops operation and releases the software resources used by the interface
\param[in] handle rsa handle to operate.
\return error code
*/
int32_t csi_rsa_uninitialize(rsa_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle rsa handle to operate.
\return \ref rsa_capabilities_t
*/
rsa_capabilities_t csi_rsa_get_capabilities(rsa_handle_t handle);
/**
\brief config rsa mode.
\param[in] handle rsa handle to operate.
\param[in] data_bits \ref rsa_data_bits_e
\param[in] endian \ref rsa_endian_mode_e
\return error code
*/
int32_t csi_rsa_config(rsa_handle_t handle,
rsa_data_bits_e data_bits,
rsa_endian_mode_e endian
);
/**
\brief encrypt
\param[in] handle rsa handle to operate.
\param[in] n Pointer to the public modulus
\param[in] e Pointer to the public exponent
\param[in] src Pointer to the source data.
\param[in] src_size the source data len
\param[out] out Pointer to the result buffer
\param[out] out_size the result size
\param[in] padding \ref rsa_padding_t
\return error code
*/
int32_t csi_rsa_encrypt(rsa_handle_t handle, void *n, void *e, void *src, int32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding);
/**
\brief decrypt
\param[in] handle rsa handle to operate.
\param[in] n Pointer to the public modulus
\param[in] d Pointer to the privte exponent
\param[in] src Pointer to the source data.
\param[in] src_size the source data len
\param[out] out Pointer to the result buffer
\param[out] out_size the result size
\param[in] padding \ref rsa_padding_t
\return error code
*/
int32_t csi_rsa_decrypt(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *out, uint32_t *out_size, rsa_padding_t padding);
/**
\brief rsa sign
\param[in] handle rsa handle to operate.
\param[in] n Pointer to the public modulus
\param[in] d Pointer to the privte exponent
\param[in] src Pointer to the source data.
\param[in] src_size the source data len
\param[out] signature Pointer to the signature
\param[out] sig_size the signature size
\param[in] padding \ref rsa_padding_t
\return error code
*/
int32_t csi_rsa_sign(rsa_handle_t handle, void *n, void *d, void *src, uint32_t src_size, void *signature, void *sig_size, rsa_padding_t padding);
/**
\brief rsa verify
\param[in] handle rsa handle to operate.
\param[in] n Pointer to the public modulus
\param[in] e Pointer to the public exponent
\param[in] src Pointer to the source data.
\param[in] src_size the source data len
\param[in] signature Pointer to the signature
\param[in] sig_size the signature size
\param[out] result Pointer to the result
\param[in] padding \ref rsa_padding_t
\return error code
*/
int32_t csi_rsa_verify(rsa_handle_t handle, void *n, void *e, void *src, uint32_t src_size, void *signature, uint32_t sig_size, void *result, rsa_padding_t padding);
/**
\brief Get RSA status.
\param[in] handle rsa handle to operate.
\return RSA status \ref rsa_status_t
*/
rsa_status_t csi_rsa_get_status(rsa_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_RSA_H_ */

View File

@ -0,0 +1,161 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_rtc.h
* @brief header file for rtc driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_RTC_H_
#define _CSI_RTC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
#include <time.h>
/// definition for rtc handle.
typedef void *rtc_handle_t;
/****** rtc specific error codes *****/
typedef enum {
EDRV_RTC_TIME = (EDRV_SPECIFIC + 1), ///< timer data not supported
} drv_rtc_error_e;
/**
\brief RTC Status
*/
typedef struct {
uint32_t active : 1; ///< rtc is running or not
} rtc_status_t;
/****** RTC Event *****/
typedef enum {
RTC_EVENT_TIMER_INTRERRUPT = 0 ///< generate interrupt
} rtc_event_e;
typedef void (*rtc_event_cb_t)(rtc_event_e event); ///< Pointer to \ref rtc_event_cb_t : RTC Event call back.
/**
\brief RTC Device Driver Capabilities.
*/
typedef struct {
uint32_t interrupt_mode : 1; ///< supports Interrupt mode
uint32_t wrap_mode : 1; ///< supports wrap mode
} rtc_capabilities_t;
/**
\brief get rtc instance count.
\return rtc instance count
*/
int32_t csi_rtc_get_instance_count(void);
/**
\brief Initialize RTC Interface. 1. Initializes the resources needed for the RTC interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_rtc_get_instance_count()
\param[in] cb_event Pointer to \ref rtc_event_cb_t
\return pointer to rtc instance
*/
rtc_handle_t csi_rtc_initialize(int32_t idx, rtc_event_cb_t cb_event);
/**
\brief De-initialize RTC Interface. stops operation and releases the software resources used by the interface
\param[in] handle rtc handle to operate.
\return error code
*/
int32_t csi_rtc_uninitialize(rtc_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle rtc handle to operate.
\return \ref rtc_capabilities_t
*/
rtc_capabilities_t csi_rtc_get_capabilities(rtc_handle_t handle);
/**
\brief Set RTC timer.
\param[in] handle rtc handle to operate.
\param[in] rtctime pointer to rtc time
\return error code
*/
int32_t csi_rtc_set_time(rtc_handle_t handle, const struct tm *rtctime);
/**
\brief Get RTC timer.
\param[in] handle rtc handle to operate.
\param[in] rtctime pointer to rtc time
\return error code
*/
int32_t csi_rtc_get_time(rtc_handle_t handle, struct tm *rtctime);
/**
\brief Start RTC timer.
\param[in] handle rtc handle to operate.
\return error code
*/
int32_t csi_rtc_start(rtc_handle_t handle);
/**
\brief Stop RTC timer.
\param[in] handle rtc handle to operate.
\return error code
*/
int32_t csi_rtc_stop(rtc_handle_t handle);
/**
\brief config rtc mode.
\param[in] handle rtc handle to operate.
\return error code
*/
//int32_t drv_rtc_config (rtc_handle_t handle/*,rtc_mode_e mode*/);
/**
\brief Get RTC status.
\param[in] handle rtc handle to operate.
\return RTC status \ref rtc_status_t
*/
rtc_status_t csi_rtc_get_status(rtc_handle_t handle);
/**
\brief config RTC timer.
\param[in] handle rtc handle to operate.
\param[in] rtctime time to wake up
\return error code
*/
int32_t csi_rtc_timer_config(rtc_handle_t handle, const struct tm *rtctime);
/**
\brief disable or enable RTC timer.
\param[in] handle rtc handle to operate.
\param[in] en set 1 enable for rtc timer
\return error code
*/
int32_t csi_rtc_timer_enable(rtc_handle_t handle, uint8_t en);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_RTC_H_ */

View File

@ -0,0 +1,172 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_sha.h
* @brief header file for sha driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_SHA_H_
#define _CSI_SHA_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
#include <drv_errno.h>
/// definition for sha handle.
typedef void *sha_handle_t;
/****** SHA specific error codes *****/
typedef enum {
SHA_ERROR_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
SHA_ERROR_ENDIAN ///< Specified endian not supported
} drv_sha_error_e;
/*----- SHA Control Codes: Mode -----*/
typedef enum {
SHA_MODE_1 = 1, ///< SHA_1 mode
SHA_MODE_256 , ///< SHA_256 mode
SHA_MODE_224 , ///< SHA_224 mode
SHA_MODE_512 , ///< SHA_512 mode
SHA_MODE_384 , ///< SHA_384 mode
SHA_MODE_512_256 , ///< SHA_512_256 mode
SHA_MODE_512_224 ///< SHA_512_224 mode
} sha_mode_e;
/*----- SHA Control Codes: Mode Parameters: Endian -----*/
typedef enum {
SHA_ENDIAN_MODE_BIG = 0, ///< Big Endian Mode
SHA_ENDIAN_MODE_LITTLE , ///< Little Endian Mode
} sha_endian_mode_e;
/**
\brief SHA Status
*/
typedef struct {
uint32_t busy : 1; ///< calculate busy flag
} sha_status_t;
/****** SHA Event *****/
typedef enum {
SHA_EVENT_COMPLETE = 0 ///< calculate completed
} sha_event_e;
typedef void (*sha_event_cb_t)(sha_event_e event); ///< Pointer to \ref sha_event_cb_t : SHA Event call back.
/**
\brief SHA Device Driver Capabilities.
*/
typedef struct {
uint32_t sha1 : 1; ///< supports sha1 mode
uint32_t sha224 : 1; ///< supports sha224 mode
uint32_t sha256 : 1; ///< supports sha256 mode
uint32_t sha384 : 1; ///< supports sha384 mode
uint32_t sha512 : 1; ///< supports sha512 mode
uint32_t sha512_224 : 1; ///< supports sha512_224 mode
uint32_t sha512_256 : 1; ///< supports sha512_256 mode
uint32_t endianmode : 1; ///< supports endian mode control
uint32_t interruptmode : 1; ///< supports interrupt mode
} sha_capabilities_t;
// Function documentation
/**
\brief get sha handle count.
\return sha handle count
*/
int32_t csi_sha_get_instance_count(void);
/**
\brief Initialize SHA Interface. 1. Initializes the resources needed for the SHA interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_sha_get_instance_count()
\param[in] cb_event Pointer to \ref sha_event_cb_t
\return return sha handle if success
*/
sha_handle_t csi_sha_initialize(int32_t idx, sha_event_cb_t cb_event);
/**
\brief De-initialize SHA Interface. stops operation and releases the software resources used by the interface
\param[in] handle sha handle to operate.
\return error code
*/
int32_t csi_sha_uninitialize(sha_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle sha handle to operate.
\return \ref sha_capabilities_t
*/
sha_capabilities_t csi_sha_get_capabilities(sha_handle_t handle);
/**
\brief config sha mode.
\param[in] handle sha handle to operate.
\param[in] mode \ref sha_mode_e
\param[in] endian \ref sha_endian_mode_e
\return error code
*/
int32_t csi_sha_config(sha_handle_t handle,
sha_mode_e mode,
sha_endian_mode_e endian
);
/**
\brief start the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\return error code
*/
int32_t csi_sha_starts(sha_handle_t handle, void *context);
/**
\brief updata the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\param[in] input Pointer to the Source data
\param[in] len the data len
\return error code
*/
int32_t csi_sha_update(sha_handle_t handle, void *context, const void *input, uint32_t len);
/**
\brief finish the engine
\param[in] handle sha handle to operate.
\param[in] context Pointer to the sha context.
\param[out] output Pointer to the dest data
\return error code
*/
int32_t csi_sha_finish(sha_handle_t handle, void *context, void *output);
/**
\brief Get SHA status.
\param[in] handle sha handle to operate.
\return SHA status \ref sha_status_t
*/
sha_status_t csi_sha_get_status(sha_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_SHA_H_ */

View File

@ -0,0 +1,240 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_spi.h
* @brief header file for spi driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_SPI_H_
#define _CSI_SPI_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
#include <config.h>
#ifdef CONFIG_SPI_DMA
#include <drv_dmac.h>
#endif
/// definition for spi handle.
typedef void *spi_handle_t;
/****** SPI specific error codes *****/
typedef enum {
EDRV_SPI_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
EDRV_SPI_FRAME_FORMAT, ///< Specified Frame Format not supported
EDRV_SPI_DATA_BITS, ///< Specified number of Data bits not supported
EDRV_SPI_BIT_ORDER, ///< Specified Bit order not supported
EDRV_SPI_SS_MODE ///< Specified Slave Select Mode not supported
} drv_spi_err_e;
/*----- SPI Control Codes: Mode -----*/
typedef enum {
SPI_MODE_INACTIVE = 0, ///< SPI Inactive
SPI_MODE_MASTER, ///< SPI Master (Output on MOSI, Input on MISO); arg = Bus Speed in bps
SPI_MODE_SLAVE, ///< SPI Slave (Output on MISO, Input on MOSI)
SPI_MODE_MASTER_SIMPLEX, ///< SPI Master (Output/Input on MOSI); arg = Bus Speed in bps
SPI_MODE_SLAVE_SIMPLEX ///< SPI Slave (Output/Input on MISO)
} spi_mode_e;
/*----- SPI Control Codes: Mode Parameters: Frame Format -----*/
typedef enum {
SPI_FORMAT_CPOL0_CPHA0 = 0, ///< Clock Polarity 0, Clock Phase 0 (default)
SPI_FORMAT_CPOL0_CPHA1, ///< Clock Polarity 0, Clock Phase 1
SPI_FORMAT_CPOL1_CPHA0, ///< Clock Polarity 1, Clock Phase 0
SPI_FORMAT_CPOL1_CPHA1, ///< Clock Polarity 1, Clock Phase 1
} spi_format_e;
/*----- SPI Control Codes: Mode Parameters: Bit Order -----*/
typedef enum {
SPI_ORDER_MSB2LSB = 0, ///< SPI Bit order from MSB to LSB (default)
SPI_ORDER_LSB2MSB ///< SPI Bit order from LSB to MSB
} spi_bit_order_e;
/*----- SPI Control Codes: Mode Parameters: Data Width in bits -----*/
#define SPI_DATAWIDTH_MAX 32 /* 1 ~ 32 bit*/
/*----- SPI Control Codes: Mode Parameters: Slave Select Mode -----*/
typedef enum {
/*options for SPI_MODE_MASTER/SPI_MODE_MASTER_SIMPLEX */
SPI_SS_MASTER_UNUSED = 0, ///< SPI Slave Select when Master: Not used (default).SS line is not controlled by master, For example,SS line connected to a fixed low level
SPI_SS_MASTER_SW, ///< SPI Slave Select when Master: Software controlled. SS line is configured by software
SPI_SS_MASTER_HW_OUTPUT, ///< SPI Slave Select when Master: Hardware controlled Output.SS line is activated or deactivated automatically by hardware
SPI_SS_MASTER_HW_INPUT, ///< SPI Slave Select when Master: Hardware monitored Input.Used in multi-master configuration where a master does not drive the Slave Select when driving the bus, but rather monitors it
/*options for SPI_MODE_SLAVE/SPI_MODE_SLAVE_SIMPLEX */
SPI_SS_SLAVE_HW, ///< SPI Slave Select when Slave: Hardware monitored (default).Hardware monitors the Slave Select line and accepts transfers only when the line is active
SPI_SS_SLAVE_SW ///< SPI Slave Select when Slave: Software controlled.Used only when the Slave Select line is not used. Software controls if the slave is responding or not(enables or disables transfers)
} spi_ss_mode_e;
/****** SPI Slave Select Signal definitions *****/
typedef enum {
SPI_SS_INACTIVE = 0, ///< SPI Slave Select Signal/line Inactive
SPI_SS_ACTIVE ///< SPI Slave Select Signal/line Active
} spi_ss_stat_e;
/**
\brief SPI Status
*/
typedef struct {
uint32_t busy : 1; ///< Transmitter/Receiver busy flag
uint32_t data_lost : 1; ///< Data lost: Receive overflow / Transmit underflow (cleared on start of transfer operation)
uint32_t mode_fault : 1; ///< Mode fault detected; optional (cleared on start of transfer operation)
} spi_status_t;
/****** SPI Event *****/
typedef enum {
SPI_EVENT_TRANSFER_COMPLETE = 0, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation
SPI_EVENT_TX_COMPLETE, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation
SPI_EVENT_RX_COMPLETE, ///< Data Transfer completed. Occurs after call to ARM_SPI_Send, ARM_SPI_Receive, or ARM_SPI_Transfer to indicate that all the data has been transferred. The driver is ready for the next transfer operation
SPI_EVENT_DATA_LOST, ///< Data lost: Receive overflow / Transmit underflow. Occurs in slave mode when data is requested/sent by master but send/receive/transfer operation has not been started and indicates that data is lost. Occurs also in master mode when driver cannot transfer data fast enough.
SPI_EVENT_MODE_FAULT ///< Master Mode Fault (SS deactivated when Master).Occurs in master mode when Slave Select is deactivated and indicates Master Mode Fault. The driver is ready for the next transfer operation.
} spi_event_e;
typedef void (*spi_event_cb_t)(spi_event_e event, void *arg); ///< Pointer to \ref spi_event_cb_t : SPI Event call back.
/**
\brief SPI Driver Capabilities.
*/
typedef struct {
uint32_t simplex : 1; ///< supports Simplex Mode (Master and Slave)
uint32_t ti_ssi : 1; ///< supports TI Synchronous Serial Interface
uint32_t microwire : 1; ///< supports Microwire Interface
uint32_t event_mode_fault : 1; ///< Signal Mode Fault event: \ref spi_event_e
} spi_capabilities_t;
/**
\brief Initialize SPI Interface. 1. Initializes the resources needed for the SPI interface 2.registers event callback function
\param[in] mosi spi pin of mosi
\param[in] miso spi pin of miso
\param[in] sclk spi pin of sclk
\param[in] ssel spi pin of ssel
\param[in] cb_event event call back function \ref spi_event_cb_t
\param[in] cb_arg argument for call back function
\return return spi handle if success
*/
spi_handle_t csi_spi_initialize(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel, spi_event_cb_t cb_event, void *cb_arg);
/**
\brief De-initialize SPI Interface. stops operation and releases the software resources used by the interface
\param[in] handle spi handle to operate.
\return error code
*/
int32_t csi_spi_uninitialize(spi_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle spi handle to operate.
\return \ref spi_capabilities_t
*/
spi_capabilities_t csi_spi_get_capabilities(spi_handle_t handle);
/**
\brief config spi mode.
\param[in] handle spi handle to operate.
\param[in] sysclk sysclk for spi module.
\param[in] baud spi baud rate. if negative, then this attribute not changed
\param[in] mode \ref spi_mode_e . if negative, then this attribute not changed
\param[in] format \ref spi_format_e . if negative, then this attribute not changed
\param[in] order \ref spi_bit_order_e . if negative, then this attribute not changed
\param[in] ss_mode \ref spi_ss_mode_e . if negative, then this attribute not changed
\param[in] bit_width spi data bitwidth: (1 ~ SPI_DATAWIDTH_MAX) . if negative, then this attribute not changed
\return error code
*/
int32_t csi_spi_config(spi_handle_t handle,
int32_t sysclk,
int32_t baud,
spi_mode_e mode,
spi_format_e format,
spi_bit_order_e order,
spi_ss_mode_e ss_mode,
int32_t bit_width);
/**
\brief config spi default tx value.
\param[in] handle spi handle to operate.
\param[in] value default tx value
\return error code
*/
int32_t csi_spi_set_default_tx_value(spi_handle_t handle, uint32_t value);
/**
\brief sending data to SPI transmitter,(received data is ignored).
if non-blocking mode, this function only start the sending,
\ref spi_event_e is signaled when operation completes or error happens.
\ref csi_spi_get_status can indicates operation status.
if blocking mode, this function return after operation completes or error happens.
\param[in] handle spi handle to operate.
\param[in] data Pointer to buffer with data to send to SPI transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits,
\param[in] num Number of data items to send.
\param[in] block_mode blocking and non_blocking to selcect
\return error code
*/
int32_t csi_spi_send(spi_handle_t handle, const void *data, uint32_t num, uint8_t block_mode);
/**
\brief receiving data from SPI receiver.transmits the default value as specified by csi_spi_set_default_tx_value
if non-blocking mode, this function only start the receiving,
\ref spi_event_e is signaled when operation completes or error happens.
\ref csi_spi_get_status can indicates operation status.
if blocking mode, this function return after operation completes or error happens.
\param[in] handle spi handle to operate.
\param[out] data Pointer to buffer for data to receive from SPI receiver
\param[in] num Number of data items to receive
\param[in] block_mode blocking and non_blocking to selcect
\return error code
*/
int32_t csi_spi_receive(spi_handle_t handle, void *data, uint32_t num, uint8_t block_mode);
/**
\brief sending/receiving data to/from SPI transmitter/receiver.
if non-blocking mode, this function only start the transfer,
\ref spi_event_e is signaled when operation completes or error happens.
\ref csi_spi_get_status can indicates operation status.
if blocking mode, this function return after operation completes or error happens.
\param[in] handle spi handle to operate.
\param[in] data_out Pointer to buffer with data to send to SPI transmitter
\param[out] data_in Pointer to buffer for data to receive from SPI receiver
\param[in] num_out Number of data items to send
\param[in] num_in Number of data items to receive
\param[in] block_mode blocking and non_blocking to selcect
\return error code
*/
int32_t csi_spi_transfer(spi_handle_t handle, const void *data_out, void *data_in, uint32_t num_out, uint32_t num_in, uint8_t block_mode);
/**
\brief abort spi transfer.
\param[in] handle spi handle to operate.
\return error code
*/
int32_t csi_spi_abort_transfer(spi_handle_t handle);
/**
\brief Get SPI status.
\param[in] handle spi handle to operate.
\return SPI status \ref spi_status_t
*/
spi_status_t csi_spi_get_status(spi_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_SPI_H_ */

View File

@ -0,0 +1,160 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_timer.h
* @brief header file for timer driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_TIMER_H_
#define _CSI_TIMER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for timer handle.
typedef void *timer_handle_t;
/*----- TIMER Control Codes: Mode -----*/
typedef enum {
TIMER_MODE_FREE_RUNNING = 0, ///< free running mode
TIMER_MODE_RELOAD ///< reload mode
} timer_mode_e;
/**
\brief TIMER Status
*/
typedef struct {
uint32_t active : 1; ///< timer active flag
uint32_t timeout : 1; ///< timeout flag
} timer_status_t;
/**
\brief TIMER Event
*/
typedef enum {
TIMER_EVENT_TIMEOUT = 0 ///< time out event
} timer_event_e;
typedef void (*timer_event_cb_t)(timer_event_e event, void *arg); ///< Pointer to \ref timer_event_cb_t : TIMER Event call back.
/**
\brief TIMER Device Driver Capabilities.
*/
typedef struct {
uint32_t interrupt_mode : 1; ///< supports Interrupt mode
} timer_capabilities_t;
/**
\brief get timer instance count.
\return timer instance count
*/
int32_t csi_timer_get_instance_count(void);
/**
\brief Initialize TIMER Interface. 1. Initializes the resources needed for the TIMER interface 2.registers event callback function
\param[in] idx instance timer index
\param[in] cb_event Pointer to \ref timer_event_cb_t
\param[in] cb_arg arguments of cb_event
\return pointer to timer instance
*/
timer_handle_t csi_timer_initialize(int32_t idx, timer_event_cb_t cb_event, void *cb_arg);
/**
\brief De-initialize TIMER Interface. stops operation and releases the software resources used by the interface
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_uninitialize(timer_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle timer handle to operate.
\return \ref timer_capabilities_t
*/
timer_capabilities_t csi_timer_get_capabilities(timer_handle_t handle);
/**
\brief config timer mode.
\param[in] handle timer handle to operate.
\param[in] mode \ref timer_mode_e
\return error code
*/
int32_t csi_timer_config(timer_handle_t handle, timer_mode_e mode);
/**
\brief Set timer.
\param[in] handle timer handle to operate.
\param[in] timeout the timeout value in microseconds(us).
\return error code
*/
int32_t csi_timer_set_timeout(timer_handle_t handle, uint32_t timeout);
/**
\brief Start timer.
\param[in] handle timer handle to operate.
\param[in] apbfreq APB frequency
\return error code
*/
int32_t csi_timer_start(timer_handle_t handle, uint32_t apbfreq);
/**
\brief Stop timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_stop(timer_handle_t handle);
/**
\brief suspend timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_suspend(timer_handle_t handle);
/**
\brief resume timer.
\param[in] handle timer handle to operate.
\return error code
*/
int32_t csi_timer_resume(timer_handle_t handle);
/**
\brief get timer current value
\param[in] handle timer handle to operate.
\param[in] value timer current value
\return error code
*/
int32_t csi_timer_get_current_value(timer_handle_t handle, uint32_t *value);
/**
\brief Get TIMER status.
\param[in] handle timer handle to operate.
\return TIMER status \ref timer_status_t
*/
timer_status_t csi_timer_get_status(timer_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_TIMER_H_ */

View File

@ -0,0 +1,118 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_trng.h
* @brief header file for trng driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_TRNG_H_
#define _CSI_TRNG_H_
#include "drv_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/// definition for trng handle.
typedef void *trng_handle_t;
/****** TRNG specific error codes *****/
typedef enum {
TRNG_ERROR_MODE = 0, ///< Specified Mode not supported
} drv_trng_error_e;
/*----- TRNG Control Codes: Mode -----*/
typedef enum {
TRNG_MODE_LOWPOWER = 0, ///< TRNG Low power Mode
TRNG_MODE_NORMAL ///< TRNG Normal Mode
} trng_mode_e;
/**
\brief TRNG Status
*/
typedef struct {
uint32_t busy : 1;
uint32_t data_valid : 1; ///< Data is valid flag
} trng_status_t;
/****** TRNG Event *****/
typedef enum {
TRNG_EVENT_DATA_GENERATE_COMPLETE = 0 ///< Get data from TRNG success
} trng_event_e;
typedef void (*trng_event_cb_t)(trng_event_e event); ///< Pointer to \ref trng_event_cb_t : TRNG Event call back.
/**
\brief TRNG Device Driver Capabilities.
*/
typedef struct {
uint32_t lowper_mode : 1; ///< supports low power mode
} trng_capabilities_t;
// Function documentation
/**
\brief get trng handle count.
\return trng handle count
*/
int32_t csi_trng_get_instance_count(void);
/**
\brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_trng_get_instance_count()
\param[in] cb_event Pointer to \ref trng_event_cb_t
\return pointer to trng handle
*/
trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event);
/**
\brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface
\param[in] handle trng handle to operate.
\return error code
*/
int32_t csi_trng_uninitialize(trng_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle trng handle to operate.
\return \ref trng_capabilities_t
*/
trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle);
/**
\brief Get data from the TRNG.
\param[in] handle trng handle to operate.
\param[out] data Pointer to buffer with data get from TRNG
\param[in] num Number of data items to obtain
\return error code
*/
int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num);
/**
\brief Get TRNG status.
\param[in] handle trng handle to operate.
\return TRNG status \ref trng_status_t
*/
trng_status_t csi_trng_get_status(trng_handle_t handle);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_TRNG_H_ */

View File

@ -0,0 +1,282 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_usart.h
* @brief header file for usart driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_USART_H_
#define _CSI_USART_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <drv_common.h>
/// definition for usart handle.
typedef void *usart_handle_t;
/****** USART specific error codes *****/
typedef enum {
EDRV_USART_MODE = (EDRV_SPECIFIC + 1), ///< Specified Mode not supported
EDRV_USART_BAUDRATE, ///< Specified baudrate not supported
EDRV_USART_DATA_BITS, ///< Specified number of Data bits not supported
EDRV_USART_PARITY, ///< Specified Parity not supported
EDRV_USART_STOP_BITS, ///< Specified number of Stop bits not supported
EDRV_USART_FLOW_CONTROL, ///< Specified Flow Control not supported
EDRV_USART_CPOL, ///< Specified Clock Polarity not supported
EDRV_USART_CPHA ///< Specified Clock Phase not supported
} drv_usart_error_e;
/*----- USART Control Codes: Mode -----*/
typedef enum {
USART_MODE_ASYNCHRONOUS = 0, ///< USART (Asynchronous)
USART_MODE_SYNCHRONOUS_MASTER , ///< Synchronous Master
USART_MODE_SYNCHRONOUS_SLAVE , ///< Synchronous Slave (external clock signal)
USART_MODE_SINGLE_WIRE ///< USART Single-wire (half-duplex)
} usart_mode_e;
/*----- USART Control Codes: Mode Parameters: Data Bits -----*/
typedef enum {
USART_DATA_BITS_5 = 0, ///< 5 Data bits
USART_DATA_BITS_6 , ///< 6 Data bit
USART_DATA_BITS_7 , ///< 7 Data bits
USART_DATA_BITS_8 , ///< 8 Data bits (default)
USART_DATA_BITS_9 ///< 9 Data bits
} usart_data_bits_e;
/*----- USART Control Codes: Mode Parameters: Parity -----*/
typedef enum {
USART_PARITY_NONE = 0, ///< No Parity (default)
USART_PARITY_EVEN , ///< Even Parity
USART_PARITY_ODD , ///< Odd Parity
USART_PARITY_1 , ///< Parity forced to 1
USART_PARITY_0 ///< Parity forced to 0
} usart_parity_e;
/*----- USART Control Codes: Mode Parameters: Stop Bits -----*/
typedef enum {
USART_STOP_BITS_1 = 0, ///< 1 Stop bit (default)
USART_STOP_BITS_2 , ///< 2 Stop bits
USART_STOP_BITS_1_5 , ///< 1.5 Stop bits
USART_STOP_BITS_0_5 ///< 0.5 Stop bits
} usart_stop_bits_e;
/*----- USART Control Codes: Mode Parameters: Clock Polarity (Synchronous mode) -----*/
typedef enum {
USART_CPOL0 = 0, ///< CPOL = 0 (default)
USART_CPOL1 ///< CPOL = 1
} usart_cpol_e;
/*----- USART Control Codes: Mode Parameters: Clock Phase (Synchronous mode) -----*/
typedef enum {
USART_CPHA0 = 0, ///< CPHA = 0 (default)
USART_CPHA1 ///< CPHA = 1
} usart_cpha_e;
/*----- USART Control Codes: flush data type-----*/
typedef enum {
USART_FLUSH_WRITE,
USART_FLUSH_READ
} usart_flush_type_e;
/**
\brief USART Status
*/
typedef struct {
uint32_t tx_busy : 1; ///< Transmitter busy flag
uint32_t rx_busy : 1; ///< Receiver busy flag
uint32_t tx_underflow : 1; ///< Transmit data underflow detected (cleared on start of next send operation)(Synchronous Slave)
uint32_t rx_overflow : 1; ///< Receive data overflow detected (cleared on start of next receive operation)
uint32_t rx_break : 1; ///< Break detected on receive (cleared on start of next receive operation)
uint32_t rx_framing_error : 1; ///< Framing error detected on receive (cleared on start of next receive operation)
uint32_t rx_parity_error : 1; ///< Parity error detected on receive (cleared on start of next receive operation)
} usart_status_t;
/****** USART Event *****/
typedef enum {
USART_EVENT_SEND_COMPLETE = 0, ///< Send completed; however USART may still transmit data
USART_EVENT_RECEIVE_COMPLETE = 1, ///< Receive completed
USART_EVENT_RECEIVED = 2, ///< Receiving data
USART_EVENT_TRANSFER_COMPLETE = 3, ///< Transfer completed
USART_EVENT_TX_COMPLETE = 4, ///< Transmit completed (optional)
USART_EVENT_TX_UNDERFLOW = 5, ///< Transmit data not available (Synchronous Slave)
USART_EVENT_RX_OVERFLOW = 6, ///< Receive data overflow
USART_EVENT_RX_TIMEOUT = 7, ///< Receive character timeout (optional)
USART_EVENT_RX_BREAK = 8, ///< Break detected on receive
USART_EVENT_RX_FRAMING_ERROR = 9, ///< Framing error detected on receive
USART_EVENT_RX_PARITY_ERROR = 10, ///< Parity error detected on receive
} usart_event_e;
typedef void (*usart_event_cb_t)(usart_event_e event, void *cb_arg); ///< Pointer to \ref usart_event_cb_t : USART Event call back.
/**
\brief USART Driver Capabilities.
*/
typedef struct {
uint32_t asynchronous : 1; ///< supports USART (Asynchronous) mode
uint32_t synchronous_master : 1; ///< supports Synchronous Master mode
uint32_t synchronous_slave : 1; ///< supports Synchronous Slave mode
uint32_t single_wire : 1; ///< supports USART Single-wire mode
uint32_t event_tx_complete : 1; ///< Transmit completed event
uint32_t event_rx_timeout : 1; ///< Signal receive character timeout event
} usart_capabilities_t;
/**
\brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
\param[in] tx usart pin of tx
\param[in] rx usart pin of rx
\param[in] cb_event Pointer to \ref usart_event_cb_t
\param[in] cb_arg argument for cb_event
\return return usart handle if success
*/
usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg);
/**
\brief De-initialize USART Interface. stops operation and releases the software resources used by the interface
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_uninitialize(usart_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle usart handle to operate.
\return \ref usart_capabilities_t
*/
usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle);
/**
\brief config usart mode.
\param[in] handle usart handle to operate.
\param[in] sysclk system clock.
\param[in] baud configured baud .
\param[in] mode \ref usart_mode_e .
\param[in] parity \ref usart_parity_e .
\param[in] stopbits \ref usart_stop_bits_e .
\param[in] bits \ref usart_data_bits_e .
\return error code
*/
int32_t csi_usart_config(usart_handle_t handle,
uint32_t sysclk,
uint32_t baud,
usart_mode_e mode,
usart_parity_e parity,
usart_stop_bits_e stopbits,
usart_data_bits_e bits);
/**
\brief config usart default tx value. used in synchronous mode
\param[in] handle usart handle to operate.
\param[in] value default tx value
\return error code
*/
int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value);
/**
\brief Start sending data to USART transmitter,(received data is ignored).
This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens.
\ref csi_usart_get_status can indicates operation status.
\param[in] handle usart handle to operate.
\param[in] data Pointer to buffer with data to send to USART transmitter. data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[in] num Number of data items to send
\return error code
*/
int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num/*,bool asynch*/);
/**
\brief Abort Send data to USART transmitter
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_send(usart_handle_t handle);
/**
\brief Start receiving data from USART receiver.transmits the default value as specified by csi_usart_set_default_tx_value. \n
This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens.
\ref csi_usart_get_status can indicates operation status.
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from USART receiver.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[in] num Number of data items to receive
\return error code
*/
int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num/*,bool asynch*/);
/**
\brief query data from UART receiver FIFO.
\param[in] handle usart handle to operate.
\param[out] data Pointer to buffer for data to receive from UART receiver
\param[in] num Number of data items to receive
\return receive fifo data num
*/
int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num/*,bool asynch*/);
/**
\brief Abort Receive data from USART receiver
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_receive(usart_handle_t handle);
/**
\brief Start synchronously sends data to the USART transmitter and receives data from the USART receiver. used in synchronous mode
This function is non-blocking,\ref usart_event_e is signaled when operation completes or error happens.
\ref csi_usart_get_status can indicates operation status.
\param[in] handle usart handle to operate.
\param[in] data_out Pointer to buffer with data to send to USART transmitter.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[out] data_in Pointer to buffer for data to receive from USART receiver.data_type is : uint8_t for 5..8 data bits, uint16_t for 9 data bits
\param[in] num Number of data items to transfer
\return error code
*/
int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num/*,bool asynch*/);
/**
\brief abort sending/receiving data to/from USART transmitter/receiver.
\param[in] handle usart handle to operate.
\return error code
*/
int32_t csi_usart_abort_transfer(usart_handle_t handle);
/**
\brief Get USART status.
\param[in] handle usart handle to operate.
\return USART status \ref usart_status_t
*/
usart_status_t csi_usart_get_status(usart_handle_t handle);
/**
\brief flush receive/send data.
\param[in] handle usart handle to operate.
\param[in] type \ref usart_flush_type_e .
\return error code
*/
int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type);
//add function
int32_t dw_usart_getchar(usart_handle_t handle, uint8_t *ch);
int32_t dw_usart_getchar_no_poll(usart_handle_t handle, uint8_t *ch);
int32_t dw_usart_putchar(usart_handle_t handle, uint8_t ch);
int32_t dw_usart_set_int_flag(usart_handle_t handle,uint32_t flag);
int32_t dw_usart_clr_int_flag(usart_handle_t handle,uint32_t flag);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_USART_H_ */

View File

@ -0,0 +1,119 @@
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv_wdt.h
* @brief header file for wdt driver
* @version V1.0
* @date 02. June 2017
******************************************************************************/
#ifndef _CSI_WDT_H_
#define _CSI_WDT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <drv_common.h>
/// definition for wdt handle.
typedef void *wdt_handle_t;
/****** WDT Event *****/
typedef enum {
WDT_EVENT_TIMEOUT = 0 ///< generate the interrupt
} wdt_event_e;
typedef void (*wdt_event_cb_t)(wdt_event_e event); ///< Pointer to \ref wdt_event_cb_t : WDT Event call back.
/**
\brief WDT Device Driver Capabilities.
*/
typedef struct {
uint32_t interrupt : 1; ///< supports interrupt
} wdt_capabilities_t;
/**
\brief get wdt instance count.
\return wdt instance count
*/
int32_t csi_wdt_get_instance_count(void);
/**
\brief Initialize WDT Interface. 1. Initializes the resources needed for the WDT interface 2.registers event callback function
\param[in] idx must not exceed return value of csi_wdt_get_instance_count()
\param[in] cb_event Pointer to \ref wdt_event_cb_t
\return pointer to wdt instance
*/
wdt_handle_t csi_wdt_initialize(int32_t idx, wdt_event_cb_t cb_event);
/**
\brief De-initialize WDT Interface. stops operation and releases the software resources used by the interface
\param[in] handle wdt handle to operate.
\return error code
*/
int32_t csi_wdt_uninitialize(wdt_handle_t handle);
/**
\brief Get driver capabilities.
\param[in] handle wdt handle to operate.
\return \ref wdt_capabilities_t
*/
wdt_capabilities_t csi_wdt_get_capabilities(wdt_handle_t handle);
/**
\brief Set the WDT value.
\param[in] handle wdt handle to operate.
\param[in] value the timeout value(ms).
\return error code
*/
int32_t csi_wdt_set_timeout(wdt_handle_t handle, uint32_t value);
/**
\brief Start the WDT.
\param[in] handle wdt handle to operate.
\return error code
*/
int32_t csi_wdt_start(wdt_handle_t handle);
/**
\brief Stop the WDT.
\param[in] handle wdt handle to operate.
\return error code
*/
int32_t csi_wdt_stop(wdt_handle_t handle);
/**
\brief Restart the WDT.
\param[in] handle wdt handle to operate.
\return error code
*/
int32_t csi_wdt_restart(wdt_handle_t handle);
/**
\brief Read the WDT Current value.
\param[in] handle wdt handle to operate.
\param[in] value Pointer to the Value.
\return error code
*/
int32_t csi_wdt_read_current_value(wdt_handle_t handle, uint32_t *value);
#ifdef __cplusplus
}
#endif
#endif /* _CSI_WDT_H_ */

View File

@ -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

252
bsp/ck802/project.cdkproj Normal file
View File

@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project Name="rt-thread" Version="1">
<Dependencies Name="Debug"/>
<Description/>
<Dependencies Name="BuildSet"/>
<BuildConfigs>
<BuildConfig Name="BuildSet">
<Target>
<ROMBank Selected="1">
<ROM1>
<InUse>yes</InUse>
<Start>0x10000000</Start>
<Size>0x40000</Size>
</ROM1>
<ROM2>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM2>
<ROM3>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM3>
<ROM4>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM4>
<ROM5>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM5>
</ROMBank>
<RAMBank>
<RAM1>
<InUse>yes</InUse>
<Start>0x20000000</Start>
<Size>0x18000</Size>
<Init>yes</Init>
</RAM1>
<RAM2>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM2>
<RAM3>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM3>
<RAM4>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM4>
<RAM5>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM5>
</RAMBank>
<CPU>ck802</CPU>
<UseMiniLib>yes</UseMiniLib>
<Endian>little</Endian>
<UseHardFloat>no</UseHardFloat>
<UseEnhancedLRW>no</UseEnhancedLRW>
</Target>
<Output>
<OutputName>$(ProjectName)</OutputName>
<Type>Executable</Type>
<CreateHexFile>yes</CreateHexFile>
<Preprocessor>yes</Preprocessor>
<Disasm>yes</Disasm>
<CallGraph>yes</CallGraph>
<Map>yes</Map>
</Output>
<User>
<BeforeCompile>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeCompile>
<BeforeMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeMake>
<AfterMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</AfterMake>
</User>
<Compiler>
<Define>RT_USING_MINILIBC</Define>
<Undefine/>
<Optim>None (-O0)</Optim>
<DebugLevel>Maximum (-g3)</DebugLevel>
<IncludePath>applications;.;drivers;libraries\include;libraries\common\aes;libraries\common\aes;libraries\common\crc;libraries\common\dmac;libraries\common\eflash;libraries\common\gpio;libraries\common\iic;libraries\common\pwm;libraries\common\rsa;libraries\common\rtc;libraries\common\sha;libraries\common\spi;libraries\common\timer;libraries\common\trng;libraries\common\usart;libraries\common\wdt;..\..\include;..\..\libcpu\c-sky\ck802;..\..\libcpu\c-sky\common;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh;..\..\components\libc\compilers\minilibc</IncludePath>
<OtherFlags> -c -mistack -ffunction-sections</OtherFlags>
<Verbose>no</Verbose>
<Ansi>no</Ansi>
<Syntax>no</Syntax>
<Pedantic>no</Pedantic>
<PedanticErr>no</PedanticErr>
<InhibitWarn>no</InhibitWarn>
<AllWarn>yes</AllWarn>
<WarnErr>no</WarnErr>
<OneElfS>no</OneElfS>
<Fstrict>no</Fstrict>
</Compiler>
<Asm>
<Define>CONFIG_CKCPU_MMU=0</Define>
<Undefine/>
<IncludePath>applications;.;drivers;libraries\include;libraries\common\aes;libraries\common\aes;libraries\common\crc;libraries\common\dmac;libraries\common\eflash;libraries\common\gpio;libraries\common\iic;libraries\common\pwm;libraries\common\rsa;libraries\common\rtc;libraries\common\sha;libraries\common\spi;libraries\common\timer;libraries\common\trng;libraries\common\usart;libraries\common\wdt;..\..\include;..\..\libcpu\c-sky\ck802;..\..\libcpu\c-sky\common;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh;..\..\components\libc\compilers\minilibc</IncludePath>
<OtherFlags/>
<DebugLevel>gdwarf2</DebugLevel>
</Asm>
<Linker>
<Garbage>yes</Garbage>
<LDFile>$(ProjectPath)\gcc_csky.ld</LDFile>
<LibName/>
<LibPath/>
<OtherFlags/>
<AutoLDFile>no</AutoLDFile>
</Linker>
<Debug>
<LoadApplicationAtStartup>yes</LoadApplicationAtStartup>
<Connector>ICE</Connector>
<StopAt>yes</StopAt>
<StopAtText>main</StopAtText>
<InitFile/>
<AutoRun>no</AutoRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>0</SoftResetVal>
<ResetAfterLoad>no</ResetAfterLoad>
<ConfigICE>
<IP>localhost</IP>
<PORT>1025</PORT>
<Clock>12000</Clock>
<Delay>10</Delay>
<DDC>yes</DDC>
<TRST>no</TRST>
<Connect>Normal</Connect>
<ResetType>Soft Reset</ResetType>
<SoftResetVal>0</SoftResetVal>
<RTOSType>Bare Metal</RTOSType>
<DownloadToFlash>no</DownloadToFlash>
<ResetAfterConnect>yes</ResetAfterConnect>
</ConfigICE>
<ConfigSIM>
<SIMTarget>soccfg/cskyv2/smart_v3_802_cfg.xml</SIMTarget>
<OtherFlags/>
<NoGraphic>no</NoGraphic>
<Log>yes</Log>
</ConfigSIM>
</Debug>
<Flash>
<InitFile/>
<Erase>Erase Sectors</Erase>
<Algorithms Path=""/>
<Program>yes</Program>
<Verify>no</Verify>
<ResetAndRun>no</ResetAndRun>
</Flash>
</BuildConfig>
</BuildConfigs>
<VirtualDirectory Name="Applications">
<File Name="applications/main.c"/>
</VirtualDirectory>
<VirtualDirectory Name="Drivers">
<File Name="drivers/board.c"/>
<File Name="drivers/board_coretimer.c"/>
<File Name="drivers/board_uart.c"/>
<File Name="drivers/isr.c"/>
<File Name="drivers/pinmux.c"/>
<File Name="drivers/system.c"/>
</VirtualDirectory>
<VirtualDirectory Name="libraries">
<File Name="libraries/startup_gcc.S"/>
<File Name="libraries/common/aes/ck_aes.c"/>
<File Name="libraries/common/crc/ck_crc.c"/>
<File Name="libraries/common/dmac/ck_dmac.c"/>
<File Name="libraries/common/eflash/ck_eflash.c"/>
<File Name="libraries/common/pwm/ck_pwm.c"/>
<File Name="libraries/common/rsa/ck_rsa.c"/>
<File Name="libraries/common/sha/ck_sha.c"/>
<File Name="libraries/common/trng/ck_trng.c"/>
<File Name="libraries/common/timer/dw_timer.c"/>
<File Name="libraries/common/gpio/dw_gpio.c"/>
<File Name="libraries/common/spi/dw_spi.c"/>
<File Name="libraries/common/iic/dw_iic.c"/>
<File Name="libraries/common/usart/dw_usart.c"/>
<File Name="libraries/common/wdt/dw_wdt.c"/>
</VirtualDirectory>
<VirtualDirectory Name="Kernel">
<File Name="../../src/clock.c"/>
<File Name="../../src/components.c"/>
<File Name="../../src/device.c"/>
<File Name="../../src/idle.c"/>
<File Name="../../src/ipc.c"/>
<File Name="../../src/irq.c"/>
<File Name="../../src/kservice.c"/>
<File Name="../../src/mem.c"/>
<File Name="../../src/mempool.c"/>
<File Name="../../src/object.c"/>
<File Name="../../src/scheduler.c"/>
<File Name="../../src/signal.c"/>
<File Name="../../src/thread.c"/>
<File Name="../../src/timer.c"/>
</VirtualDirectory>
<VirtualDirectory Name="CK802">
<File Name="../../libcpu/c-sky/ck802/core_ck802.c"/>
<File Name="../../libcpu/c-sky/ck802/stack_ck802.c"/>
<File Name="../../libcpu/c-sky/ck802/contex_ck802_gcc.S"/>
</VirtualDirectory>
<VirtualDirectory Name="DeviceDrivers">
<File Name="../../components/drivers/misc/pin.c"/>
<File Name="../../components/drivers/serial/serial.c"/>
<File Name="../../components/drivers/src/completion.c"/>
<File Name="../../components/drivers/src/dataqueue.c"/>
<File Name="../../components/drivers/src/pipe.c"/>
<File Name="../../components/drivers/src/ringbuffer.c"/>
<File Name="../../components/drivers/src/waitqueue.c"/>
<File Name="../../components/drivers/src/workqueue.c"/>
</VirtualDirectory>
<VirtualDirectory Name="finsh">
<File Name="../../components/finsh/shell.c"/>
<File Name="../../components/finsh/symbol.c"/>
<File Name="../../components/finsh/cmd.c"/>
<File Name="../../components/finsh/msh.c"/>
<File Name="../../components/finsh/msh_cmd.c"/>
<File Name="../../components/finsh/msh_file.c"/>
</VirtualDirectory>
<VirtualDirectory Name="libc">
<File Name="../../components/libc/compilers/minilibc/ctype.c"/>
<File Name="../../components/libc/compilers/minilibc/math.c"/>
<File Name="../../components/libc/compilers/minilibc/qsort.c"/>
<File Name="../../components/libc/compilers/minilibc/rand.c"/>
<File Name="../../components/libc/compilers/minilibc/stdlib.c"/>
<File Name="../../components/libc/compilers/minilibc/string.c"/>
<File Name="../../components/libc/compilers/minilibc/time.c"/>
</VirtualDirectory>
<DebugSessions>
<watchExpressions/>
<memoryExpressions>;;;</memoryExpressions>
<statistics>;;MHZ</statistics>
</DebugSessions>
</Project>

145
bsp/ck802/rtconfig.h Normal file
View File

@ -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

63
bsp/ck802/rtconfig.py Normal file
View File

@ -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'

176
bsp/ck802/template.cdkproj Normal file
View File

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project Name="rt-thread" Version="1">
<Dependencies Name="Debug"/>
<Description/>
<Dependencies Name="BuildSet"/>
<BuildConfigs>
<BuildConfig Name="BuildSet">
<Target>
<ROMBank Selected="1">
<ROM1>
<InUse>yes</InUse>
<Start>0x10000000</Start>
<Size>0x40000</Size>
</ROM1>
<ROM2>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM2>
<ROM3>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM3>
<ROM4>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM4>
<ROM5>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM5>
</ROMBank>
<RAMBank>
<RAM1>
<InUse>yes</InUse>
<Start>0x20000000</Start>
<Size>0x18000</Size>
<Init>yes</Init>
</RAM1>
<RAM2>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM2>
<RAM3>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM3>
<RAM4>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM4>
<RAM5>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM5>
</RAMBank>
<CPU>ck802</CPU>
<UseMiniLib>yes</UseMiniLib>
<Endian>little</Endian>
<UseHardFloat>no</UseHardFloat>
<UseEnhancedLRW>no</UseEnhancedLRW>
</Target>
<Output>
<OutputName>$(ProjectName)</OutputName>
<Type>Executable</Type>
<CreateHexFile>yes</CreateHexFile>
<Preprocessor>yes</Preprocessor>
<Disasm>yes</Disasm>
<CallGraph>yes</CallGraph>
<Map>yes</Map>
</Output>
<User>
<BeforeCompile>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeCompile>
<BeforeMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeMake>
<AfterMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</AfterMake>
</User>
<Compiler>
<Define/>
<Undefine/>
<Optim>None (-O0)</Optim>
<DebugLevel>Maximum (-g3)</DebugLevel>
<IncludePath/>
<OtherFlags></OtherFlags>
<Verbose>no</Verbose>
<Ansi>no</Ansi>
<Syntax>no</Syntax>
<Pedantic>no</Pedantic>
<PedanticErr>no</PedanticErr>
<InhibitWarn>no</InhibitWarn>
<AllWarn>yes</AllWarn>
<WarnErr>no</WarnErr>
<OneElfS>no</OneElfS>
<Fstrict>no</Fstrict>
</Compiler>
<Asm>
<Define>CONFIG_CKCPU_MMU=0</Define>
<Undefine/>
<IncludePath></IncludePath>
<OtherFlags/>
<DebugLevel>gdwarf2</DebugLevel>
</Asm>
<Linker>
<Garbage>yes</Garbage>
<LDFile>$(ProjectPath)\gcc_csky.ld</LDFile>
<LibName/>
<LibPath/>
<OtherFlags/>
<AutoLDFile>no</AutoLDFile>
</Linker>
<Debug>
<LoadApplicationAtStartup>yes</LoadApplicationAtStartup>
<Connector>ICE</Connector>
<StopAt>yes</StopAt>
<StopAtText>main</StopAtText>
<InitFile/>
<AutoRun>no</AutoRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>0</SoftResetVal>
<ResetAfterLoad>no</ResetAfterLoad>
<ConfigICE>
<IP>localhost</IP>
<PORT>1025</PORT>
<Clock>12000</Clock>
<Delay>10</Delay>
<DDC>yes</DDC>
<TRST>no</TRST>
<Connect>Normal</Connect>
<ResetType>Soft Reset</ResetType>
<SoftResetVal>0</SoftResetVal>
<RTOSType>Bare Metal</RTOSType>
<DownloadToFlash>no</DownloadToFlash>
<ResetAfterConnect>yes</ResetAfterConnect>
</ConfigICE>
<ConfigSIM>
<SIMTarget>soccfg/cskyv2/smart_v3_802_cfg.xml</SIMTarget>
<OtherFlags/>
<NoGraphic>no</NoGraphic>
<Log>yes</Log>
</ConfigSIM>
</Debug>
<Flash>
<InitFile/>
<Erase>Erase Sectors</Erase>
<Algorithms Path=""/>
<Program>yes</Program>
<Verify>no</Verify>
<ResetAndRun>no</ResetAndRun>
</Flash>
</BuildConfig>
</BuildConfigs>
<DebugSessions>
<watchExpressions/>
<memoryExpressions>;;;</memoryExpressions>
<statistics>;;MHZ</statistics>
</DebugSessions>
</Project>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff