summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--bsp/allwinner_tina/.config265
-rw-r--r--bsp/allwinner_tina/Kconfig29
-rw-r--r--bsp/allwinner_tina/README.md132
-rw-r--r--bsp/allwinner_tina/SConscript14
-rw-r--r--bsp/allwinner_tina/SConstruct27
-rw-r--r--bsp/allwinner_tina/applications/SConscript9
-rw-r--r--bsp/allwinner_tina/applications/main.c36
-rw-r--r--bsp/allwinner_tina/drivers/Kconfig16
-rw-r--r--bsp/allwinner_tina/drivers/SConscript16
-rw-r--r--bsp/allwinner_tina/drivers/board.c117
-rw-r--r--bsp/allwinner_tina/drivers/board.h38
-rw-r--r--bsp/allwinner_tina/drivers/drv_clock.c527
-rw-r--r--bsp/allwinner_tina/drivers/drv_clock.h252
-rw-r--r--bsp/allwinner_tina/drivers/drv_gpio.c564
-rw-r--r--bsp/allwinner_tina/drivers/drv_gpio.h244
-rw-r--r--bsp/allwinner_tina/drivers/drv_uart.c324
-rw-r--r--bsp/allwinner_tina/drivers/drv_uart.h83
-rw-r--r--bsp/allwinner_tina/libcpu/SConscript13
-rw-r--r--bsp/allwinner_tina/libcpu/context_gcc.S92
-rw-r--r--bsp/allwinner_tina/libcpu/cpu.c41
-rw-r--r--bsp/allwinner_tina/libcpu/cpuport.c229
-rw-r--r--bsp/allwinner_tina/libcpu/interrupt.c206
-rw-r--r--bsp/allwinner_tina/libcpu/interrupt.h107
-rw-r--r--bsp/allwinner_tina/libcpu/mmu.c457
-rw-r--r--bsp/allwinner_tina/libcpu/mmu.h65
-rw-r--r--bsp/allwinner_tina/libcpu/rt_low_level_init.c81
-rw-r--r--bsp/allwinner_tina/libcpu/stack.c81
-rw-r--r--bsp/allwinner_tina/libcpu/start_gcc.S346
-rw-r--r--bsp/allwinner_tina/libcpu/trap.c223
-rw-r--r--bsp/allwinner_tina/link.lds148
-rw-r--r--bsp/allwinner_tina/rtconfig.h235
-rw-r--r--bsp/allwinner_tina/rtconfig.py58
33 files changed, 5076 insertions, 0 deletions
diff --git a/.travis.yml b/.travis.yml
index d7589e23ad..fbcb1241f3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -27,6 +27,7 @@ env:
# - RTT_BSP='apollo2' RTT_TOOL_CHAIN='sourcery-arm'
- RTT_BSP='asm9260t' RTT_TOOL_CHAIN='sourcery-arm'
- RTT_BSP='at91sam9260' RTT_TOOL_CHAIN='sourcery-arm'
+ - RTT_BSP='allwinner_tina' RTT_TOOL_CHAIN='sourcery-arm'
# - RTT_BSP='avr32uc3b0' RTT_TOOL_CHAIN='atmel-avr32'
# - RTT_BSP='bf533' # no scons
- RTT_BSP='efm32' RTT_TOOL_CHAIN='sourcery-arm'
diff --git a/bsp/allwinner_tina/.config b/bsp/allwinner_tina/.config
new file mode 100644
index 0000000000..0d06a6d220
--- /dev/null
+++ b/bsp/allwinner_tina/.config
@@ -0,0 +1,265 @@
+#
+# 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="uart0"
+# CONFIG_RT_USING_MODULE is not set
+CONFIG_ARCH_ARM=y
+CONFIG_ARCH_ARM_ARM9=y
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+
+#
+# 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=5
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
+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 is not set
+
+#
+# Device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=2
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
+CONFIG_DFS_FD_MAX=4
+CONFIG_RT_USING_DFS_ELMFAT=y
+
+#
+# elm-chan's FatFs, Generic FAT Filesystem Module
+#
+CONFIG_RT_DFS_ELM_CODE_PAGE=437
+CONFIG_RT_DFS_ELM_WORD_ACCESS=y
+CONFIG_RT_DFS_ELM_USE_LFN_0=y
+# 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
+CONFIG_RT_DFS_ELM_USE_LFN=0
+CONFIG_RT_DFS_ELM_MAX_LFN=255
+CONFIG_RT_DFS_ELM_DRIVES=2
+CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512
+# CONFIG_RT_DFS_ELM_USE_ERASE is not set
+CONFIG_RT_DFS_ELM_REENTRANT=y
+CONFIG_RT_USING_DFS_DEVFS=y
+# CONFIG_RT_USING_DFS_NET is not set
+# CONFIG_RT_USING_DFS_ROMFS is not set
+# CONFIG_RT_USING_DFS_RAMFS is not set
+# CONFIG_RT_USING_DFS_UFFS is not set
+# CONFIG_RT_USING_DFS_JFFS2 is not set
+# CONFIG_RT_USING_DFS_NFS 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_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
+
+#
+# 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=y
+# CONFIG_RT_USING_PTHREADS is not set
+CONFIG_RT_USING_POSIX=y
+# CONFIG_RT_USING_POSIX_MMAP is not set
+# CONFIG_RT_USING_POSIX_TERMIOS is not set
+# CONFIG_RT_USING_POSIX_AIO 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
+
+#
+# RT-Thread UI Engine
+#
+# CONFIG_RT_USING_GUIENGINE 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
+#
+
+#
+# system packages
+#
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_PERSIMMON is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+
+#
+# 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_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
+
+#
+# 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
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_IPERF is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+
+#
+# example package: hello
+#
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+CONFIG_TINA_USING_UART0=y
+# CONFIG_TINA_USING_UART1 is not set
+CONFIG_TINA_USING_UART2=y
+CONFIG_RT_USING_CPU_FFS=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
diff --git a/bsp/allwinner_tina/Kconfig b/bsp/allwinner_tina/Kconfig
new file mode 100644
index 0000000000..fd1b6f9abd
--- /dev/null
+++ b/bsp/allwinner_tina/Kconfig
@@ -0,0 +1,29 @@
+mainmenu "RT-Thread Configuration"
+
+config $BSP_DIR
+ string
+ option env="BSP_ROOT"
+ default "."
+
+config $RTT_DIR
+ string
+ option env="RTT_ROOT"
+ default "../.."
+
+# you can change the RTT_ROOT default "../.." to your rtthread_root,
+# example : default "F:/git_repositories/rt-thread"
+
+config $PKGS_DIR
+ string
+ option env="PKGS_ROOT"
+ default "packages"
+
+source "$RTT_DIR/KConfig"
+source "$PKGS_DIR/KConfig"
+
+config SOC_TINA
+ bool
+ select ARCH_ARM_ARM9
+ default y
+
+source "$BSP_DIR/drivers/Kconfig"
diff --git a/bsp/allwinner_tina/README.md b/bsp/allwinner_tina/README.md
new file mode 100644
index 0000000000..82616e1f5e
--- /dev/null
+++ b/bsp/allwinner_tina/README.md
@@ -0,0 +1,132 @@
+# Allwinner tina板级支持包
+
+## 1. 简介
+
+Allwinner tina 是由全志公司推出的ARM9内核的SOC
+包括如下硬件特性:
+
+| 硬件 | 描述 |
+| -- | -- |
+|芯片型号| tina系列 |
+|CPU| ARM9 |
+|主频| 408MHz |
+|片内DDR | 32MB |
+|板载SPI Nor Flash | 8/16MB|
+
+## 2. 编译说明
+
+| 环境 | 说明 |
+| --- | --- |
+|PC操作系统|Linux/MacOS|
+|编译器|arm-none-eabi-gcc version 6.3.1 20170620 (release)|
+|构建工具|scons|
+1) 下载源码
+
+```
+ git clone https://github.com/RT-Thread/rt-thread.git
+```
+2) 配置工程并准备env
+```
+ cd rt-thread/bsp/allwinner_tina
+ scons --menuconfig
+ source ~/.env/env.sh
+ pkgs --upgrade
+
+```
+3) 编译安装下载工具
+```
+ pushd /tmp
+ git clone https://github.com/Icenowy/sunxi-tools.git
+ pushd sunxi-tools
+ git checkout -b f1c100s
+ git checkout -b f1c100s origin/f1c100s
+ make
+ sudo make install
+ popd
+ popd
+```
+4) 编译
+```
+ scons
+```
+如果编译正确无误,会产生rtthread.elf、rtthread.bin文件。其中rtthread.bin需要烧写到设备中进行运行。
+
+## 3. 烧写及执行
+**烧写工具目前仅支持Linux/MacOS环境,请在Linux/MaxOS环境下进行烧写操作**
+当正确编译产生出rtthread.bin映像文件后可以使用下面的方式来烧写到设备中。
+
+1)编译初始化引导文件
+编译依赖 arm-eabi-gcc
+```
+ pushd ../../..
+ git clone https://github.com/uestczyh222/tina-spl.git
+ pushd tina-spl
+ make
+ cp output/f1c100s.bin ../rt-thread/bsp/tina/tina-spl.bin
+ popd
+ popd
+```
+2)下载并运行
+
+```
+1.短接flash 1、4脚(当flash中无可引导代码时无需此步骤)
+2.连接USB
+3.松开短接的引脚
+4.输入下列指令
+```
+
+```
+ sudo sunxi-fel -p write 0x00000000 tina-spl.bin
+ sudo sunxi-fel exec 0x00000000
+ sudo sunxi-fel -p write 0x80000000 rtthread.bin
+ sudo sunxi-fel exec 0x80000000
+```
+
+### 3.1 运行结果
+
+如果编译 & 烧写无误,会在串口0上看到RT-Thread的启动logo信息:
+
+```
+ \ | /
+- RT - Thread Operating System
+ / | \ 3.0.2 build Feb 8 2018
+ 2006 - 2017 Copyright by rt-thread team
+periph_get_pll_clk:600000000
+cpu_get_clk:408000000
+ahb_get_clk:200000000
+apb_get_clk:100000000
+msh />
+```
+
+
+## 4. 驱动支持情况及计划
+
+| 驱动 | 支持情况 | 备注 |
+| ------ | :----: | :------: |
+| UART | 支持 | UART0/1/2 |
+| GPIO | 支持 | / |
+| clock | 支持 | / |
+| mmu | 支持 | / |
+
+
+### 4.1 IO在板级支持包中的映射情况
+
+| IO号 | 板级包中的定义 |
+| -- | -- |
+| PE8 | USART2 RX |
+| PE7 | USART2 TX |
+| PA3 | USART1 RX |
+| PA2 | USART1 TX |
+| PE1 | USART0 TX |
+| PE0 | USART0 RX |
+
+
+## 5. 联系人信息
+
+维护人:
+[uestczyh222][4] < [[email protected]][5] >
+
+
+ [1]: https://www.rt-thread.org/page/download.html
+ [4]: https://github.com/uestczyh222
+ [5]: mailto:[email protected]
diff --git a/bsp/allwinner_tina/SConscript b/bsp/allwinner_tina/SConscript
new file mode 100644
index 0000000000..c7ef7659ec
--- /dev/null
+++ b/bsp/allwinner_tina/SConscript
@@ -0,0 +1,14 @@
+# for module compiling
+import os
+from building import *
+
+cwd = GetCurrentDir()
+objs = []
+list = os.listdir(cwd)
+
+for d in list:
+ path = os.path.join(cwd, d)
+ if os.path.isfile(os.path.join(path, 'SConscript')):
+ objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')
diff --git a/bsp/allwinner_tina/SConstruct b/bsp/allwinner_tina/SConstruct
new file mode 100644
index 0000000000..f0c508ba6d
--- /dev/null
+++ b/bsp/allwinner_tina/SConstruct
@@ -0,0 +1,27 @@
+import os
+import sys
+import rtconfig
+
+from rtconfig import RTT_ROOT
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+TARGET = 'rtthread.' + rtconfig.TARGET_EXT
+
+env = Environment(tools = ['mingw'],
+ AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
+ CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
+ CXX = rtconfig.CC, CXXFLAGS = rtconfig.CXXFLAGS,
+ AR = rtconfig.AR, ARFLAGS = '-rc',
+ LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True)
+
+# make a building
+DoBuilding(TARGET, objs)
diff --git a/bsp/allwinner_tina/applications/SConscript b/bsp/allwinner_tina/applications/SConscript
new file mode 100644
index 0000000000..e1255c80c8
--- /dev/null
+++ b/bsp/allwinner_tina/applications/SConscript
@@ -0,0 +1,9 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+CPPPATH = [cwd, str(Dir('#'))]
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/bsp/allwinner_tina/applications/main.c b/bsp/allwinner_tina/applications/main.c
new file mode 100644
index 0000000000..7aaf1f8db3
--- /dev/null
+++ b/bsp/allwinner_tina/applications/main.c
@@ -0,0 +1,36 @@
+/*
+ * File : main.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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-5-30 Bernard the first version
+ */
+
+#include "rtthread.h"
+#include "drv_clock.h"
+
+int main(int argc, char **argv)
+{
+ rt_kprintf("periph_get_pll_clk:%d\n", periph_get_pll_clk());
+ rt_kprintf("cpu_get_clk:%d\n", cpu_get_clk());
+ rt_kprintf("ahb_get_clk:%d\n", ahb_get_clk());
+ rt_kprintf("apb_get_clk:%d\n", apb_get_clk());
+
+ return 0;
+}
diff --git a/bsp/allwinner_tina/drivers/Kconfig b/bsp/allwinner_tina/drivers/Kconfig
new file mode 100644
index 0000000000..b7efb5de20
--- /dev/null
+++ b/bsp/allwinner_tina/drivers/Kconfig
@@ -0,0 +1,16 @@
+
+
+config TINA_USING_UART0
+ bool "Using UART0"
+ select RT_USING_SERIAL
+ default n
+
+config TINA_USING_UART1
+ bool "Using UART1"
+ select RT_USING_SERIAL
+ default y
+
+config TINA_USING_UART2
+ bool "Using UART2"
+ select RT_USING_SERIAL
+ default y
diff --git a/bsp/allwinner_tina/drivers/SConscript b/bsp/allwinner_tina/drivers/SConscript
new file mode 100644
index 0000000000..d42736afe6
--- /dev/null
+++ b/bsp/allwinner_tina/drivers/SConscript
@@ -0,0 +1,16 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+list = os.listdir(cwd)
+CPPPATH = [cwd]
+objs = []
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+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'))
+objs = objs + group
+Return('objs')
diff --git a/bsp/allwinner_tina/drivers/board.c b/bsp/allwinner_tina/drivers/board.c
new file mode 100644
index 0000000000..e3b54b3536
--- /dev/null
+++ b/bsp/allwinner_tina/drivers/board.c
@@ -0,0 +1,117 @@
+/*
+ * File : board.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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-5-30 Bernard the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "board.h"
+#include "drv_uart.h"
+#include "interrupt.h"
+#include "mmu.h"
+
+static void os_clock_irq_handle(int irqno, void *param)
+{
+ volatile rt_uint32_t *temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x04);
+
+ /* clear timer */
+ *temp_addr |= 0x01;
+
+ rt_tick_increase();
+}
+
+static void mmu_init(void)
+{
+ struct mem_desc r6_mem_desc[] =
+ {
+ { 0x00000000, 0xFFFFFFFF, 0x00000000, RW_NCNB }, /* None cached for 4G memory */
+ { 0x80000000, 0x82000000 - 1, 0x80000000, RW_CB }, /* 32M cached SDRAM memory */
+ //{ 0x00000000, 0x00001000-1, 0x80000000, RW_CB }, /* isr vector table */
+ //here not set mmu
+ //start_gcc.S Copy vector to the correct address
+ };
+
+ rt_hw_mmu_init(r6_mem_desc, sizeof(r6_mem_desc) / sizeof(r6_mem_desc[0]));
+}
+
+static void os_clock_init(void)
+{
+ rt_uint32_t temp;
+ volatile rt_uint32_t *temp_addr;
+
+ /* reload value */
+ temp = 0xB71B00 / RT_TICK_PER_SECOND;
+ temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x14);
+ *temp_addr = temp;
+
+ /* continuous | /2 | 24Mhz | reload*/
+ temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1);
+ temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x10);
+ *temp_addr &= 0xffffff00;
+ *temp_addr |= temp;
+
+ /* open timer irq */
+ temp = 0x01 << 0;
+ temp_addr = (rt_uint32_t *)(0x01C20C00);
+ *temp_addr |= temp;
+
+ /* set init value */
+ temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x18);
+ *temp_addr = 0;
+
+ /* begin run timer */
+ temp = 0x01 << 0;
+ temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x10);
+ *temp_addr |= temp;
+
+ temp_addr = (rt_uint32_t *)(0x01C20C00);
+ /* set irq handle */
+ rt_hw_interrupt_install(TIMER0_INTERRUPT, os_clock_irq_handle, (void *)temp_addr, "timer");
+ rt_hw_interrupt_umask(TIMER0_INTERRUPT);
+
+}
+
+void rt_hw_board_init(void)
+{
+ mmu_init();
+
+ rt_hw_interrupt_init();
+
+#ifdef RT_USING_HEAP
+ /* init memory system */
+ rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
+#endif
+ /* init hardware interrupt */
+ rt_hw_uart_init();
+
+#ifdef RT_USING_CONSOLE
+ /* set console device */
+ rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+#endif /* RT_USING_CONSOLE */
+
+ os_clock_init();
+
+#ifdef RT_USING_COMPONENTS_INIT
+ rt_components_board_init();
+#endif
+}
diff --git a/bsp/allwinner_tina/drivers/board.h b/bsp/allwinner_tina/drivers/board.h
new file mode 100644
index 0000000000..11c6a9a15f
--- /dev/null
+++ b/bsp/allwinner_tina/drivers/board.h
@@ -0,0 +1,38 @@
+/*
+ * File : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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-5-30 Bernard the first version
+ */
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#include <stdint.h>
+
+extern unsigned char __bss_start;
+extern unsigned char __bss_end;
+
+#define RT_HW_HEAP_BEGIN (void*)&__bss_end
+#define RT_HW_HEAP_END (void*)(0x80000000 + 32 * 1024 * 1024)
+
+void rt_hw_board_init(void);
+
+#endif
diff --git a/bsp/allwinner_tina/drivers/drv_clock.c b/bsp/allwinner_tina/drivers/drv_clock.c
new file mode 100644
index 0000000000..8c8431b913
--- /dev/null
+++ b/bsp/allwinner_tina/drivers/drv_clock.c
@@ -0,0 +1,527 @@
+/*
+ * File : drv_clock.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "drv_clock.h"
+
+int cpu_get_pll_clk(void)
+{
+ rt_uint32_t reg;
+ int n, k, m, p;
+
+ reg = CCU->pll_cpu_ctrl;
+ if (!(reg & (0x01 << 31)))
+ return 0;
+
+ p = PLL_CPU_DIV_P(reg) + 1;
+ n = PLL_CPU_FACTOR_N(reg) + 1;
+ k = PLL_CPU_FACTOR_K(reg) + 1;
+ m = PLL_CPU_FACTOR_M(reg) + 1;
+ //(24MHz*n*k)/(m*p)
+ return (_24MHZ_ * n * k) / (m * p);
+}
+
+int audio_get_pll_clk(void)
+{
+ rt_uint32_t reg;
+ unsigned char n, m;
+
+ reg = CCU->pll_audio_ctrl;
+ if (!(reg & (0x01 << 31)))
+ return 0;
+
+ n = PLL_AUDIO_FACTOR_N(reg) + 1;
+ m = PLL_AUDIO_PREDIV_M(reg) + 1;
+
+ //24MHz*n*2/m
+ return _24MHZ_ * 2 * n / m;
+}
+
+int video_get_pll_clk(void)
+{
+ rt_uint32_t reg;
+ int n, m;
+
+ reg = CCU->pll_video_ctrl;
+ if (!(reg & (0x01 << 31)))
+ return 0;
+
+ if (reg & PLL_VIDEO_MODE_SEL)
+ {
+ //(24MHz*n)/m
+ n = PLL_VIDEO_FACTOR_N(reg) + 1;
+ m = PLL_VIDEO_PREDIV_M(reg) + 1;
+ return (_24MHZ_ * n) / m;
+ }
+
+ if (reg & PLL_VIDEO_FRAC_CLK_OUT)
+ return 270000000;
+ else
+ return 297000000;
+
+ return 0;
+}
+
+int ve_get_pll_clk(void)
+{
+ rt_uint32_t reg;
+ int n, m;
+
+ reg = CCU->pll_ve_ctrl;
+ if (!(reg & (0x01 << 31)))
+ return 0;
+
+ if (reg & PLL_VE_MODE_SEL)
+ {
+ //(24MHz*n)/m
+ n = PLL_VE_FACTOR_N(reg) + 1;
+ m = PLL_VE_PREDIV_M(reg) + 1;
+
+ return (_24MHZ_ * n) / m;
+ }
+
+ if (reg & PLL_VE_FRAC_CLK_OUT)
+ return 297000000;
+ else
+ return 270000000;
+
+ return 0;
+}
+
+int ddr_get_pll_clk(void)
+{
+ rt_uint32_t reg;
+ int n, k, m;
+
+ reg = CCU->pll_ddr_ctrl;
+ if (!(reg & (0x01 << 31)))
+ return 0;
+
+ n = PLL_DDR_FACTOR_N(reg) + 1;
+ k = PLL_DDR_FACTOR_K(reg) + 1;
+ m = PLL_DDR_FACTOR_M(reg) + 1;
+
+ //(24MHz*n*k)/m
+ return (_24MHZ_ * n * k) / m;
+}
+
+int periph_get_pll_clk(void)
+{
+ rt_uint32_t reg;
+ int n, k;
+
+ reg = CCU->pll_periph_ctrl;
+ if (!(reg & (0x01 << 31)))
+ return 0;
+
+ n = PLL_PERIPH_FACTOR_N(reg) + 1;
+ k = PLL_PERIPH_FACTOR_K(reg) + 1;
+
+ return _24MHZ_ * n * k;
+}
+
+static int cpu_get_clk_src(void)
+{
+ return (CCU->cpu_clk_src >> 16) & 0x3;
+}
+
+int cpu_get_clk(void)
+{
+ rt_uint32_t reg;
+ int cpusrc;
+
+ reg = CCU->ahb_apb_hclkc_cfg;
+ cpusrc = cpu_get_clk_src();
+
+ if (cpusrc == CLK_PLL_SRC)
+ return (cpu_get_pll_clk() / (HCLKC_DIV(reg) + 1));
+ else if (cpusrc == CLK_OSC24M_SRC)
+ return _24MHZ_ / (HCLKC_DIV(reg) + 1);
+ else
+ return _32KHZ_ / (HCLKC_DIV(reg) + 1); //猜测 内部32KHz时钟
+
+ return 0;
+}
+
+int ahb_get_clk(void)
+{
+ rt_uint32_t reg;
+ int sel, spd;
+
+ reg = CCU->ahb_apb_hclkc_cfg;
+ sel = AHB_SRC_SEL(reg);
+
+ if (sel == CLK_PLL_SRC)
+ {
+ spd = cpu_get_clk();
+ return spd / (1 << AHB_CLK_DIV(reg));
+ }
+ else if (sel == PRE_DIV_SRC)
+ {
+ spd = periph_get_pll_clk();
+ return spd / (AHB_PRE_DIV(reg) + 1) / (1 << AHB_CLK_DIV(reg));
+ }
+ else if (sel == CLK_OSC24M_SRC)
+ return _24MHZ_ / (1 << AHB_CLK_DIV(reg));
+ else
+ return _32KHZ_ / (1 << AHB_CLK_DIV(reg));
+}
+
+int apb_get_clk(void)
+{
+ rt_uint32_t reg;
+ int spd;
+
+ reg = CCU->ahb_apb_hclkc_cfg;
+ spd = ahb_get_clk();
+ // 0x:/2 10:/4 11:/8
+ if (!(APH_CLK_PATIO(reg) & 0x1))
+ return spd / 2;
+ else
+ return spd / (1 << APH_CLK_PATIO(reg));
+}
+
+
+static rt_err_t wait_pll_stable(rt_uint32_t base)
+{
+ rt_uint32_t rval = 0;
+ volatile int time = 0xfff;
+
+ do
+ {
+ rval = *((volatile rt_uint32_t *)base);
+ time--;
+ }
+ while (time && !(rval & (1 << 28)));
+
+ return !time;
+}
+
+rt_err_t cpu_set_pll_clk(int clk)
+{
+ rt_uint32_t cpu_src;
+ int p = 0, k = 1, m = 1, n = 0;
+
+ if (clk == 0)
+ return RT_EINVAL;
+
+ if (clk > 1152000000)
+ {
+ k = 2;
+ }
+ else if (clk > 768000000)
+ {
+ k = 3;
+ m = 2;
+ }
+
+ n = clk / (_24MHZ_ * k / m) - 1;
+ cpu_src = (CCU->cpu_clk_src >> 16) & 0x3;
+ CCU->cpu_clk_src = CLK_OSC24M_SRC << 16;
+ CCU->pll_cpu_ctrl &= ~(0x1 << 31);
+ //PLL1 rate = ((24000000 * n * k) >> 0) / m (p is ignored)
+ CCU->pll_cpu_ctrl = (0x1 << 31) | (m << 0) | (k << 4) | (n << 8) | (p << 16);
+ if (wait_pll_stable((rt_uint32_t)(&CCU->pll_cpu_ctrl)))
+ return RT_ERROR;
+
+ CCU->cpu_clk_src = cpu_src << 16;
+
+ return RT_EOK;
+}
+
+rt_err_t audio_set_pll_clk(int clk)
+{
+ int n = 0, m = 0;
+ int n_temp = clk;
+ int m_temp = _24MHZ_ * 2;
+
+ if ((clk > 200000000) || (clk < 20000000))
+ return RT_EINVAL;
+
+ if (clk == 0)
+ {
+ CCU->pll_audio_ctrl &= ~(0x1 << 31);
+ return RT_EOK;
+ }
+
+ while (n_temp != m_temp)
+ {
+ if (n_temp > m_temp)
+ {
+ n_temp = n_temp - m_temp;
+ }
+ else if (m_temp > n_temp)
+ {
+ m_temp = m_temp - n_temp;
+ }
+ }
+
+ n = clk / n_temp;
+ m = _24MHZ_ * 2 / m_temp;
+ if ((n > 128) || (m > 32) || (clk != (_24MHZ_ * n * 2) / m))
+ return RT_ERROR;
+
+ CCU->pll_audio_ctrl &= ~(0x1 << 31);
+ n = (n - 1) & 0x7f;
+ m = (m - 1) & 0x1f;
+ //clk = (24 * n * 2) / m
+ CCU->pll_audio_ctrl = (0x1 << 31) | (0x0 << 24) | (n << 8) | m;
+
+ if (wait_pll_stable((rt_uint32_t)(&CCU->pll_audio_ctrl)))
+ return RT_ERROR;
+ else
+ return RT_EOK;
+}
+
+rt_err_t video_set_pll_clk(int clk)
+{
+ int n = 0, m = 0;
+ int n_temp = clk;
+ int m_temp = _24MHZ_;
+
+ if ((clk > 600000000) || (clk < 30000000))
+ return RT_EINVAL;
+
+ if (clk == 0)
+ {
+ CCU->pll_video_ctrl &= ~(0x1 << 31);
+ return RT_EOK;
+ }
+
+ while (n_temp != m_temp)
+ {
+ if (n_temp > m_temp)
+ {
+ n_temp = n_temp - m_temp;
+ }
+ else if (m_temp > n_temp)
+ {
+ m_temp = m_temp - n_temp;
+ }
+ }
+
+ n = clk / n_temp;
+ m = _24MHZ_ / m_temp;
+
+ if ((n > 128) || (m > 16) || (clk != (_24MHZ_ * n) / m))
+ return RT_ERROR;
+
+ CCU->pll_video_ctrl &= ~(0x1 << 31);
+ n = (n - 1) & 0x7f;
+ m = (m - 1) & 0xf;
+ //speed = (24*n)/m
+ CCU->pll_video_ctrl = (0x1 << 31) | (0x0 << 30) | (0x1 << 24) | (n << 8) | m;
+
+ if (wait_pll_stable((rt_uint32_t)(&CCU->pll_video_ctrl)))
+ return RT_ERROR;
+ else
+ return RT_EOK;
+}
+
+rt_err_t ve_set_pll_clk(int clk)
+{
+ int n = 0, m = 0;
+ int n_temp = clk;
+ int m_temp = _24MHZ_;
+
+ if ((clk > 600000000) || (clk < 30000000))
+ return RT_EINVAL;
+
+ if (clk == 0)
+ {
+ CCU->pll_ve_ctrl &= ~(0x1 << 31);
+ return RT_EOK;
+ }
+
+ while (n_temp != m_temp)
+ {
+ if (n_temp > m_temp)
+ {
+ n_temp = n_temp - m_temp;
+ }
+ else if (m_temp > n_temp)
+ {
+ m_temp = m_temp - n_temp;
+ }
+ }
+
+ n = clk / n_temp;
+ m = _24MHZ_ / m_temp;
+
+ if ((n > 128) || (m > 16) || (clk != (_24MHZ_ * n) / m))
+ return RT_ERROR;
+
+ CCU->pll_ve_ctrl &= ~(0x1 << 31);
+ n = (n - 1) & 0x7f;
+ m = (m - 1) & 0xf;
+ //clk = (24 * n) / m
+ CCU->pll_ve_ctrl = (0x1 << 31) | (0x1 << 24) | (n << 8) | m;
+ if (wait_pll_stable((rt_uint32_t)(&CCU->pll_ve_ctrl)))
+ return RT_ERROR;
+ else
+ return RT_EOK;
+}
+
+rt_err_t periph_set_pll_clk(int clk)
+{
+ rt_uint32_t clk_src;
+ rt_uint32_t temp_data;
+ int n = 0, k = 0;
+
+ if ((clk > 1800000000) || (clk < 200000000) || (clk == 0) || (clk % _24MHZ_ != 0))
+ return RT_EINVAL;
+
+ n = clk / _24MHZ_;
+
+ for (k = 2; ((n > 32) || (k < 5)); k++)
+ {
+ if ((n % k) != 0)
+ n /= k;
+ }
+
+ if ((n > 32) || (k > 4) || (clk != (_24MHZ_ * n * k)))
+ return RT_ERROR;
+ temp_data = CCU->ahb_apb_hclkc_cfg;
+ clk_src = (temp_data >> 12) & 0x3;
+ temp_data &= ~(0x3 << 12);
+ temp_data |= (CLK_PLL_SRC << 12);
+ CCU->ahb_apb_hclkc_cfg = temp_data;
+ CCU->pll_periph_ctrl &= ~(0x1 << 31);
+ n = (n - 1) & 0x1f;
+ k = (k - 1) & 0x3;
+ //clk = 24 * n *k
+ CCU->pll_periph_ctrl = (0x1 << 31) | (0x1 << 18) | (n << 8) | (k << 4) || (0x1);
+ if (wait_pll_stable((rt_uint32_t)(&CCU->pll_periph_ctrl)))
+ return RT_ERROR;
+
+ temp_data = CCU->ahb_apb_hclkc_cfg;
+ temp_data &= ~(0x3 << 12);
+ temp_data |= (clk_src << 12);
+ CCU->ahb_apb_hclkc_cfg = temp_data;
+
+ return RT_EOK;
+}
+
+rt_err_t cpu_set_clk(int clk)
+{
+ if (clk < _24MHZ_)
+ return RT_EINVAL;
+
+ if (clk == cpu_get_clk())
+ return RT_EOK;
+
+ CCU->cpu_clk_src = CLK_OSC24M_SRC << 16;
+ if (clk == _24MHZ_)
+ return RT_EOK;
+
+ if (cpu_set_pll_clk(clk))
+ return RT_ERROR;
+
+ CCU->ahb_apb_hclkc_cfg &= ~(0x3 << 16);
+ CCU->cpu_clk_src = CLK_PLL_SRC << 16;
+
+ return RT_EOK;
+}
+
+rt_err_t bus_gate_clk_enalbe(enum bus_gate bus)
+{
+ rt_uint32_t offset;
+ rt_uint32_t gate_reg;
+
+ offset = bus & 0xfff;
+ gate_reg = bus >> BUS_GATE_OFFSET_BIT;
+
+ if (gate_reg == 0x00)
+ CCU->bus_clk_gating0 |= (0x1 << offset);
+ else if (gate_reg == 0x01)
+ CCU->bus_clk_gating1 |= (0x1 << offset);
+ else if (gate_reg == 0x02)
+ CCU->bus_clk_gating2 |= (0x1 << offset);
+ else
+ return RT_EINVAL;
+
+ return RT_EOK;
+}
+
+rt_err_t bus_gate_clk_disalbe(enum bus_gate bus)
+{
+ rt_uint32_t offset;
+ rt_uint32_t gate_reg;
+
+ offset = bus & 0xfff;
+ gate_reg = bus >> BUS_GATE_OFFSET_BIT;
+
+ if (gate_reg == 0x00)
+ CCU->bus_clk_gating0 &= ~(0x1 << offset);
+ else if (gate_reg == 0x01)
+ CCU->bus_clk_gating1 &= ~(0x1 << offset);
+ else if (gate_reg == 0x02)
+ CCU->bus_clk_gating2 &= ~(0x1 << offset);
+ else
+ return RT_EINVAL;
+
+ return RT_EOK;
+}
+
+rt_err_t bus_software_reset_enalbe(enum bus_gate bus)
+{
+ rt_uint32_t offset;
+ rt_uint32_t gate_reg;
+
+ offset = bus & 0xfff;
+ gate_reg = bus >> BUS_GATE_OFFSET_BIT;
+
+ if (gate_reg == 0x00)
+ CCU->bus_soft_rst0 |= (0x1 << offset);
+ else if (gate_reg == 0x01)
+ CCU->bus_soft_rst1 |= (0x1 << offset);
+ else if (gate_reg == 0x02)
+ CCU->bus_soft_rst2 |= (0x1 << offset);
+ else
+ return RT_EINVAL;
+
+ return RT_EOK;
+}
+
+rt_err_t bus_software_reset_disalbe(enum bus_gate bus)
+{
+ rt_uint32_t offset;
+ rt_uint32_t gate_reg;
+
+ offset = bus & 0xfff;
+ gate_reg = bus >> BUS_GATE_OFFSET_BIT;
+
+ if (gate_reg == 0x00)
+ CCU->bus_soft_rst0 &= ~(0x1 << offset);
+ else if (gate_reg == 0x01)
+ CCU->bus_soft_rst1 &= ~(0x1 << offset);
+ else if (gate_reg == 0x02)
+ CCU->bus_soft_rst2 &= ~(0x1 << offset);
+ else
+ return RT_EINVAL;
+
+ return RT_EOK;
+}
+
diff --git a/bsp/allwinner_tina/drivers/drv_clock.h b/bsp/allwinner_tina/drivers/drv_clock.h
new file mode 100644
index 0000000000..4818d06dc8
--- /dev/null
+++ b/bsp/allwinner_tina/drivers/drv_clock.h
@@ -0,0 +1,252 @@
+/*
+ * File : drv_clock.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+#ifndef __DRV_CLOCK_H__
+#define __DRV_CLOCK_H__
+
+/* PLL state */
+#define PLL_ENBALE (0x1)
+#define PLL_STABLE (0x2)
+
+/* Clock source selection */
+#define CLK_LOSC_SRC (0x00)
+#define CLK_OSC24M_SRC (0x01)
+#define CLK_PLL_SRC (0x02)
+#define PRE_DIV_SRC (0x03)
+
+/* */
+#define BE_GATING_DRAM (0x1<<26)
+#define FE_GATING_DRAM (0x1<<24)
+#define TVD_GATING_DRAM (0x1<<3)
+#define DEINTERLACE_GATING_DRAM (0x1<<2)
+#define CSI_GATING_DRAM (0x1<<1)
+#define VE_GATING_DRAM (0x1<<0)
+
+
+/* */
+#define TCON_PLL_VIDEO_X1 (0x000)
+#define TCON_PLL_VIDEO_X2 (0x002)
+
+
+#define PLL_CPU_ENABLE_STATE (0x1<<31)
+#define PLL_CPU_HAS_BEEN_STABLE (0x1<<28)
+#define PLL_CPU_DIV_P(reg) ((reg>>16)&0x3)
+#define PLL_CPU_FACTOR_N(reg) ((reg>>8)&0x1f)
+#define PLL_CPU_FACTOR_K(reg) ((reg>>4)&0x3)
+#define PLL_CPU_FACTOR_M(reg) ((reg)&0x3)
+
+#define PLL_AUDIO_ENABLE_STATE (0x1<<31)
+#define PLL_AUDIO_HAS_BEEN_STABLE (0x1<<28)
+#define PLL_AUDIO_FACTOR_N(reg) ((reg>>8)&0x7f)
+#define PLL_AUDIO_PREDIV_M(reg) ((reg)&0x1f)
+
+#define PLL_VIDEO_ENABLE_STATE (0x1<<31)
+#define PLL_VIDEO_MODE (0x1<<30)
+#define PLL_VIDEO_HAS_BEEN_STABLE (0x1<<28)
+#define PLL_VIDEO_FRAC_CLK_OUT (0x1<<25)
+#define PLL_VIDEO_MODE_SEL (0x1<<24)
+#define PLL_VIDEO_SDM_EN (0x1<<20)
+#define PLL_VIDEO_FACTOR_N(reg) ((reg>>8)&0x7f)
+#define PLL_VIDEO_PREDIV_M(reg) (reg&0xf)
+
+#define PLL_VE_ENABLE_STATE (0x1<<31)
+#define PLL_VE_HAS_BEEN_STABLE (0x1<<28)
+#define PLL_VE_FRAC_CLK_OUT (0x1<<25)
+#define PLL_VE_MODE_SEL (0x1<<24)
+#define PLL_VE_FACTOR_N(reg) ((reg>>8)&0x7f)
+#define PLL_VE_PREDIV_M(reg) (reg&0xf)
+
+#define PLL_DDR_ENABLE_STATE (0x1<<31)
+#define PLL_DDR_HAS_BEEN_STABLE (0x1<<28)
+#define SDRAM_SIGMA_DELTA_EN (0x1<<24)
+#define PLL_DDR_CFG_UPDATE (0x1<<20)
+#define PLL_DDR_FACTOR_N(reg) ((reg>>8)&0x1f)
+#define PLL_DDR_FACTOR_K(reg) ((reg>>4)&0x3)
+#define PLL_DDR_FACTOR_M(reg) ((reg)&0x3)
+
+#define PLL_PERIPH_ENABLE_STATE (0x1<<31)
+#define PLL_PERIPH_HAS_BEEN_STABLE (0x1<<28)
+#define PLL_PERIPH_24M_OUT_EN (0x1<<18)
+#define PLL_PERIPH_24M_POST_DIV(reg) ((reg>>16)&0x3)
+#define PLL_PERIPH_FACTOR_N(reg) ((reg>>8)&0x1f)
+#define PLL_PERIPH_FACTOR_K(reg) ((reg>>4)&0x3)
+#define PLL_PERIPH_FACTOR_M(reg) (reg&0x3)
+
+#define HCLKC_DIV(reg) ((reg>>16)&0x3)
+#define AHB_SRC_SEL(reg) ((reg>>12)&0x3)
+#define AHB_CLK_DIV(reg) ((reg>>4)&0x3)
+#define AHB_PRE_DIV(reg) ((reg>>6)&0x3)
+#define APH_CLK_PATIO(reg) ((reg>>8)&0x3)
+
+
+#define CCM_MMC_CTRL_OSCM24 (0x00)
+#define CCM_MMC_CTRL_PLL_PERIPH (0x01)
+
+#define CCU_BASE_ADDR (0x01C20000)
+
+#define _24MHZ_ (24000000U)
+#define _32KHZ_ (32000U)
+
+/* GATE */
+
+#define BUS_GATE_OFFSET_BIT (12)
+
+enum bus_gate
+{
+ USB_OTG_GATING = (0x18 | (0x0 << BUS_GATE_OFFSET_BIT)),
+ SPI1_GATING = (0x15 | (0x0 << BUS_GATE_OFFSET_BIT)),
+ SPI0_GATING = (0x14 | (0x0 << BUS_GATE_OFFSET_BIT)),
+ SDRAM_GATING = (0x0E | (0x0 << BUS_GATE_OFFSET_BIT)),
+ SD1_GATING = (0x09 | (0x0 << BUS_GATE_OFFSET_BIT)),
+ SD0_GATING = (0x08 | (0x0 << BUS_GATE_OFFSET_BIT)),
+ DMA_GATING = (0x06 | (0x0 << BUS_GATE_OFFSET_BIT)),
+
+ DEFE_GATING = (0x0E | (0x1 << BUS_GATE_OFFSET_BIT)),
+ DEBE_GATING = (0x0C | (0x1 << BUS_GATE_OFFSET_BIT)),
+ TVE_GATING = (0x0A | (0x1 << BUS_GATE_OFFSET_BIT)),
+ TVD_GATING = (0x09 | (0x1 << BUS_GATE_OFFSET_BIT)),
+ CSI_GATING = (0x08 | (0x1 << BUS_GATE_OFFSET_BIT)),
+ DEINTERLACE_GATING = (0x05 | (0x1 << BUS_GATE_OFFSET_BIT)),
+ LCD_GATING = (0x04 | (0x1 << BUS_GATE_OFFSET_BIT)),
+ VE_GATING = (0x00 | (0x1 << BUS_GATE_OFFSET_BIT)),
+
+ UART2_GATING = (0x16 | (0x2 << BUS_GATE_OFFSET_BIT)),
+ UART1_GATING = (0x15 | (0x2 << BUS_GATE_OFFSET_BIT)),
+ UART0_GATING = (0x14 | (0x2 << BUS_GATE_OFFSET_BIT)),
+ TWI2_GATING = (0x12 | (0x2 << BUS_GATE_OFFSET_BIT)),
+ TWI1_GATING = (0x11 | (0x2 << BUS_GATE_OFFSET_BIT)),
+ TWI0_GATING = (0x10 | (0x2 << BUS_GATE_OFFSET_BIT)),
+ DAUDIO_GATING = (0x0C | (0x2 << BUS_GATE_OFFSET_BIT)),
+ RSB_GATING = (0x03 | (0x2 << BUS_GATE_OFFSET_BIT)),
+ CIR_GATING = (0x02 | (0x2 << BUS_GATE_OFFSET_BIT)),
+ OWA_GATING = (0x01 | (0x2 << BUS_GATE_OFFSET_BIT)),
+ AUDIO_CODEC_GATING = (0x00 | (0x2 << BUS_GATE_OFFSET_BIT)),
+};
+
+struct tina_ccu
+{
+ volatile rt_uint32_t pll_cpu_ctrl; /* 0x000 */
+ volatile rt_uint32_t reserved0;
+ volatile rt_uint32_t pll_audio_ctrl; /* 0x008 */
+ volatile rt_uint32_t reserved1;
+ volatile rt_uint32_t pll_video_ctrl; /* 0x010 */
+ volatile rt_uint32_t reserved2;
+ volatile rt_uint32_t pll_ve_ctrl; /* 0x018 */
+ volatile rt_uint32_t reserved3;
+ volatile rt_uint32_t pll_ddr_ctrl; /* 0x020 */
+ volatile rt_uint32_t reserved4;
+ volatile rt_uint32_t pll_periph_ctrl; /* 0x028 */
+ volatile rt_uint32_t reserved5[9];
+ volatile rt_uint32_t cpu_clk_src; /* 0x050 */
+ volatile rt_uint32_t ahb_apb_hclkc_cfg; /* 0x054 */
+ volatile rt_uint32_t reserved6[2];
+ volatile rt_uint32_t bus_clk_gating0; /* 0x060 */
+ volatile rt_uint32_t bus_clk_gating1; /* 0x064 */
+ volatile rt_uint32_t bus_clk_gating2; /* 0x068 */
+ volatile rt_uint32_t reserved7[7];
+ volatile rt_uint32_t sdmmc0_clk; /* 0x088 */
+ volatile rt_uint32_t sdmmc1_clk; /* 0x08C */
+ volatile rt_uint32_t reserved8[8];
+ volatile rt_uint32_t daudio_clk; /* 0x0B0 */
+ volatile rt_uint32_t owa_clk; /* 0x0B4 */
+ volatile rt_uint32_t cir_clk; /* 0x0B8 */
+ volatile rt_uint32_t reserved9[4];
+ volatile rt_uint32_t usbphy_clk; /* 0x0CC */
+ volatile rt_uint32_t reserved10[12];
+ volatile rt_uint32_t dram_gating; /* 0x100 */
+ volatile rt_uint32_t be_clk; /* 0x104 */
+ volatile rt_uint32_t reserved11;
+ volatile rt_uint32_t fe_clk; /* 0x10C */
+ volatile rt_uint32_t reserved12[2];
+ volatile rt_uint32_t tcon_clk; /* 0x118*/
+ volatile rt_uint32_t di_clk; /* 0x11C */
+ volatile rt_uint32_t tve_clk; /* 0x120 */
+ volatile rt_uint32_t tvd_clk; /* 0x124 */
+ volatile rt_uint32_t reserved13[3];
+ volatile rt_uint32_t csi_clk; /* 0x134 */
+ volatile rt_uint32_t reserved14;
+ volatile rt_uint32_t ve_clk; /* 0x13C */
+ volatile rt_uint32_t audio_codec_clk; /* 0x140 */
+ volatile rt_uint32_t avs_clk; /* 0x144 */
+ volatile rt_uint32_t reserved15[46];
+ volatile rt_uint32_t pll_stable_time0; /* 0x200 */
+ volatile rt_uint32_t pll_stable_time1; /* 0x204 */
+ volatile rt_uint32_t reserved16[6];
+ volatile rt_uint32_t pll_cpu_bias; /* 0x220 */
+ volatile rt_uint32_t pll_audio_bias; /* 0x224 */
+ volatile rt_uint32_t pll_video_bias; /* 0x228 */
+ volatile rt_uint32_t pll_ve_bias; /* 0x22C */
+ volatile rt_uint32_t pll_ddr_bias; /* 0x230 */
+ volatile rt_uint32_t pll_periph_bias; /* 0x234 */
+ volatile rt_uint32_t reserved17[6];
+ volatile rt_uint32_t pll_cpu_tun; /* 0x250 */
+ volatile rt_uint32_t reserved18[3];
+ volatile rt_uint32_t pll_ddr_tun; /* 0x260 */
+ volatile rt_uint32_t reserved19[8];
+ volatile rt_uint32_t pll_audio_pat_ctrl; /* 0x284 */
+ volatile rt_uint32_t pll_video_pat_ctrl; /* 0x288 */
+ volatile rt_uint32_t reserved20;
+ volatile rt_uint32_t pll_ddr_pat_ctrl; /* 0x290 */
+ volatile rt_uint32_t reserved21[11];
+ volatile rt_uint32_t bus_soft_rst0; /* 0x2C0 */
+ volatile rt_uint32_t bus_soft_rst1; /* 0x2C4 */
+ volatile rt_uint32_t reserved22[2];
+ volatile rt_uint32_t bus_soft_rst2; /* 0x2D0 */
+};
+
+typedef struct tina_ccu *tina_ccu_t;
+
+#define CCU ((tina_ccu_t) CCU_BASE_ADDR)
+
+
+
+
+
+
+
+
+int cpu_get_pll_clk(void);
+int audio_get_pll_clk(void);
+int video_get_pll_clk(void);
+int ve_get_pll_clk(void);
+int ddr_get_pll_clk(void);
+int periph_get_pll_clk(void);
+int cpu_get_clk(void);
+int ahb_get_clk(void);
+int apb_get_clk(void);
+
+rt_err_t cpu_set_pll_clk(int clk);
+rt_err_t audio_set_pll_clk(int clk);
+rt_err_t video_set_pll_clk(int clk);
+rt_err_t ve_set_pll_clk(int clk);
+rt_err_t periph_set_pll_clk(int clk);
+
+rt_err_t cpu_set_clk(int clk);
+
+
+rt_err_t bus_gate_clk_enalbe(enum bus_gate bus);
+rt_err_t bus_gate_clk_disalbe(enum bus_gate bus);
+rt_err_t bus_software_reset_enalbe(enum bus_gate bus);
+rt_err_t bus_software_reset_disalbe(enum bus_gate bus);
+
+#endif \ No newline at end of file
diff --git a/bsp/allwinner_tina/drivers/drv_gpio.c b/bsp/allwinner_tina/drivers/drv_gpio.c
new file mode 100644
index 0000000000..ba31cca0e9
--- /dev/null
+++ b/bsp/allwinner_tina/drivers/drv_gpio.c
@@ -0,0 +1,564 @@
+/*
+ * File : drv_gpio.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "drv_gpio.h"
+#include "interrupt.h"
+
+#define DBG_ENABLE
+#define DBG_SECTION_NAME "[GPIO]"
+#define DBG_LEVEL DBG_WARNING
+#define DBG_COLOR
+#include <rtdbg.h>
+
+
+#define readl(addr) (*(volatile unsigned int *)(addr))
+#define writel(value,addr) (*(volatile unsigned int *)(addr) = (value))
+
+// Todo: add RT_ASSERT.
+
+/*********************************************************
+** IO
+*********************************************************/
+int gpio_set_func(enum gpio_port port, enum gpio_pin pin, rt_uint8_t func)
+{
+ rt_uint32_t addr;
+ rt_uint32_t offset;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ if (func & 0x8)
+ {
+ dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
+ return RT_EINVAL;
+ }
+
+ addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
+ offset = (pin % 8) * 4;
+
+ data = readl(addr);
+ data &= ~(0x7 << offset);
+ data |= func << offset;
+ writel(data, addr);
+
+ dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+ return RT_EOK;
+}
+
+int gpio_set_value(enum gpio_port port, enum gpio_pin pin, rt_uint8_t value)
+{
+ rt_uint32_t addr;
+ rt_uint32_t offset;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ if (value & 0xE)
+ {
+ dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
+ return RT_EINVAL;
+ }
+
+ addr = GPIOn_DATA_ADDR(port);
+ offset = pin;
+
+ data = readl(addr);
+ data &= ~(0x1 << offset);
+ data |= value << offset;
+ writel(data, addr);
+
+ dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+ return RT_EOK;
+}
+
+int gpio_get_value(enum gpio_port port, enum gpio_pin pin)
+{
+ rt_uint32_t addr;
+ rt_uint32_t offset;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ addr = GPIOn_DATA_ADDR(port);
+ offset = pin;
+
+ data = readl(addr);
+
+ dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+ return (data >> offset) & 0x01;
+}
+
+int gpio_set_pull_mode(enum gpio_port port, enum gpio_pin pin, enum gpio_pull pull)
+{
+ rt_uint32_t addr;
+ rt_uint32_t offset;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ if (pull & 0xC)
+ {
+ dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
+ return RT_EINVAL;
+ }
+
+ addr = GPIOn_PUL_ADDR(port);
+ addr += pin > GPIO_PIN_15 ? 0x4 : 0x0;
+ offset = (pin & 0xf) << 1;
+
+ data = readl(addr);
+ data &= ~(0x3 << offset);
+ data |= pull << offset;
+ writel(data, addr);
+
+ dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+ return RT_EOK;
+}
+
+int gpio_set_drive_level(enum gpio_port port, enum gpio_pin pin, enum gpio_drv_level level)
+{
+ volatile rt_uint32_t addr;
+ rt_uint32_t offset;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ if (level & 0xC)
+ {
+ dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
+ return RT_EINVAL;
+ }
+
+ addr = GPIOn_DRV_ADDR(port);
+ addr += pin > GPIO_PIN_15 ? 0x4 : 0x0;
+ offset = (pin & 0xf) << 1;
+
+ data = readl(addr);
+ data &= ~(0x3 << offset);
+ data |= level << offset;
+ writel(data, addr);
+
+ dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+ return RT_EOK;
+}
+
+void gpio_direction_input(enum gpio_port port, enum gpio_pin pin)
+{
+ volatile rt_uint32_t addr;
+ rt_uint32_t offset;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
+ offset = (pin % 8) * 4;
+
+ data = readl(addr);
+ data &= ~(0x7 << offset);
+ data |= IO_INPUT << offset;
+ writel(data, addr);
+
+ dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+}
+
+void gpio_direction_output(enum gpio_port port, enum gpio_pin pin, int value)
+{
+ volatile rt_uint32_t addr;
+ rt_uint32_t offset;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ gpio_set_value(port, pin, value);
+ addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
+ offset = (pin % 8) * 4;
+
+ data = readl(addr);
+ data &= ~(0x7 << offset);
+ data |= IO_OUTPUT << offset;
+ writel(data, addr);
+
+ dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+}
+/*********************************************************
+** IRQ
+*********************************************************/
+static void gpio_ack_irq(enum gpio_port port, enum gpio_pin pin)
+{
+ rt_uint32_t addr;
+ rt_uint32_t data;
+
+ addr = GPIOn_INT_STA_ADDR(port);
+ data = readl(addr);
+ data |= 0x1 << pin;
+ writel(data, addr);
+}
+
+void gpio_select_irq_clock(enum gpio_port port, enum gpio_irq_clock clock)
+{
+ rt_uint32_t addr;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+
+ addr = GPIOn_INT_DEB_ADDR(port - GPIO_PORT_D);
+
+ data = readl(addr);
+ data &= ~0x01;
+ data |= clock;
+ writel(data, addr);
+ dbg_log(DBG_LOG, "[line]:%d addr:%08x data:%08x\n", __LINE__, addr, *((rt_uint32_t *)addr));
+}
+
+void gpio_set_debounce(enum gpio_port port, enum gpio_direction_type prescaler)
+{
+ rt_uint32_t addr;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+
+ addr = GPIOn_INT_DEB_ADDR(port - GPIO_PORT_D);
+
+ data = readl(addr);
+ data &= ~(0x07 << 4);
+ data |= prescaler << 4;
+ writel(data, addr);
+ dbg_log(DBG_LOG, "[line]:%d addr:%08x data:%08x\n", __LINE__, addr, *((rt_uint32_t *)addr));
+}
+
+void gpio_irq_enable(enum gpio_port port, enum gpio_pin pin)
+{
+ rt_uint32_t addr;
+ rt_uint32_t offset;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ addr = GPIOn_INT_CTRL_ADDR(port - GPIO_PORT_D);
+ offset = pin;
+
+ data = readl(addr);
+ data |= 0x1 << offset;
+ writel(data, addr);
+ gpio_select_irq_clock(port, GPIO_IRQ_HOSC_24MHZ);
+ dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+}
+
+void gpio_irq_disable(enum gpio_port port, enum gpio_pin pin)
+{
+ rt_uint32_t addr;
+ rt_uint32_t offset;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ gpio_ack_irq(port - GPIO_PORT_D, pin);
+ addr = GPIOn_INT_CTRL_ADDR(port - GPIO_PORT_D);
+ offset = pin;
+
+ data = readl(addr);
+ data &= ~(0x1 << offset);
+
+ writel(data, addr);
+ dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+}
+
+void gpio_set_irq_type(enum gpio_port port, enum gpio_pin pin, enum gpio_irq_type irq_type)
+{
+ rt_uint32_t addr;
+ rt_uint32_t offset;
+ rt_uint32_t data;
+
+ RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ addr = GPIOn_INT_CFG_ADDR(port - GPIO_PORT_D) + (pin / 8) * 4;
+ offset = (pin % 8) * 4;
+
+ data = readl(addr);
+ data &= ~(0x7 << offset);
+ data |= irq_type << offset;
+ writel(data, addr);
+
+ dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+}
+
+static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_PORT_NUM];
+
+void gpio_set_irq_callback(enum gpio_port port, enum gpio_pin pin, void (*irq_cb)(void *), void *irq_arg)
+{
+ RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+ RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+ _g_gpio_irq_tbl[port].irq_cb[pin] = irq_cb;
+ _g_gpio_irq_tbl[port].irq_arg[pin] = irq_arg;
+}
+
+void gpio_clear_irq_callback(enum gpio_port port, enum gpio_pin pin)
+{
+ gpio_irq_disable(port, pin);
+
+ _g_gpio_irq_tbl[port].irq_cb[pin] = RT_NULL;
+ _g_gpio_irq_tbl[port].irq_arg[pin] = RT_NULL;
+}
+
+static void gpio_irq_handler(int irq, void *param)
+{
+ struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param;
+ rt_uint32_t pend, enable;
+ int port, pin;
+ rt_uint32_t addr;
+
+ pin = 0;
+ port = irq - PIOD_INTERRUPT;
+ addr = GPIOn_INT_STA_ADDR(port);
+ pend = readl(addr);
+ addr = GPIOn_INT_CTRL_ADDR(port);
+ enable = readl(addr);
+ pend &= enable;
+
+ while (pend)
+ {
+ if ((pend & 0x1) && (irq_def->irq_cb[pin] != RT_NULL))
+ {
+ dbg_log(DBG_LOG, "do irq callback...\n", port, pin);
+ irq_def->irq_cb[pin](irq_def->irq_arg[pin]);
+ }
+ pin++;
+ pend = pend >> 1;
+ gpio_ack_irq(port, pin);
+ }
+}
+
+
+#ifdef RT_USING_PIN
+#include <rtdevice.h>
+
+#define PIN_MAGIC (0x5A)
+#define PIN_NUM(_N) (sizeof(_N) / sizeof(_N[0]))
+
+struct _pin_index
+{
+ rt_uint8_t id;
+ rt_uint8_t pin_port;
+ rt_uint8_t pin;
+ rt_uint8_t magic;
+};
+
+static struct _pin_index pin_index[] =
+{
+ {0, 0, 0, 0},
+ {1, 0, 0, 0},
+ {2, 0, 0, 0},
+ {3, 0, 0, 0},
+ {4, 0, 0, 0},
+ {5, 0, 0, 0},
+ {6, GPIO_PORT_D, GPIO_PIN_0, PIN_MAGIC},
+ {7, GPIO_PORT_D, GPIO_PIN_1, PIN_MAGIC},
+ {8, GPIO_PORT_D, GPIO_PIN_2, PIN_MAGIC},
+ {9, GPIO_PORT_D, GPIO_PIN_3, PIN_MAGIC},
+ {10, GPIO_PORT_D, GPIO_PIN_4, PIN_MAGIC},
+ {11, GPIO_PORT_D, GPIO_PIN_5, PIN_MAGIC},
+ {12, GPIO_PORT_D, GPIO_PIN_6, PIN_MAGIC},
+ {13, GPIO_PORT_D, GPIO_PIN_7, PIN_MAGIC},
+ {14, GPIO_PORT_D, GPIO_PIN_8, PIN_MAGIC},
+ {15, GPIO_PORT_D, GPIO_PIN_9, PIN_MAGIC},
+ {16, GPIO_PORT_D, GPIO_PIN_10, PIN_MAGIC},
+ {17, GPIO_PORT_D, GPIO_PIN_11, PIN_MAGIC},
+ {18, GPIO_PORT_D, GPIO_PIN_12, PIN_MAGIC},
+ {19, GPIO_PORT_D, GPIO_PIN_13, PIN_MAGIC},
+ {20, 0, 0, 0},
+ {21, GPIO_PORT_D, GPIO_PIN_14, PIN_MAGIC},
+ {22, 0, 0, 0},
+ {23, GPIO_PORT_D, GPIO_PIN_15, PIN_MAGIC},
+ {24, GPIO_PORT_D, GPIO_PIN_16, PIN_MAGIC},
+ {25, GPIO_PORT_D, GPIO_PIN_17, PIN_MAGIC},
+ {26, GPIO_PORT_D, GPIO_PIN_18, PIN_MAGIC},
+ {27, GPIO_PORT_D, GPIO_PIN_19, PIN_MAGIC},
+ {28, GPIO_PORT_D, GPIO_PIN_20, PIN_MAGIC},
+ {29, GPIO_PORT_D, GPIO_PIN_21, PIN_MAGIC},
+ {30, 0, 0, 0},
+ {31, 0, 0, 0},
+ {32, 0, 0, 0},
+ {33, 0, 0, 0},
+ {34, 0, 0, 0},
+ {35, 0, 0, 0},
+ {36, 0, 0, 0},
+ {37, GPIO_PORT_E, GPIO_PIN_12, PIN_MAGIC},
+ {38, GPIO_PORT_E, GPIO_PIN_11, PIN_MAGIC},
+ {39, GPIO_PORT_E, GPIO_PIN_10, PIN_MAGIC},
+ {40, GPIO_PORT_E, GPIO_PIN_9, PIN_MAGIC},
+ {41, GPIO_PORT_E, GPIO_PIN_8, PIN_MAGIC},
+ {42, GPIO_PORT_E, GPIO_PIN_7, PIN_MAGIC},
+ {43, GPIO_PORT_E, GPIO_PIN_6, PIN_MAGIC},
+ {44, GPIO_PORT_E, GPIO_PIN_5, PIN_MAGIC},
+ {45, GPIO_PORT_E, GPIO_PIN_4, PIN_MAGIC},
+ {46, GPIO_PORT_E, GPIO_PIN_3, PIN_MAGIC},
+ {47, GPIO_PORT_E, GPIO_PIN_2, PIN_MAGIC},
+ {48, GPIO_PORT_E, GPIO_PIN_1, PIN_MAGIC},
+ {49, GPIO_PORT_E, GPIO_PIN_0, PIN_MAGIC},
+ {50, 0, 0, 0},
+ {51, 0, 0, 0},
+ {52, 0, 0, 0},
+ {53, GPIO_PORT_F, GPIO_PIN_5, PIN_MAGIC},
+ {54, GPIO_PORT_F, GPIO_PIN_4, PIN_MAGIC},
+ {55, GPIO_PORT_F, GPIO_PIN_3, PIN_MAGIC},
+ {56, GPIO_PORT_F, GPIO_PIN_2, PIN_MAGIC},
+ {57, GPIO_PORT_F, GPIO_PIN_1, PIN_MAGIC},
+ {58, GPIO_PORT_F, GPIO_PIN_0, PIN_MAGIC},
+ {59, GPIO_PORT_C, GPIO_PIN_0, PIN_MAGIC},
+ {60, GPIO_PORT_C, GPIO_PIN_1, PIN_MAGIC},
+ {61, GPIO_PORT_C, GPIO_PIN_2, PIN_MAGIC},
+ {62, GPIO_PORT_C, GPIO_PIN_3, PIN_MAGIC},
+ {63, GPIO_PORT_A, GPIO_PIN_3, PIN_MAGIC},
+ {64, GPIO_PORT_A, GPIO_PIN_2, PIN_MAGIC},
+ {65, GPIO_PORT_A, GPIO_PIN_1, PIN_MAGIC},
+ {66, GPIO_PORT_A, GPIO_PIN_0, PIN_MAGIC},
+};
+
+static void pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
+{
+ if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+ {
+ dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+ return;
+ }
+
+ gpio_set_func(pin_index[pin].pin_port, pin_index[pin].pin, mode);
+}
+
+static void pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
+{
+ if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+ {
+ dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+ return;
+ }
+
+ gpio_set_value(pin_index[pin].pin_port, pin_index[pin].pin, value);
+}
+
+static int pin_read(struct rt_device *device, rt_base_t pin)
+{
+ if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+ {
+ dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+ return 0;
+ }
+
+ return gpio_get_value(pin_index[pin].pin_port, pin_index[pin].pin);
+}
+
+static rt_err_t pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args)
+{
+ if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+ {
+ dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+ return RT_ERROR;
+ }
+
+ gpio_set_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin, hdr, args);
+ gpio_set_irq_type(pin_index[pin].pin_port, pin_index[pin].pin, mode);
+ return RT_EOK;
+}
+static rt_err_t pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
+{
+ if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+ {
+ dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+ return RT_ERROR;
+ }
+
+ gpio_clear_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin);
+
+ return RT_EOK;
+}
+
+rt_err_t pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
+{
+ if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+ {
+ dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+ return RT_ERROR;
+ }
+
+ if (enabled)
+ gpio_irq_enable(pin_index[pin].pin_port, pin_index[pin].pin);
+ else
+ gpio_irq_disable(pin_index[pin].pin_port, pin_index[pin].pin);
+
+ return RT_EOK;
+}
+
+/*
+ID GPIO ID GPIO ID GPIO ID GPIO ID GPIO ID GPIO ID GPIO
+6 PD0 13 PD7 21 PD14 29 PD21 43 PE6 53 PF5 60 PC1
+7 PD1 14 PD8 23 PD15 37 PE12 44 PE5 54 PF4 61 PC2
+8 PD2 15 PD9 24 PD16 38 PE11 45 PE4 55 PF3 62 PC3
+9 PD3 16 PD10 25 PD17 39 PE10 46 PE3 56 PF2 63 PA3
+10 PD4 17 PD11 26 PD18 40 PE9 47 PE2 57 PF1 64 PA2
+11 PD5 18 PD12 27 PD19 41 PE8 48 PE1 58 PF0 65 PA1
+12 PD6 19 PD13 28 PD20 42 PE7 49 PE0 59 PC0 66 PA0
+*/
+
+static const struct rt_pin_ops ops =
+{
+ pin_mode,
+ pin_write,
+ pin_read,
+ pin_attach_irq,
+ pin_dettach_irq,
+ pin_irq_enable,
+};
+#endif
+
+int rt_hw_gpio_init(void)
+{
+#ifdef RT_USING_PIN
+ rt_device_pin_register("gpio", &ops, RT_NULL);
+#endif
+ /* install ISR */
+ rt_hw_interrupt_install(PIOD_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_D], "gpiod_irq");
+ rt_hw_interrupt_umask(PIOD_INTERRUPT);
+
+ rt_hw_interrupt_install(PIOE_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_E], "gpioe_irq");
+ rt_hw_interrupt_umask(PIOE_INTERRUPT);
+
+ rt_hw_interrupt_install(PIOF_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_F], "gpiof_irq");
+ rt_hw_interrupt_umask(PIOF_INTERRUPT);
+
+ return 0;
+}
+INIT_DEVICE_EXPORT(rt_hw_gpio_init);
diff --git a/bsp/allwinner_tina/drivers/drv_gpio.h b/bsp/allwinner_tina/drivers/drv_gpio.h
new file mode 100644
index 0000000000..35d368f1c8
--- /dev/null
+++ b/bsp/allwinner_tina/drivers/drv_gpio.h
@@ -0,0 +1,244 @@
+/*
+ * File : drv_gpio.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+#ifndef __DRV_GPIO_H__
+#define __DRV_GPIO_H__
+
+/* IO default function */
+#define IO_INPUT (0x00)
+#define IO_OUTPUT (0x01)
+#define IO_DISABLE (0x07)
+
+#define IO_FUN_1 (0x02)
+#define IO_FUN_2 (0x03)
+#define IO_FUN_3 (0x04)
+#define IO_FUN_4 (0x05)
+#define IO_FUN_5 (0x06)
+
+/* IO port */
+enum gpio_port
+{
+ GPIO_PORT_A = 0,
+ GPIO_PORT_B,
+ GPIO_PORT_C,
+ GPIO_PORT_D,
+ GPIO_PORT_E,
+ GPIO_PORT_F,
+ GPIO_PORT_NUM,
+};
+
+/* IO pin */
+enum gpio_pin
+{
+ GPIO_PIN_0 = 0,
+ GPIO_PIN_1,
+ GPIO_PIN_2,
+ GPIO_PIN_3,
+ GPIO_PIN_4,
+ GPIO_PIN_5,
+ GPIO_PIN_6,
+ GPIO_PIN_7,
+ GPIO_PIN_8,
+ GPIO_PIN_9,
+ GPIO_PIN_10,
+ GPIO_PIN_11,
+ GPIO_PIN_12,
+ GPIO_PIN_13,
+ GPIO_PIN_14,
+ GPIO_PIN_15,
+ GPIO_PIN_16,
+ GPIO_PIN_17,
+ GPIO_PIN_18,
+ GPIO_PIN_19,
+ GPIO_PIN_20,
+ GPIO_PIN_21,
+ GPIO_PIN_22,
+ GPIO_PIN_23,
+ GPIO_PIN_NUM,
+};
+
+/* Drive level */
+enum gpio_drv_level
+{
+ DRV_LEVEL_0 = 0,
+ DRV_LEVEL_1,
+ DRV_LEVEL_2,
+ DRV_LEVEL_3,
+};
+
+/* Pull mode */
+enum gpio_pull
+{
+ PULL_DISABLE = 0,
+ PULL_UP,
+ PULL_DOWN,
+};
+
+/* interrupt type */
+enum gpio_irq_type
+{
+ POSITIVE = 0,
+ NEGATIVE,
+ HIGH,
+ LOW,
+ DOUBLE,
+};
+
+enum gpio_irq_clock
+{
+ GPIO_IRQ_LOSC_32KHZ = 0,
+ GPIO_IRQ_HOSC_24MHZ
+};
+
+enum gpio_direction_type
+{
+ DEBOUNCE_PRE_SCALE_1 = 0,
+ DEBOUNCE_PRE_SCALE_2,
+ DEBOUNCE_PRE_SCALE_4,
+ DEBOUNCE_PRE_SCALE_8,
+ DEBOUNCE_PRE_SCALE_16,
+ DEBOUNCE_PRE_SCALE_32,
+ DEBOUNCE_PRE_SCALE_64,
+ DEBOUNCE_PRE_SCALE_128,
+};
+
+struct gpio_irq_def
+{
+ void *irq_arg[32];
+ void (*irq_cb[32])(void *param);
+};
+
+#define GPIO_BASE_ADDR (0x01C20800)
+#define GPIOn_CFG_ADDR(n) (GPIO_BASE_ADDR + (n) * 0x24 + 0x00)
+#define GPIOn_DATA_ADDR(n) (GPIO_BASE_ADDR + (n) * 0x24 + 0x10)
+#define GPIOn_DRV_ADDR(n) (GPIO_BASE_ADDR + (n) * 0x24 + 0x14)
+#define GPIOn_PUL_ADDR(n) (GPIO_BASE_ADDR + (n) * 0x24 + 0x1C)
+#define GPIOn_INT_CFG_ADDR(n) (GPIO_BASE_ADDR + 0x200 + (n) * 0x20 + 0x00)
+#define GPIOn_INT_CTRL_ADDR(n) (GPIO_BASE_ADDR + 0x200 + (n) * 0x20 + 0x10)
+#define GPIOn_INT_STA_ADDR(n) (GPIO_BASE_ADDR + 0x200 + (n) * 0x20 + 0x14)
+#define GPIOn_INT_DEB_ADDR(n) (GPIO_BASE_ADDR + 0x200 + (n) * 0x20 + 0x18)
+
+struct tina_gpio
+{
+ volatile rt_uint32_t pa_cfg0; /* 0x00 */
+ volatile rt_uint32_t pa_cfg1; /* 0x04 */
+ volatile rt_uint32_t pa_cfg2; /* 0x08 */
+ volatile rt_uint32_t pa_cfg3; /* 0x0C */
+ volatile rt_uint32_t pa_data; /* 0x10 */
+ volatile rt_uint32_t pa_drv0; /* 0x14 */
+ volatile rt_uint32_t pa_drv1; /* 0x18 */
+ volatile rt_uint32_t pa_pul0; /* 0x1C */
+ volatile rt_uint32_t pa_pul1; /* 0x20 */
+ volatile rt_uint32_t pb_cfg0; /* 0x24 */
+ volatile rt_uint32_t pb_cfg1; /* 0x28 */
+ volatile rt_uint32_t pb_cfg2; /* 0x2C */
+ volatile rt_uint32_t pb_cfg3; /* 0x30 */
+ volatile rt_uint32_t pb_data; /* 0x34 */
+ volatile rt_uint32_t pb_drv0; /* 0x38 */
+ volatile rt_uint32_t pb_drv1; /* 0x3C */
+ volatile rt_uint32_t pb_pul0; /* 0x40 */
+ volatile rt_uint32_t pb_pul1; /* 0x44 */
+ volatile rt_uint32_t pc_cfg0; /* 0x48 */
+ volatile rt_uint32_t pc_cfg1; /* 0x4C */
+ volatile rt_uint32_t pc_cfg2; /* 0x50 */
+ volatile rt_uint32_t pc_cfg3; /* 0x54 */
+ volatile rt_uint32_t pc_data; /* 0x58 */
+ volatile rt_uint32_t pc_drv0; /* 0x5C */
+ volatile rt_uint32_t pc_drv1; /* 0x60 */
+ volatile rt_uint32_t pc_pul0; /* 0x64 */
+ volatile rt_uint32_t pc_pul1; /* 0x68 */
+ volatile rt_uint32_t pd_cfg0; /* 0x6C */
+ volatile rt_uint32_t pd_cfg1; /* 0x70 */
+ volatile rt_uint32_t pd_cfg2; /* 0x74 */
+ volatile rt_uint32_t pd_cfg3; /* 0x78 */
+ volatile rt_uint32_t pd_data; /* 0x7C */
+ volatile rt_uint32_t pd_drv0; /* 0x80 */
+ volatile rt_uint32_t pd_drv1; /* 0x84 */
+ volatile rt_uint32_t pd_pul0; /* 0x88 */
+ volatile rt_uint32_t pd_pul1; /* 0x8C */
+ volatile rt_uint32_t pe_cfg0; /* 0x90 */
+ volatile rt_uint32_t pe_cfg1; /* 0x94 */
+ volatile rt_uint32_t pe_cfg2; /* 0x98 */
+ volatile rt_uint32_t pe_cfg3; /* 0x9C */
+ volatile rt_uint32_t pe_data; /* 0xA0 */
+ volatile rt_uint32_t pe_drv0; /* 0xA4 */
+ volatile rt_uint32_t pe_drv1; /* 0xA8 */
+ volatile rt_uint32_t pe_pul0; /* 0xAC */
+ volatile rt_uint32_t pe_pul1; /* 0xB0 */
+ volatile rt_uint32_t pf_cfg0; /* 0xB4 */
+ volatile rt_uint32_t pf_cfg1; /* 0xB8 */
+ volatile rt_uint32_t pf_cfg2; /* 0xBC */
+ volatile rt_uint32_t pf_cfg3; /* 0xC0 */
+ volatile rt_uint32_t pf_data; /* 0xC4 */
+ volatile rt_uint32_t pf_drv0; /* 0xC8 */
+ volatile rt_uint32_t pf_drv1; /* 0xCC */
+ volatile rt_uint32_t pf_pul0; /* 0xD0 */
+ volatile rt_uint32_t reserved0[76];
+ volatile rt_uint32_t pd_int_cfg0; /* 0x200 */
+ volatile rt_uint32_t pd_int_cfg1; /* 0x204 */
+ volatile rt_uint32_t pd_int_cfg2; /* 0x208 */
+ volatile rt_uint32_t pd_int_cfg3; /* 0x20C */
+ volatile rt_uint32_t pd_int_ctrl; /* 0x210 */
+ volatile rt_uint32_t pd_int_sta; /* 0x214 */
+ volatile rt_uint32_t pd_int_deb; /* 0x218 */
+ volatile rt_uint32_t reserved1;
+ volatile rt_uint32_t pe_int_cfg0; /* 0x220 */
+ volatile rt_uint32_t pe_int_cfg1; /* 0x224 */
+ volatile rt_uint32_t pe_int_cfg2; /* 0x228 */
+ volatile rt_uint32_t pe_int_cfg3; /* 0x22C */
+ volatile rt_uint32_t pe_int_ctrl; /* 0x230 */
+ volatile rt_uint32_t pe_int_sta; /* 0x234 */
+ volatile rt_uint32_t pe_int_deb; /* 0x238 */
+ volatile rt_uint32_t reserved2;
+ volatile rt_uint32_t pf_int_cfg0; /* 0x240 */
+ volatile rt_uint32_t pf_int_cfg1; /* 0x244 */
+ volatile rt_uint32_t pf_int_cfg2; /* 0x248 */
+ volatile rt_uint32_t pf_int_cfg3; /* 0x24C */
+ volatile rt_uint32_t pf_int_ctrl; /* 0x250 */
+ volatile rt_uint32_t pf_int_sta; /* 0x254 */
+ volatile rt_uint32_t pf_int_deb; /* 0x258 */
+ volatile rt_uint32_t reserved3[26];
+ volatile rt_uint32_t sdr_pad_drv; /* 0x2C0*/
+ volatile rt_uint32_t sdr_pad_pul; /* 0x2C4 */
+};
+
+typedef struct tina_gpio *tina_gpio_t;
+
+#define GPIO ((tina_gpio_t)GPIO_BASE_ADDR)
+
+int gpio_set_func(enum gpio_port port, enum gpio_pin pin, rt_uint8_t func);
+int gpio_set_value(enum gpio_port port, enum gpio_pin pin, rt_uint8_t value);
+int gpio_get_value(enum gpio_port port, enum gpio_pin pin);
+int gpio_set_pull_mode(enum gpio_port port, enum gpio_pin pin, enum gpio_pull pull);
+int gpio_set_drive_level(enum gpio_port port, enum gpio_pin pin, enum gpio_drv_level level);
+void gpio_direction_input(enum gpio_port port, enum gpio_pin pin);
+void gpio_direction_output(enum gpio_port port, enum gpio_pin pin, int value);
+void gpio_irq_enable(enum gpio_port port, enum gpio_pin pin);
+void gpio_irq_disable(enum gpio_port port, enum gpio_pin pin);
+void gpio_set_irq_type(enum gpio_port port, enum gpio_pin pin, enum gpio_irq_type irq_type);
+void gpio_select_irq_clock(enum gpio_port port, enum gpio_irq_clock clock);
+void gpio_set_debounce(enum gpio_port port, rt_uint8_t prescaler);
+void gpio_set_irq_callback(enum gpio_port port, enum gpio_pin pin, void (*irq_cb)(void *), void *irq_arg);
+int rt_hw_gpio_init(void);
+
+#endif /* __DRV_GPIO_H__ */ \ No newline at end of file
diff --git a/bsp/allwinner_tina/drivers/drv_uart.c b/bsp/allwinner_tina/drivers/drv_uart.c
new file mode 100644
index 0000000000..1c48c53dca
--- /dev/null
+++ b/bsp/allwinner_tina/drivers/drv_uart.c
@@ -0,0 +1,324 @@
+/*
+ * File : drv_uart.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "drv_uart.h"
+#include "interrupt.h"
+
+#include "drv_gpio.h"
+#include "drv_clock.h"
+
+#define readl(addr) (*(volatile unsigned int *)(addr))
+#define writel(value,addr) (*(volatile unsigned int *)(addr) = (value))
+
+#ifdef RT_USING_SERIAL
+
+struct device_uart
+{
+ rt_uint32_t hw_base;
+ rt_uint32_t irqno;
+ char name[RT_NAME_MAX];
+ rt_uint32_t gpio_rx_port;
+ rt_uint32_t gpio_tx_port;
+ rt_uint32_t gpio_rx_pin;
+ rt_uint32_t gpio_tx_pin;
+ rt_uint32_t gpio_rx_fun;
+ rt_uint32_t gpio_tx_fun;
+};
+
+static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
+static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg);
+static int uart_putc(struct rt_serial_device *serial, char c);
+static int uart_getc(struct rt_serial_device *serial);
+static rt_size_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
+
+void uart_irq_handler(int irqno, void *param);
+
+const struct rt_uart_ops _uart_ops =
+{
+ uart_configure,
+ uart_control,
+ uart_putc,
+ uart_getc,
+ uart_dma_transmit
+};
+
+/*
+ * UART Initiation
+ */
+int rt_hw_uart_init(void)
+{
+ struct rt_serial_device *serial;
+ struct device_uart *uart;
+ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+
+#ifdef TINA_USING_UART0
+ {
+ static struct rt_serial_device serial0;
+ static struct device_uart uart0;
+
+ serial = &serial0;
+ uart = &uart0;
+
+ serial->ops = &_uart_ops;
+ serial->config = config;
+ serial->config.baud_rate = 115200;
+
+ uart->hw_base = UART0_BASE_ADDR; // UART0_BASE;
+ uart->irqno = UART0_INTERRUPT; // IRQ_UART0;
+ uart->gpio_rx_port = GPIO_PORT_E;
+ uart->gpio_tx_port = GPIO_PORT_E;
+ uart->gpio_rx_pin = GPIO_PIN_0;
+ uart->gpio_tx_pin = GPIO_PIN_1;
+ uart->gpio_rx_fun = IO_FUN_4;
+ uart->gpio_tx_fun = IO_FUN_4;
+
+ rt_hw_serial_register(serial,
+ "uart0",
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+ uart);
+ }
+#endif
+
+#ifdef TINA_USING_UART1
+ {
+ static struct rt_serial_device serial1;
+ static struct device_uart uart1;
+
+ serial = &serial1;
+ uart = &uart1;
+
+ serial->ops = &_uart_ops;
+ serial->config = config;
+ serial->config.baud_rate = 115200;
+
+ uart->hw_base = UART1_BASE_ADDR; // UART1_BASE;
+ uart->irqno = UART1_INTERRUPT; // IRQ_UART1;
+ uart->gpio_rx_port = GPIO_PORT_A;
+ uart->gpio_tx_port = GPIO_PORT_A;
+ uart->gpio_rx_pin = GPIO_PIN_3;
+ uart->gpio_tx_pin = GPIO_PIN_2;
+ uart->gpio_rx_fun = IO_FUN_4;
+ uart->gpio_tx_fun = IO_FUN_4;
+
+ rt_hw_serial_register(serial,
+ "uart1",
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+ uart);
+ }
+#endif
+
+#ifdef TINA_USING_UART2
+ {
+ static struct rt_serial_device serial2;
+ static struct device_uart uart2;
+
+ serial = &serial2;
+ uart = &uart2;
+
+ serial->ops = &_uart_ops;
+ serial->config = config;
+ serial->config.baud_rate = 115200;
+
+ uart->hw_base = UART2_BASE_ADDR; // UART1_BASE;
+ uart->irqno = UART2_INTERRUPT; // IRQ_UART1;
+ uart->gpio_rx_port = GPIO_PORT_E;
+ uart->gpio_tx_port = GPIO_PORT_E;
+ uart->gpio_rx_pin = GPIO_PIN_8;
+ uart->gpio_tx_pin = GPIO_PIN_7;
+ uart->gpio_rx_fun = IO_FUN_2;
+ uart->gpio_tx_fun = IO_FUN_2;
+
+ rt_hw_serial_register(serial,
+ "uart2",
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+ uart);
+ }
+#endif
+
+ return 0;
+}
+
+/*
+ * UART interface
+ */
+static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
+{
+ rt_uint32_t addr, val;
+ struct device_uart *uart;
+
+ RT_ASSERT(serial != RT_NULL);
+ serial->config = *cfg;
+
+ uart = serial->parent.user_data;
+ RT_ASSERT(uart != RT_NULL);
+ /* config gpio port */
+ gpio_set_func(uart->gpio_rx_port, uart->gpio_rx_pin, uart->gpio_rx_fun);
+ gpio_set_func(uart->gpio_tx_port, uart->gpio_tx_pin, uart->gpio_tx_fun);
+ /* Enable UART clock */
+ /* Open the clock gate for uart */
+ if ((rt_uint32_t)(uart->hw_base) == UART0_BASE_ADDR)
+ {
+ bus_gate_clk_enalbe(UART0_GATING);
+ bus_software_reset_enalbe(UART0_GATING);
+ }
+ else if ((rt_uint32_t)(uart->hw_base) == UART1_BASE_ADDR)
+ {
+ bus_gate_clk_enalbe(UART1_GATING);
+ bus_software_reset_enalbe(UART1_GATING);
+ }
+ else if ((rt_uint32_t)(uart->hw_base) == UART2_BASE_ADDR)
+ {
+ bus_gate_clk_enalbe(UART2_GATING);
+ bus_software_reset_enalbe(UART2_GATING);
+ }
+ else
+ RT_ASSERT(0);
+ /* Config uart0 to 115200-8-1-0 */
+ addr = uart->hw_base;
+ /* close uart irq */
+ writel(0x0, addr + UART_IER);
+ /* config fifo */
+ writel(0x37, addr + UART_FCR);
+ /* config modem */
+ writel(0x0, addr + UART_MCR);
+ /* config baud */
+ val = readl(addr + UART_LCR);
+ val |= (1 << 7);
+ writel(val, addr + UART_LCR);
+ val = apb_get_clk() / 16 / serial->config.baud_rate;
+ writel(val & 0xff, addr + UART_DLL);
+ writel((val >> 8) & 0xff, addr + UART_DLH);
+ val = readl(addr + UART_LCR);
+ val &= ~(1 << 7);
+ writel(val, addr + UART_LCR);
+
+ val = readl(addr + UART_LCR);
+ val &= ~0x1f;
+ val |= ((serial->config.data_bits - DATA_BITS_5) << 0) | (0 << 2) | (0x0 << 3);
+ writel(val, addr + UART_LCR);
+
+ writel(0xf, addr + UART_TFL);
+ writel(0x3F, addr + UART_RFL);
+
+ writel(0x1, addr + UART_IER);
+ return RT_EOK;
+}
+
+static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
+{
+ struct device_uart *uart;
+
+ uart = serial->parent.user_data;
+
+ RT_ASSERT(uart != RT_NULL);
+
+ switch (cmd)
+ {
+ case RT_DEVICE_CTRL_CLR_INT:
+ /* Disable the UART Interrupt */
+ rt_hw_interrupt_mask(uart->irqno);
+ writel(0x00, uart->hw_base + UART_IER);
+ break;
+
+ case RT_DEVICE_CTRL_SET_INT:
+ /* install interrupt */
+ rt_hw_interrupt_install(uart->irqno, uart_irq_handler,
+ serial, uart->name);
+ rt_hw_interrupt_umask(uart->irqno);
+ writel(0x01, uart->hw_base + UART_IER);
+ /* Enable the UART Interrupt */
+ break;
+ }
+
+ return (RT_EOK);
+}
+
+
+static int uart_putc(struct rt_serial_device *serial, char c)
+{
+ struct device_uart *uart;
+ volatile rt_uint32_t *sed_buf;
+ volatile rt_uint32_t *sta;
+
+ uart = serial->parent.user_data;
+ sed_buf = (rt_uint32_t *)(uart->hw_base + UART_THR);
+ sta = (rt_uint32_t *)(uart->hw_base + UART_USR);
+ /* FIFO status, contain valid data */
+ while (!(*sta & 0x02));
+ *sed_buf = c;
+
+ return (1);
+}
+
+static int uart_getc(struct rt_serial_device *serial)
+{
+ int ch = -1;
+ volatile rt_uint32_t *rec_buf;
+ volatile rt_uint32_t *sta;
+ struct device_uart *uart = serial->parent.user_data;
+
+ RT_ASSERT(serial != RT_NULL);
+
+ rec_buf = (rt_uint32_t *)(uart->hw_base + UART_RHB);
+ sta = (rt_uint32_t *)(uart->hw_base + UART_USR);
+ /* Receive Data Available */
+ if (*sta & 0x08)
+ {
+ ch = *rec_buf & 0xff;
+ }
+
+ return ch;
+}
+
+static rt_size_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
+{
+ return (0);
+}
+
+/* UART ISR */
+void uart_irq_handler(int irqno, void *param)
+{
+ rt_uint32_t val;
+ struct rt_serial_device *serial = (struct rt_serial_device *)param;
+ struct device_uart *uart = serial->parent.user_data;
+
+ val = readl(uart->hw_base + 0x08) & 0x0F;
+ /* read interrupt status and clear it */
+ if (val & 0x4) /* rx ind */
+ {
+ rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+ }
+
+ if (0) /* tx done */
+ {
+ rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
+ }
+
+}
+
+#endif \ No newline at end of file
diff --git a/bsp/allwinner_tina/drivers/drv_uart.h b/bsp/allwinner_tina/drivers/drv_uart.h
new file mode 100644
index 0000000000..a4e648ffab
--- /dev/null
+++ b/bsp/allwinner_tina/drivers/drv_uart.h
@@ -0,0 +1,83 @@
+/*
+ * File : drv_uart.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+
+
+#ifndef __DRV_UART_H__
+#define __DRV_UART_H__
+
+#define UART0_BASE_ADDR (0x01C25000)
+#define UART1_BASE_ADDR (0x01C25400)
+#define UART2_BASE_ADDR (0x01C25800)
+
+#define UART_THR (0X00)
+#define UART_RHB (0X00)
+#define UART_DLL (0X00)
+#define UART_DLH (0X04)
+#define UART_IER (0X04)
+#define UART_IIR (0X08)
+#define UART_FCR (0X08)
+#define UART_LCR (0X0C)
+#define UART_MCR (0X10)
+#define UART_LSR (0X14)
+#define UART_MSR (0X18)
+#define UART_SCH (0X1C)
+#define UART_USR (0X7C)
+#define UART_TFL (0X80)
+#define UART_RFL (0X84)
+#define UART_HSK (0X88)
+#define UART_HALT (0XA4)
+#define UART_DBG_DLL (0XB0)
+#define UART_DBG_DLH (0XB4)
+
+struct tina_uart
+{
+ volatile rt_uint32_t rx_tx_dll; /* 0x00 */
+ volatile rt_uint32_t dlh_ier; /* 0x04 */
+ volatile rt_uint32_t iir_fcr; /* 0x08 */
+ volatile rt_uint32_t lcr; /* 0x0C */
+ volatile rt_uint32_t mcr; /* 0x10 */
+ volatile rt_uint32_t lsr; /* 0x14 */
+ volatile rt_uint32_t msr; /* 0x18 */
+ volatile rt_uint32_t sch; /* 0x1C */
+ volatile rt_uint32_t reserved0[23];
+ volatile rt_uint32_t usr; /* 0x7c */
+ volatile rt_uint32_t tfl; /* 0x80 */
+ volatile rt_uint32_t rfl; /* 0x84 */
+ volatile rt_uint32_t hsk; /* 0x88 */
+ volatile rt_uint32_t reserved1[6];
+ volatile rt_uint32_t halt; /* 0xa4 */
+ volatile rt_uint32_t reserved2[2];
+ volatile rt_uint32_t dbg_dll; /* 0xb0 */
+ volatile rt_uint32_t dbg_dlh; /* 0xb4 */
+};
+
+typedef struct tina_uart *tina_uart_t;
+
+#define UART0 ((tina_gpio_t)UART0_BASE_ADDR)
+#define UART1 ((tina_gpio_t)UART1_BASE_ADDR)
+#define UART2 ((tina_gpio_t)UART2_BASE_ADDR)
+
+int rt_hw_uart_init(void);
+
+#endif /* __DRV_UART_H__ */
diff --git a/bsp/allwinner_tina/libcpu/SConscript b/bsp/allwinner_tina/libcpu/SConscript
new file mode 100644
index 0000000000..aa13c2b179
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/SConscript
@@ -0,0 +1,13 @@
+Import('rtconfig')
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_gcc.S')
+
+group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/bsp/allwinner_tina/libcpu/context_gcc.S b/bsp/allwinner_tina/libcpu/context_gcc.S
new file mode 100644
index 0000000000..5152618d24
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/context_gcc.S
@@ -0,0 +1,92 @@
+;/*
+; * File : context_iar.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, 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
+; * 2011-08-14 weety copy from mini2440
+; */
+
+#define NOINT 0xC0
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+ .globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+ MRS R0, CPSR
+ ORR R1, R0, #NOINT
+ MSR CPSR_c, R1
+ BX LR
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+ .globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+ MSR CPSR, R0
+ BX LR
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+ .globl rt_hw_context_switch
+rt_hw_context_switch:
+ STMFD SP!, {LR} @; push pc (lr should be pushed in place of pc)
+ STMFD SP!, {R0-R12, LR} @; push lr & register file
+ MRS R4, CPSR
+ STMFD SP!, {R4} @; push cpsr
+ STR SP, [R0] @; store sp in preempted tasks tcb
+ LDR SP, [R1] @; get new task stack pointer
+ LDMFD SP!, {R4} @; pop new task spsr
+ MSR SPSR_cxsf, R4
+ LDMFD SP!, {R0-R12, LR, PC}^ @; pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+ .globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+ LDR SP, [R0] @; get new task stack pointer
+ LDMFD SP!, {R4} @; pop new task cpsr
+ MSR SPSR_cxsf, R4
+ LDMFD SP!, {R0-R12, LR, PC}^ @; pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+ .globl rt_thread_switch_interrupt_flag
+ .globl rt_interrupt_from_thread
+ .globl rt_interrupt_to_thread
+ .globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+ LDR R2, =rt_thread_switch_interrupt_flag
+ LDR R3, [R2]
+ CMP R3, #1
+ BEQ _reswitch
+ MOV R3, #1 @; set flag to 1
+ STR R3, [R2]
+ LDR R2, =rt_interrupt_from_thread @; set rt_interrupt_from_thread
+ STR R0, [R2]
+_reswitch:
+ LDR R2, =rt_interrupt_to_thread @; set rt_interrupt_to_thread
+ STR R1, [R2]
+ BX LR
diff --git a/bsp/allwinner_tina/libcpu/cpu.c b/bsp/allwinner_tina/libcpu/cpu.c
new file mode 100644
index 0000000000..23953dea42
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/cpu.c
@@ -0,0 +1,41 @@
+/*
+ * File : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+RT_WEAK void machine_reset(void)
+{
+ rt_kprintf("reboot system...\n");
+ rt_hw_interrupt_disable();
+ while (1);
+}
+
+RT_WEAK void machine_shutdown(void)
+{
+ rt_kprintf("shutdown...\n");
+ rt_hw_interrupt_disable();
+ while (1);
+}
+
diff --git a/bsp/allwinner_tina/libcpu/cpuport.c b/bsp/allwinner_tina/libcpu/cpuport.c
new file mode 100644
index 0000000000..5def9905f8
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/cpuport.c
@@ -0,0 +1,229 @@
+/*
+ * File : cpuport.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#define ICACHE_MASK (rt_uint32_t)(1 << 12)
+#define DCACHE_MASK (rt_uint32_t)(1 << 2)
+
+extern void machine_reset(void);
+extern void machine_shutdown(void);
+
+#if defined(__GNUC__) || defined(__ICCARM__)
+rt_inline rt_uint32_t cp15_rd(void)
+{
+ rt_uint32_t i;
+
+ __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r"(i));
+ return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+ __asm volatile(\
+ "mrc p15,0,r0,c1,c0,0\n\t" \
+ "orr r0,r0,%0\n\t" \
+ "mcr p15,0,r0,c1,c0,0" \
+ : \
+ : "r"(bit) \
+ : "memory");
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+ __asm volatile(\
+ "mrc p15,0,r0,c1,c0,0\n\t" \
+ "bic r0,r0,%0\n\t" \
+ "mcr p15,0,r0,c1,c0,0" \
+ : \
+ : "r"(bit) \
+ : "memory");
+}
+#endif
+
+#if defined(__CC_ARM)
+rt_inline rt_uint32_t cp15_rd(void)
+{
+ rt_uint32_t i;
+
+ __asm volatile
+ {
+ mrc p15, 0, i, c1, c0, 0
+ }
+
+ return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+ rt_uint32_t value;
+
+ __asm volatile
+ {
+ mrc p15, 0, value, c1, c0, 0
+ orr value, value, bit
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+ rt_uint32_t value;
+
+ __asm volatile
+ {
+ mrc p15, 0, value, c1, c0, 0
+ bic value, value, bit
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+#endif
+
+/**
+ * enable I-Cache
+ *
+ */
+void rt_hw_cpu_icache_enable()
+{
+ cache_enable(ICACHE_MASK);
+}
+
+/**
+ * disable I-Cache
+ *
+ */
+void rt_hw_cpu_icache_disable()
+{
+ cache_disable(ICACHE_MASK);
+}
+
+/**
+ * return the status of I-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_icache_status()
+{
+ return (cp15_rd() & ICACHE_MASK);
+}
+
+/**
+ * enable D-Cache
+ *
+ */
+void rt_hw_cpu_dcache_enable()
+{
+ cache_enable(DCACHE_MASK);
+}
+
+/**
+ * disable D-Cache
+ *
+ */
+void rt_hw_cpu_dcache_disable()
+{
+ cache_disable(DCACHE_MASK);
+}
+
+/**
+ * return the status of D-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_dcache_status()
+{
+ return (cp15_rd() & DCACHE_MASK);
+}
+
+/**
+ * reset cpu by dog's time-out
+ *
+ */
+void rt_hw_cpu_reset()
+{
+
+ rt_kprintf("Restarting system...\n");
+ machine_reset();
+
+ while (1); /* loop forever and wait for reset to happen */
+
+ /* NEVER REACHED */
+}
+
+/**
+ * shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+ rt_uint32_t level;
+ rt_kprintf("shutdown...\n");
+
+ level = rt_hw_interrupt_disable();
+ machine_shutdown();
+ while (level)
+ {
+ RT_ASSERT(0);
+ }
+}
+
+#ifdef RT_USING_CPU_FFS
+/**
+ * This function finds the first bit set (beginning with the least significant bit)
+ * in value and return the index of that bit.
+ *
+ * Bits are numbered starting at 1 (the least significant bit). A return value of
+ * zero from any of these functions means that the argument was zero.
+ *
+ * @return return the index of the first bit set. If value is 0, then this function
+ * shall return 0.
+ */
+#if defined(__CC_ARM)
+int __rt_ffs(int value)
+{
+ register rt_uint32_t x;
+
+ if (value == 0)
+ return value;
+
+ __asm
+ {
+ rsb x, value, #0
+ and x, x, value
+ clz x, x
+ rsb x, x, #32
+ }
+
+ return x;
+}
+#elif defined(__GNUC__) || defined(__ICCARM__)
+int __rt_ffs(int value)
+{
+ return __builtin_ffs(value);
+}
+#endif
+
+#endif
+
+
+/*@}*/
diff --git a/bsp/allwinner_tina/libcpu/interrupt.c b/bsp/allwinner_tina/libcpu/interrupt.c
new file mode 100644
index 0000000000..af9b054da9
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/interrupt.c
@@ -0,0 +1,206 @@
+/*
+ * File : interrupt.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "interrupt.h"
+
+extern rt_uint32_t rt_interrupt_nest;
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+static struct rt_irq_desc isr_table[INTERRUPTS_MAX];
+
+static void rt_hw_interrupt_handler(int vector, void *param)
+{
+ rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+#define readl(addr) (*(volatile unsigned int *)(addr))
+#define writel(value,addr) (*(volatile unsigned int *)(addr) = (value))
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init(void)
+{
+ rt_int32_t idx;
+
+ rt_memset(isr_table, 0x00, sizeof(isr_table));
+ for (idx = 0; idx < INTERRUPTS_MAX; idx ++)
+ {
+ isr_table[idx].handler = rt_hw_interrupt_handler;
+ }
+
+ /* init interrupt nest, and context in thread sp */
+ rt_interrupt_nest = 0;
+ rt_interrupt_from_thread = 0;
+ rt_interrupt_to_thread = 0;
+ rt_thread_switch_interrupt_flag = 0;
+
+ /* set base_addr reg */
+ INTC->base_addr_reg = 0x00000000;
+ /* clear enable */
+ INTC->en_reg0 = 0x00000000;
+ INTC->en_reg1 = 0x00000000;
+ /* mask interrupt */
+ INTC->mask_reg0 = 0xFFFFFFFF;
+ INTC->mask_reg1 = 0xFFFFFFFF;
+ /* clear pending */
+ INTC->pend_reg0 = 0x00000000;
+ INTC->pend_reg1 = 0x00000000;
+ /* set priority */
+ INTC->resp_reg0 = 0x00000000;
+ INTC->resp_reg1 = 0x00000000;
+ /* close fiq interrupt */
+ INTC->ff_reg0 = 0x00000000;
+ INTC->ff_reg1 = 0x00000000;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+ rt_uint32_t mask_addr, data;
+
+ if ((vector < 0) || (vector > INTERRUPTS_MAX))
+ {
+ return;
+ }
+
+ mask_addr = (rt_uint32_t)(&INTC->mask_reg0);
+ mask_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+
+ vector &= 0x1F;
+ data = readl(mask_addr);
+ data |= 0x1 << vector;
+ writel(data, mask_addr);
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+ rt_uint32_t mask_addr, data;
+
+ if ((vector < 0) || (vector > INTERRUPTS_MAX))
+ {
+ return;
+ }
+
+ mask_addr = (rt_uint32_t)(&INTC->mask_reg0);
+ mask_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+
+ vector &= 0x1F;
+ data = readl(mask_addr);
+ data &= ~(0x1 << vector);
+ writel(data, mask_addr);
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param handler the interrupt service routine to be installed
+ * @param param the interrupt service function parameter
+ * @param name the interrupt name
+ * @return old handler
+ */
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+ void *param, char *name)
+{
+ rt_isr_handler_t old_handler = RT_NULL;
+ rt_uint32_t pend_addr, en_addr, data;
+
+ if ((vector < 0) || (vector > INTERRUPTS_MAX))
+ {
+ return old_handler;
+ }
+
+ old_handler = isr_table[vector].handler;
+
+#ifdef RT_USING_INTERRUPT_INFO
+ rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
+#endif /* RT_USING_INTERRUPT_INFO */
+ isr_table[vector].handler = handler;
+ isr_table[vector].param = param;
+
+ pend_addr = (rt_uint32_t)(&INTC->pend_reg0);
+ en_addr = (rt_uint32_t)(&INTC->en_reg0);
+ pend_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+ en_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+
+ vector &= 0x1F;
+ data = readl(pend_addr);
+ data &= ~(0x1 << vector);
+ writel(data, pend_addr);
+
+ data = readl(en_addr);
+ data |= 0x1 << vector;
+ writel(data, en_addr);
+
+ return old_handler;
+}
+
+void rt_interrupt_dispatch(void)
+{
+ void *param;
+ int vector;
+ rt_isr_handler_t isr_func;
+ rt_uint32_t pend_addr, data;
+
+ vector = INTC->vector_reg - INTC->base_addr_reg;
+ vector = vector >> 2;
+
+ isr_func = isr_table[vector].handler;
+ param = isr_table[vector].param;
+
+ /* jump to fun */
+ isr_func(vector, param);
+ /* clear pend bit */
+ pend_addr = (rt_uint32_t)(&INTC->pend_reg0);
+ pend_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+
+ vector &= 0x1F;
+ data = readl(pend_addr);
+ data &= ~(0x1 << vector);
+ writel(data, pend_addr);
+
+#ifdef RT_USING_INTERRUPT_INFO
+ isr_table[vector].counter ++;
+#endif
+}
+
+
+
+
+
+
+
+
+
diff --git a/bsp/allwinner_tina/libcpu/interrupt.h b/bsp/allwinner_tina/libcpu/interrupt.h
new file mode 100644
index 0000000000..5389f0655b
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/interrupt.h
@@ -0,0 +1,107 @@
+/*
+ * File : interrupt.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
+
+/* Max number of interruptions */
+#define INTERRUPTS_MAX (64)
+/* a group num */
+#define GROUP_NUM (32)
+/* Interrupt Source */
+#define NMI_INTERRUPT (0)
+#define UART0_INTERRUPT (1)
+#define UART1_INTERRUPT (2)
+#define UART2_INTERRUPT (3)
+#define OWA_INTERRUPT (5)
+#define CIR_INTERRUPT (6)
+#define TWI0_INTERRUPT (7)
+#define TWI1_INTERRUPT (8)
+#define TWI2_INTERRUPT (9)
+#define SPI0_INTERRUPT (10)
+#define SPI1_INTERRUPT (11)
+#define TIMER0_INTERRUPT (13)
+#define TIMER1_INTERRUPT (14)
+#define TIMER2_INTERRUPT (15)
+#define WATCHDOG_INTERRUPT (16)
+#define RSB_INTERRUPT (17)
+#define DMA_INTERRUPT (18)
+#define TOUCHPANEL_INTERRUPT (20)
+#define AUDIOCODEC_INTERRUPT (21)
+#define KEYADC_INTERRUPT (22)
+#define SDC0_INTERRUPT (23)
+#define SDC1_INTERRUPT (24)
+#define USB_OTG_INTERRUPT (26)
+#define TVD_INTERRUPT (27)
+#define TVE_INTERRUPT (28)
+#define TCON_INTERRUPT (29)
+#define DE_FE_INTERRUPT (30)
+#define DE_BE_INTERRUPT (31)
+#define CSI_INTERRUPT (32)
+#define DE_INTERLACER_INTERRUPT (33)
+#define VE_INTERRUPT (34)
+#define DAUDIO_INTERRUPT (35)
+#define PIOD_INTERRUPT (38)
+#define PIOE_INTERRUPT (39)
+#define PIOF_INTERRUPT (40)
+
+/* intc register address */
+#define INTC_BASE_ADDR (0x01C20400)
+
+struct tina_intc
+{
+ volatile rt_uint32_t vector_reg; /* 0x00 */
+ volatile rt_uint32_t base_addr_reg; /* 0x04 */
+ volatile rt_uint32_t reserved0;
+ volatile rt_uint32_t nmi_ctrl_reg; /* 0x0C */
+ volatile rt_uint32_t pend_reg0; /* 0x10 */
+ volatile rt_uint32_t pend_reg1; /* 0x14 */
+ volatile rt_uint32_t reserved1[2];
+ volatile rt_uint32_t en_reg0; /* 0x20 */
+ volatile rt_uint32_t en_reg1; /* 0x24 */
+ volatile rt_uint32_t reserved2[2];
+ volatile rt_uint32_t mask_reg0; /* 0x30 */
+ volatile rt_uint32_t mask_reg1; /* 0x34 */
+ volatile rt_uint32_t reserved3[2];
+ volatile rt_uint32_t resp_reg0; /* 0x40 */
+ volatile rt_uint32_t resp_reg1; /* 0x44 */
+ volatile rt_uint32_t reserved4[2];
+ volatile rt_uint32_t ff_reg0; /* 0x50 */
+ volatile rt_uint32_t ff_reg1; /* 0x54 */
+ volatile rt_uint32_t reserved5[2];
+ volatile rt_uint32_t prio_reg0; /* 0x60 */
+ volatile rt_uint32_t prio_reg1; /* 0x64 */
+ volatile rt_uint32_t prio_reg2; /* 0x68 */
+ volatile rt_uint32_t prio_reg3; /* 0x6C */
+} ;
+
+typedef struct tina_intc *tina_intc_t;
+
+#define INTC ((tina_intc_t)INTC_BASE_ADDR)
+
+void rt_hw_interrupt_init(void);
+void rt_hw_interrupt_mask(int vector);
+void rt_hw_interrupt_umask(int vector);
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, char *name);
+
+#endif /* __INTERRUPT_H__ */
diff --git a/bsp/allwinner_tina/libcpu/mmu.c b/bsp/allwinner_tina/libcpu/mmu.c
new file mode 100644
index 0000000000..177668a23b
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/mmu.c
@@ -0,0 +1,457 @@
+/*
+ * File : mmu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+
+#include "mmu.h"
+
+/*----- Keil -----------------------------------------------------------------*/
+#ifdef __CC_ARM
+void mmu_setttbase(rt_uint32_t i)
+{
+ register rt_uint32_t value;
+
+ /* Invalidates all TLBs.Domain access is selected as
+ * client by configuring domain access register,
+ * in that case access controlled by permission value
+ * set by page table entry
+ */
+ value = 0;
+ __asm volatile{ mcr p15, 0, value, c8, c7, 0 }
+ value = 0x55555555;
+ __asm volatile { mcr p15, 0, value, c3, c0, 0 }
+ __asm volatile { mcr p15, 0, i, c2, c0, 0 }
+}
+
+void mmu_set_domain(rt_uint32_t i)
+{
+ __asm volatile { mcr p15, 0, i, c3, c0, 0 }
+}
+
+void mmu_enable()
+{
+ register rt_uint32_t value;
+
+ __asm volatile
+ {
+ mrc p15, 0, value, c1, c0, 0
+ orr value, value, #0x01
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+
+void mmu_disable()
+{
+ register rt_uint32_t value;
+
+ __asm volatile
+ {
+ mrc p15, 0, value, c1, c0, 0
+ bic value, value, #0x01
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+
+void mmu_enable_icache()
+{
+ register rt_uint32_t value;
+
+ __asm volatile
+ {
+ mrc p15, 0, value, c1, c0, 0
+ orr value, value, #0x1000
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+
+void mmu_enable_dcache()
+{
+ register rt_uint32_t value;
+
+ __asm volatile
+ {
+ mrc p15, 0, value, c1, c0, 0
+ orr value, value, #0x04
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+
+void mmu_disable_icache()
+{
+ register rt_uint32_t value;
+
+ __asm volatile
+ {
+ mrc p15, 0, value, c1, c0, 0
+ bic value, value, #0x1000
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+
+void mmu_disable_dcache()
+{
+ register rt_uint32_t value;
+
+ __asm volatile
+ {
+ mrc p15, 0, value, c1, c0, 0
+ bic value, value, #0x04
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+
+void mmu_enable_alignfault()
+{
+ register rt_uint32_t value;
+
+ __asm volatile
+ {
+ mrc p15, 0, value, c1, c0, 0
+ orr value, value, #0x02
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+
+void mmu_disable_alignfault()
+{
+ register rt_uint32_t value;
+
+ __asm volatile
+ {
+ mrc p15, 0, value, c1, c0, 0
+ bic value, value, #0x02
+ mcr p15, 0, value, c1, c0, 0
+ }
+}
+
+void mmu_clean_invalidated_cache_index(int index)
+{
+ __asm volatile { mcr p15, 0, index, c7, c14, 2 }
+}
+
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+ unsigned int ptr;
+
+ ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+ while (ptr < buffer + size)
+ {
+ __asm volatile { MCR p15, 0, ptr, c7, c14, 1 }
+ ptr += CACHE_LINE_SIZE;
+ }
+}
+
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+ unsigned int ptr;
+
+ ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+ while (ptr < buffer + size)
+ {
+ __asm volatile { MCR p15, 0, ptr, c7, c10, 1 }
+ ptr += CACHE_LINE_SIZE;
+ }
+}
+
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+ unsigned int ptr;
+
+ ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+ while (ptr < buffer + size)
+ {
+ __asm volatile { MCR p15, 0, ptr, c7, c6, 1 }
+ ptr += CACHE_LINE_SIZE;
+ }
+}
+
+void mmu_invalidate_tlb()
+{
+ register rt_uint32_t value;
+
+ value = 0;
+ __asm volatile { mcr p15, 0, value, c8, c7, 0 }
+}
+
+void mmu_invalidate_icache()
+{
+ register rt_uint32_t value;
+
+ value = 0;
+
+ __asm volatile { mcr p15, 0, value, c7, c5, 0 }
+}
+
+
+void mmu_invalidate_dcache_all()
+{
+ register rt_uint32_t value;
+
+ value = 0;
+
+ __asm volatile { mcr p15, 0, value, c7, c6, 0 }
+}
+/*----- GNU ------------------------------------------------------------------*/
+#elif defined(__GNUC__) || defined(__ICCARM__)
+void mmu_setttbase(register rt_uint32_t i)
+{
+ register rt_uint32_t value;
+
+ /* Invalidates all TLBs.Domain access is selected as
+ * client by configuring domain access register,
+ * in that case access controlled by permission value
+ * set by page table entry
+ */
+ value = 0;
+ asm volatile("mcr p15, 0, %0, c8, c7, 0"::"r"(value));
+
+ value = 0x55555555;
+ asm volatile("mcr p15, 0, %0, c3, c0, 0"::"r"(value));
+
+ asm volatile("mcr p15, 0, %0, c2, c0, 0"::"r"(i));
+
+}
+
+void mmu_set_domain(register rt_uint32_t i)
+{
+ asm volatile("mcr p15,0, %0, c3, c0, 0": :"r"(i));
+}
+
+void mmu_enable()
+{
+ asm volatile
+ (
+ "mrc p15, 0, r0, c1, c0, 0 \n"
+ "orr r0, r0, #0x1 \n"
+ "mcr p15, 0, r0, c1, c0, 0 \n"
+ :::"r0"
+ );
+}
+
+void mmu_disable()
+{
+ asm volatile
+ (
+ "mrc p15, 0, r0, c1, c0, 0 \n"
+ "bic r0, r0, #0x1 \n"
+ "mcr p15, 0, r0, c1, c0, 0 \n"
+ :::"r0"
+ );
+
+}
+
+void mmu_enable_icache()
+{
+ asm volatile
+ (
+ "mrc p15, 0, r0, c1, c0, 0 \n"
+ "orr r0, r0, #(1<<12) \n"
+ "mcr p15, 0, r0, c1, c0, 0 \n"
+ :::"r0"
+ );
+}
+
+void mmu_enable_dcache()
+{
+ asm volatile
+ (
+ "mrc p15, 0, r0, c1, c0, 0 \n"
+ "orr r0, r0, #(1<<2) \n"
+ "mcr p15, 0, r0, c1, c0, 0 \n"
+ :::"r0"
+ );
+
+}
+
+void mmu_disable_icache()
+{
+ asm volatile
+ (
+ "mrc p15, 0, r0, c1, c0, 0 \n"
+ "bic r0, r0, #(1<<12) \n"
+ "mcr p15, 0, r0, c1, c0, 0 \n"
+ :::"r0"
+ );
+
+}
+
+void mmu_disable_dcache()
+{
+ asm volatile
+ (
+ "mrc p15, 0, r0, c1, c0, 0 \n"
+ "bic r0, r0, #(1<<2) \n"
+ "mcr p15, 0, r0, c1, c0, 0 \n"
+ :::"r0"
+ );
+
+}
+
+void mmu_enable_alignfault()
+{
+ asm volatile
+ (
+ "mrc p15, 0, r0, c1, c0, 0 \n"
+ "orr r0, r0, #1 \n"
+ "mcr p15, 0, r0, c1, c0, 0 \n"
+ :::"r0"
+ );
+
+}
+
+void mmu_disable_alignfault()
+{
+ asm volatile
+ (
+ "mrc p15, 0, r0, c1, c0, 0 \n"
+ "bic r0, r0, #1 \n"
+ "mcr p15, 0, r0, c1, c0, 0 \n"
+ :::"r0"
+ );
+
+}
+
+void mmu_clean_invalidated_cache_index(int index)
+{
+ asm volatile("mcr p15, 0, %0, c7, c14, 2": :"r"(index));
+}
+
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+ unsigned int ptr;
+
+ ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+ while (ptr < buffer + size)
+ {
+ asm volatile("mcr p15, 0, %0, c7, c14, 1": :"r"(ptr));
+
+ ptr += CACHE_LINE_SIZE;
+ }
+}
+
+
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+ unsigned int ptr;
+
+ ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+ while (ptr < buffer + size)
+ {
+ asm volatile("mcr p15, 0, %0, c7, c10, 1": :"r"(ptr));
+
+ ptr += CACHE_LINE_SIZE;
+ }
+}
+
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+ unsigned int ptr;
+
+ ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+ while (ptr < buffer + size)
+ {
+ asm volatile("mcr p15, 0, %0, c7, c6, 1": :"r"(ptr));
+
+ ptr += CACHE_LINE_SIZE;
+ }
+}
+
+void mmu_invalidate_tlb()
+{
+ asm volatile("mcr p15, 0, %0, c8, c7, 0": :"r"(0));
+
+}
+
+void mmu_invalidate_icache()
+{
+ asm volatile("mcr p15, 0, %0, c7, c5, 0": :"r"(0));
+
+}
+
+void mmu_invalidate_dcache_all()
+{
+ asm volatile("mcr p15, 0, %0, c7, c6, 0": :"r"(0));
+
+}
+#endif
+
+/* level1 page table */
+#if defined(__ICCARM__)
+#pragma data_alignment=(16*1024)
+static volatile rt_uint32_t _page_table[4 * 1024];
+#else
+static volatile rt_uint32_t _page_table[4 * 1024] \
+__attribute__((aligned(16 * 1024)));
+#endif
+
+void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd,
+ rt_uint32_t paddrStart, rt_uint32_t attr)
+{
+ volatile rt_uint32_t *pTT;
+ volatile int nSec;
+ int i = 0;
+ pTT = (rt_uint32_t *)_page_table + (vaddrStart >> 20);
+ nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
+ for (i = 0; i <= nSec; i++)
+ {
+ *pTT = attr | (((paddrStart >> 20) + i) << 20);
+ pTT++;
+ }
+}
+
+void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)
+{
+ /* disable I/D cache */
+ mmu_disable_dcache();
+ mmu_disable_icache();
+ mmu_disable();
+ mmu_invalidate_tlb();
+
+ /* set page table */
+ for (; size > 0; size--)
+ {
+ mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
+ mdesc->paddr_start, mdesc->attr);
+ mdesc++;
+ }
+
+ /* set MMU table address */
+ mmu_setttbase((rt_uint32_t)_page_table);
+
+ /* enables MMU */
+ mmu_enable();
+
+ /* enable Instruction Cache */
+ mmu_enable_icache();
+
+ /* enable Data Cache */
+ mmu_enable_dcache();
+
+ mmu_invalidate_icache();
+ mmu_invalidate_dcache_all();
+}
diff --git a/bsp/allwinner_tina/libcpu/mmu.h b/bsp/allwinner_tina/libcpu/mmu.h
new file mode 100644
index 0000000000..b73f59c288
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/mmu.h
@@ -0,0 +1,65 @@
+/*
+ * File : mmu.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+#ifndef __MMU_H__
+#define __MMU_H__
+
+#include <rtthread.h>
+
+#define CACHE_LINE_SIZE 32
+
+#define DESC_SEC (0x2|(1<<4))
+#define CB (3<<2) //cache_on, write_back
+#define CNB (2<<2) //cache_on, write_through
+#define NCB (1<<2) //cache_off,WR_BUF on
+#define NCNB (0<<2) //cache_off,WR_BUF off
+#define AP_RW (3<<10) //supervisor=RW, user=RW
+#define AP_RO (2<<10) //supervisor=RW, user=RO
+
+#define DOMAIN_FAULT (0x0)
+#define DOMAIN_CHK (0x1)
+#define DOMAIN_NOTCHK (0x3)
+#define DOMAIN0 (0x0<<5)
+#define DOMAIN1 (0x1<<5)
+
+#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
+#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
+
+#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */
+#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */
+#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
+#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
+
+struct mem_desc
+{
+ rt_uint32_t vaddr_start;
+ rt_uint32_t vaddr_end;
+ rt_uint32_t paddr_start;
+ rt_uint32_t attr;
+};
+
+void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size);
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size);
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size);
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size);
+#endif
diff --git a/bsp/allwinner_tina/libcpu/rt_low_level_init.c b/bsp/allwinner_tina/libcpu/rt_low_level_init.c
new file mode 100644
index 0000000000..807b9b203d
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/rt_low_level_init.c
@@ -0,0 +1,81 @@
+/*
+ * File : rt_low_level_init.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+
+void rt_low_level_init(void)
+{
+ volatile unsigned int *addr;
+ volatile unsigned int time;
+ int i;
+
+ //change cpu clk source to 24M
+ addr = (unsigned int *)(0x01c20000 + 0x050);
+ *addr = 0x10000;
+ //init cpu pll clk 408M
+ addr = (unsigned int *)(0x01c20000 + 0x000);
+ *addr = 0x80001000;
+ time = 0xffff;
+ while ((!(*addr & (0x1 << 28))) && (time--));
+ //change cpu clk source to pll
+ if (time > 0)
+ {
+ addr = (unsigned int *)(0x01c20000 + 0x050);
+ *addr = 0x20000;
+ }
+
+ //init periph pll clk:600M
+ //init ahb pll clk:200M
+ //init apb pll clk:100M
+ addr = (unsigned int *)(0x01c20000 + 0x028);
+ if (*addr & (0x1 << 31))
+ return;
+
+ addr = (unsigned int *)(0x01c20000 + 0x200);
+ *addr = 0x1ff;
+ addr = (unsigned int *)(0x01c20000 + 0x204);
+ *addr = 0x1ff;
+
+ addr = (unsigned int *)(0x01c20000 + 0x028);
+ *addr |= (0x1 << 31);
+ while (!(*addr & (0x1 << 28)));
+
+ addr = (unsigned int *)(0x01c20000 + 0x054);
+ *addr = (0x0 << 16) | (0x3 << 12) | (0x0 << 8) | (0x2 << 6) | (0x0 << 4);
+
+ //init gpio config
+ for (i = 0; i < 6; i++)
+ {
+ if (i == 1)
+ continue;// not config gpio B
+
+ addr = (unsigned int *)(0x01c20800 + i * 0x24 + 0x00);
+ *addr = 0x77777777;
+ addr = (unsigned int *)(0x01c20800 + i * 0x24 + 0x04);
+ *addr = 0x77777777;
+ addr = (unsigned int *)(0x01c20800 + i * 0x24 + 0x08);
+ *addr = 0x77777777;
+ addr = (unsigned int *)(0x01c20800 + i * 0x24 + 0x0C);
+ *addr = 0x77777777;
+ }
+}
+
diff --git a/bsp/allwinner_tina/libcpu/stack.c b/bsp/allwinner_tina/libcpu/stack.c
new file mode 100644
index 0000000000..8f4c218ee1
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/stack.c
@@ -0,0 +1,81 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+#include <rtthread.h>
+
+/*****************************/
+/* CPU Mode */
+/*****************************/
+#define USERMODE 0x10
+#define FIQMODE 0x11
+#define IRQMODE 0x12
+#define SVCMODE 0x13
+#define ABORTMODE 0x17
+#define UNDEFMODE 0x1b
+#define MODEMASK 0x1f
+#define NOINT 0xc0
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+ rt_uint8_t *stack_addr, void *texit)
+{
+ rt_uint32_t *stk;
+
+ //stk = (rt_uint32_t*)stack_addr;
+ stack_addr += sizeof(rt_uint32_t);
+ stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
+ stk = (rt_uint32_t *)stack_addr;
+
+ *(--stk) = (rt_uint32_t)tentry; /* entry point */
+ *(--stk) = (rt_uint32_t)texit; /* lr */
+ *(--stk) = 0xdeadbeef; /* r12 */
+ *(--stk) = 0xdeadbeef; /* r11 */
+ *(--stk) = 0xdeadbeef; /* r10 */
+ *(--stk) = 0xdeadbeef; /* r9 */
+ *(--stk) = 0xdeadbeef; /* r8 */
+ *(--stk) = 0xdeadbeef; /* r7 */
+ *(--stk) = 0xdeadbeef; /* r6 */
+ *(--stk) = 0xdeadbeef; /* r5 */
+ *(--stk) = 0xdeadbeef; /* r4 */
+ *(--stk) = 0xdeadbeef; /* r3 */
+ *(--stk) = 0xdeadbeef; /* r2 */
+ *(--stk) = 0xdeadbeef; /* r1 */
+ *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
+ /* cpsr */
+ if ((rt_uint32_t)tentry & 0x01)
+ *(--stk) = SVCMODE | 0x20; /* thumb mode */
+ else
+ *(--stk) = SVCMODE; /* arm mode */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
diff --git a/bsp/allwinner_tina/libcpu/start_gcc.S b/bsp/allwinner_tina/libcpu/start_gcc.S
new file mode 100644
index 0000000000..94c985a370
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/start_gcc.S
@@ -0,0 +1,346 @@
+/*
+ * File : start_gcc.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2013-2018, RT-Thread Development Team
+ */
+
+.equ MODE_USR, 0x10
+.equ MODE_FIQ, 0x11
+.equ MODE_IRQ, 0x12
+.equ MODE_SVC, 0x13
+.equ MODE_ABT, 0x17
+.equ MODE_UND, 0x1B
+.equ MODE_SYS, 0x1F
+.equ MODEMASK, 0x1F
+.equ NOINT, 0xC0
+
+.equ I_BIT, 0x80
+.equ F_BIT, 0x40
+
+.equ UND_STACK_SIZE, 0x00000100
+.equ SVC_STACK_SIZE, 0x00000100
+.equ ABT_STACK_SIZE, 0x00000100
+.equ FIQ_STACK_SIZE, 0x00000100
+.equ IRQ_STACK_SIZE, 0x00000100
+.equ SYS_STACK_SIZE, 0x00000100
+
+ /*
+ ***************************************
+ * Interrupt vector table
+ ***************************************
+ */
+.section .vectors
+.code 32
+
+.global system_vectors
+system_vectors:
+ ldr pc, _vector_reset
+ ldr pc, _vector_undef
+ ldr pc, _vector_swi
+ ldr pc, _vector_pabt
+ ldr pc, _vector_dabt
+ ldr pc, _vector_resv
+ ldr pc, _vector_irq
+ ldr pc, _vector_fiq
+
+_vector_reset:
+ .word reset
+_vector_undef:
+ .word vector_undef
+_vector_swi:
+ .word vector_swi
+_vector_pabt:
+ .word vector_pabt
+_vector_dabt:
+ .word vector_dabt
+_vector_resv:
+ .word vector_resv
+_vector_irq:
+ .word vector_irq
+_vector_fiq:
+ .word vector_fiq
+
+.balignl 16,0xdeadbeef
+
+
+ /*
+ ***************************************
+ * Stack and Heap Definitions
+ ***************************************
+ */
+ .section .data
+ .space UND_STACK_SIZE
+ .align 3
+ .global und_stack_start
+und_stack_start:
+
+ .space ABT_STACK_SIZE
+ .align 3
+ .global abt_stack_start
+abt_stack_start:
+
+ .space FIQ_STACK_SIZE
+ .align 3
+ .global fiq_stack_start
+fiq_stack_start:
+
+ .space IRQ_STACK_SIZE
+ .align 3
+ .global irq_stack_start
+irq_stack_start:
+
+ .skip SYS_STACK_SIZE
+ .align 3
+ .global sys_stack_start
+sys_stack_start:
+
+ .space SVC_STACK_SIZE
+ .align 3
+ .global svc_stack_start
+svc_stack_start:
+
+/*
+ ***************************************
+ * Startup Code
+ ***************************************
+ */
+ .section .text
+ .global reset
+reset:
+ /* Enter svc mode and mask interrupts */
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK
+ orr r0, r0, #MODE_SVC|NOINT
+ msr cpsr_cxsf, r0
+
+ /* init cpu */
+ bl cpu_init_crit
+
+ /* todo:copyself to link address */
+
+ /* Copy vector to the correct address */
+ ldr r0, =system_vectors
+ mrc p15, 0, r2, c1, c0, 0
+ ands r2, r2, #(1 << 13)
+ ldreq r1, =0x00000000
+ ldrne r1, =0xffff0000
+ ldmia r0!, {r2-r8, r10}
+ stmia r1!, {r2-r8, r10}
+ ldmia r0!, {r2-r8, r10}
+ stmia r1!, {r2-r8, r10}
+
+ /* turn off the watchdog */
+ ldr r0, =0x01C20CB8
+ mov r1, #0x0
+ str r1, [r0]
+
+ /* mask all IRQs source */
+ ldr r1, =0xffffffff
+ ldr r0, =0x01C20430
+ str r1, [r0], #0x04
+ str r1, [r0]
+
+ /* Call low level init function */
+ ldr sp, =svc_stack_start
+ ldr r0, =rt_low_level_init
+ blx r0
+
+ /* init stack */
+ bl stack_setup
+
+ /* clear bss */
+ mov r0, #0
+ ldr r1, =__bss_start
+ ldr r2, =__bss_end
+
+bss_clear_loop:
+ cmp r1, r2
+ strlo r0, [r1], #4
+ blo bss_clear_loop
+
+ /* call c++ constructors of global objects */
+ /*
+ ldr r0, =__ctors_start__
+ ldr r1, =__ctors_end__
+
+ctor_loop:
+ cmp r0, r1
+ beq ctor_end
+ ldr r2, [r0], #4
+ stmfd sp!, {r0-r1}
+ mov lr, pc
+ bx r2
+ ldmfd sp!, {r0-r1}
+ b ctor_loop
+ctor_end:
+ */
+ /* start RT-Thread Kernel */
+ ldr pc, _rtthread_startup
+_rtthread_startup:
+ .word rtthread_startup
+
+
+
+cpu_init_crit:
+ /* invalidate I/D caches */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0
+ mcr p15, 0, r0, c8, c7, 0
+
+ /* disable MMU stuff and caches */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00002300
+ bic r0, r0, #0x00000087
+ orr r0, r0, #0x00000002
+ orr r0, r0, #0x00001000
+ mcr p15, 0, r0, c1, c0, 0
+
+ bx lr
+
+stack_setup:
+ /* Setup Stack for each mode */
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK
+
+ orr r1, r0, #MODE_UND|NOINT
+ msr cpsr_cxsf, r1
+ ldr sp, =und_stack_start
+
+ orr r1, r0, #MODE_ABT|NOINT
+ msr cpsr_cxsf, r1
+ ldr sp, =abt_stack_start
+
+ orr r1, r0, #MODE_IRQ|NOINT
+ msr cpsr_cxsf, r1
+ ldr sp, =irq_stack_start
+
+ orr r1, r0, #MODE_FIQ|NOINT
+ msr cpsr_cxsf, r1
+ ldr sp, =fiq_stack_start
+
+ orr r1, r0, #MODE_SYS|NOINT
+ msr cpsr_cxsf,r1
+ ldr sp, =sys_stack_start
+
+ orr r1, r0, #MODE_SVC|NOINT
+ msr cpsr_cxsf, r1
+ ldr sp, =svc_stack_start
+
+ bx lr
+
+/*
+ ***************************************
+ * exception handlers
+ ***************************************
+ */
+ .global rt_hw_trap_udef
+ .global rt_hw_trap_swi
+ .global rt_hw_trap_pabt
+ .global rt_hw_trap_dabt
+ .global rt_hw_trap_resv
+ .global rt_hw_trap_irq
+ .global rt_hw_trap_fiq
+
+ .global rt_interrupt_enter
+ .global rt_interrupt_leave
+ .global rt_thread_switch_interrupt_flag
+ .global rt_interrupt_from_thread
+ .global rt_interrupt_to_thread
+
+ /* Interrupt */
+ .align 5
+vector_fiq:
+ stmfd sp!,{r0-r7,lr}
+ bl rt_hw_trap_fiq
+ ldmfd sp!,{r0-r7,lr}
+ subs pc, lr, #4
+
+ .align 5
+vector_irq:
+ stmfd sp!, {r0-r12,lr}
+
+ bl rt_interrupt_enter
+ bl rt_hw_trap_irq
+ bl rt_interrupt_leave
+
+ ldr r0, =rt_thread_switch_interrupt_flag
+ ldr r1, [r0]
+ cmp r1, #1
+ beq rt_hw_context_switch_interrupt_do
+
+ ldmfd sp!, {r0-r12,lr}
+ subs pc, lr, #4
+
+rt_hw_context_switch_interrupt_do:
+ mov r1, #0
+ str r1, [r0]
+
+ mov r1, sp
+ add sp, sp, #4*4
+ ldmfd sp!, {r4-r12,lr}
+ mrs r0, spsr
+ sub r2, lr, #4
+
+ msr cpsr_c, #I_BIT|F_BIT|MODE_SVC
+
+ stmfd sp!, {r2}
+ stmfd sp!, {r4-r12,lr}
+ ldmfd r1, {r1-r4}
+ stmfd sp!, {r1-r4}
+ stmfd sp!, {r0}
+
+ ldr r4, =rt_interrupt_from_thread
+ ldr r5, [r4]
+ str sp, [r5]
+
+ ldr r6, =rt_interrupt_to_thread
+ ldr r6, [r6]
+ ldr sp, [r6]
+
+ ldmfd sp!, {r4}
+ msr spsr_cxsf, r4
+
+ ldmfd sp!, {r0-r12,lr,pc}^
+
+ /* Exception */
+.macro push_svc_reg
+ sub sp, sp, #17 * 4
+ stmia sp, {r0 - r12}
+ mov r0, sp
+ mrs r6, spsr
+ str lr, [r0, #15*4]
+ str r6, [r0, #16*4]
+ str sp, [r0, #13*4]
+ str lr, [r0, #14*4]
+.endm
+
+ .align 5
+vector_swi:
+ push_svc_reg
+ bl rt_hw_trap_swi
+ b .
+
+ .align 5
+vector_undef:
+ push_svc_reg
+ bl rt_hw_trap_udef
+ b .
+
+ .align 5
+vector_pabt:
+ push_svc_reg
+ bl rt_hw_trap_pabt
+ b .
+
+ .align 5
+vector_dabt:
+ push_svc_reg
+ bl rt_hw_trap_dabt
+ b .
+
+ .align 5
+vector_resv:
+ push_svc_reg
+ bl rt_hw_trap_resv
+ b .
+
diff --git a/bsp/allwinner_tina/libcpu/trap.c b/bsp/allwinner_tina/libcpu/trap.c
new file mode 100644
index 0000000000..84bb3e7f8a
--- /dev/null
+++ b/bsp/allwinner_tina/libcpu/trap.c
@@ -0,0 +1,223 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2018-02-08 RT-Thread the first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#define INT_IRQ 0x00
+#define INT_FIQ 0x01
+
+extern struct rt_thread *rt_current_thread;
+#ifdef RT_USING_FINSH
+extern long list_thread(void);
+#endif
+
+struct rt_hw_register
+{
+ rt_uint32_t r0;
+ rt_uint32_t r1;
+ rt_uint32_t r2;
+ rt_uint32_t r3;
+ rt_uint32_t r4;
+ rt_uint32_t r5;
+ rt_uint32_t r6;
+ rt_uint32_t r7;
+ rt_uint32_t r8;
+ rt_uint32_t r9;
+ rt_uint32_t r10;
+ rt_uint32_t fp;
+ rt_uint32_t ip;
+ rt_uint32_t sp;
+ rt_uint32_t lr;
+ rt_uint32_t pc;
+ rt_uint32_t cpsr;
+ rt_uint32_t ORIG_r0;
+};
+static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
+void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context))
+{
+ rt_exception_hook = exception_handle;
+}
+/**
+ * this function will show registers of CPU
+ *
+ * @param regs the registers point
+ */
+
+void rt_hw_show_register(struct rt_hw_register *regs)
+{
+ rt_kprintf("Execption:\n");
+ rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n",
+ regs->r0, regs->r1, regs->r2, regs->r3);
+ rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n",
+ regs->r4, regs->r5, regs->r6, regs->r7);
+ rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n",
+ regs->r8, regs->r9, regs->r10);
+ rt_kprintf("fp :0x%08x ip :0x%08x\n",
+ regs->fp, regs->ip);
+ rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n",
+ regs->sp, regs->lr, regs->pc);
+ rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
+}
+
+/**
+ * When ARM7TDMI comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_udef(struct rt_hw_register *regs)
+{
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(regs);
+ if (result == RT_EOK) return;
+ }
+ rt_hw_show_register(regs);
+
+ rt_kprintf("undefined instruction\n");
+ rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * The software interrupt instruction (SWI) is used for entering
+ * Supervisor mode, usually to request a particular supervisor
+ * function.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_swi(struct rt_hw_register *regs)
+{
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(regs);
+ if (result == RT_EOK) return;
+ }
+ rt_hw_show_register(regs);
+
+ rt_kprintf("software interrupt\n");
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_pabt(struct rt_hw_register *regs)
+{
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(regs);
+ if (result == RT_EOK) return;
+ }
+ rt_hw_show_register(regs);
+
+ rt_kprintf("prefetch abort\n");
+ rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during a data access.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_dabt(struct rt_hw_register *regs)
+{
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(regs);
+ if (result == RT_EOK) return;
+ }
+ rt_hw_show_register(regs);
+
+ rt_kprintf("data abort\n");
+ rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * Normally, system will never reach here
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_resv(struct rt_hw_register *regs)
+{
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(regs);
+ if (result == RT_EOK) return;
+ }
+ rt_kprintf("not used\n");
+ rt_hw_show_register(regs);
+ rt_hw_cpu_shutdown();
+}
+
+extern void rt_interrupt_dispatch(void);
+
+void rt_hw_trap_irq(void)
+{
+ rt_interrupt_dispatch();
+}
+
+void rt_hw_trap_fiq(void)
+{
+ rt_interrupt_dispatch();
+}
diff --git a/bsp/allwinner_tina/link.lds b/bsp/allwinner_tina/link.lds
new file mode 100644
index 0000000000..eb974dea0f
--- /dev/null
+++ b/bsp/allwinner_tina/link.lds
@@ -0,0 +1,148 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+SECTIONS
+{
+ . = 0x80000000;
+
+ . = ALIGN(4);
+ __text_start = .;
+ .text :
+ {
+ *(.vectors)
+ *(.text)
+ *(.text.*)
+ KEEP(*(.fini))
+
+ /* 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 modules */
+ . = ALIGN(4);
+ __rtmsymtab_start = .;
+ KEEP(*(RTMSymTab))
+ __rtmsymtab_end = .;
+
+ /* section information for initialization */
+ . = ALIGN(4);
+ __rt_init_start = .;
+ KEEP(*(SORT(.rti_fn*)))
+ __rt_init_end = .;
+ } =0
+ __text_end = .;
+
+ __rodata_start = .;
+ .rodata : { *(.rodata) *(.rodata.*) *(.eh_frame) }
+ __rodata_end = .;
+
+ . = ALIGN(4);
+ .ctors :
+ {
+ PROVIDE(__ctors_start__ = .);
+ *crtbegin.o(.ctors)
+ *crtbegin?.o(.ctors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+ PROVIDE(__ctors_end__ = .);
+ }
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ }
+ /* The .ARM.exidx section is used for C++ exception handling. */
+ /* .ARM.exidx is sorted, so has to go in its own output section. */
+ __exidx_start = .;
+ ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+
+ /* This is used by the startup in order to initialize the .data secion */
+ _sidata = .;
+ }
+ __exidx_end = .;
+
+ .dtors :
+ {
+ PROVIDE(__dtors_start__ = .);
+ *crtbegin.o(.dtors)
+ *crtbegin?.o(.dtors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+ PROVIDE(__dtors_end__ = .);
+ }
+
+ __data_start = .;
+ . = ALIGN(4);
+ .data :
+ {
+ *(.data)
+ *(.data.*)
+
+ . = ALIGN(4);
+ /* preinit data */
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(4);
+ /* init data */
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+
+ . = ALIGN(4);
+ /* finit data */
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+ /* All data end */
+
+ *(.gnu.linkonce.d*)
+ }
+ __data_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss :
+ {
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ . = ALIGN(4);
+ }
+ . = ALIGN(4);
+ __bss_end = .;
+
+ /* Stabs debugging sections. */
+ .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_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ _end = .;
+}
diff --git a/bsp/allwinner_tina/rtconfig.h b/bsp/allwinner_tina/rtconfig.h
new file mode 100644
index 0000000000..ea0bbf8deb
--- /dev/null
+++ b/bsp/allwinner_tina/rtconfig.h
@@ -0,0 +1,235 @@
+#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
+/* RT_THREAD_PRIORITY_8 is not set */
+#define RT_THREAD_PRIORITY_32
+/* RT_THREAD_PRIORITY_256 is not set */
+#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
+/* RT_USING_TIMER_SOFT is not set */
+
+/* Inter-Thread communication */
+
+#define RT_USING_SEMAPHORE
+#define RT_USING_MUTEX
+#define RT_USING_EVENT
+#define RT_USING_MAILBOX
+#define RT_USING_MESSAGEQUEUE
+/* RT_USING_SIGNALS is not set */
+
+/* Memory Management */
+
+#define RT_USING_MEMPOOL
+/* RT_USING_MEMHEAP is not set */
+/* RT_USING_NOHEAP is not set */
+#define RT_USING_SMALL_MEM
+/* RT_USING_SLAB is not set */
+/* RT_USING_MEMTRACE is not set */
+#define RT_USING_HEAP
+
+/* Kernel Device Object */
+
+#define RT_USING_DEVICE
+/* RT_USING_INTERRUPT_INFO is not set */
+#define RT_USING_CONSOLE
+#define RT_CONSOLEBUF_SIZE 128
+#define RT_CONSOLE_DEVICE_NAME "uart0"
+/* RT_USING_MODULE is not set */
+#define ARCH_ARM
+#define ARCH_ARM_ARM9
+
+/* RT-Thread Components */
+
+#define RT_USING_COMPONENTS_INIT
+#define RT_USING_USER_MAIN
+
+/* C++ features */
+
+/* RT_USING_CPLUSPLUS is not set */
+
+/* Command shell */
+
+#define RT_USING_FINSH
+#define FINSH_THREAD_NAME "tshell"
+#define FINSH_USING_HISTORY
+#define FINSH_HISTORY_LINES 5
+#define FINSH_USING_SYMTAB
+#define FINSH_USING_DESCRIPTION
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 4096
+#define FINSH_CMD_SIZE 80
+/* FINSH_USING_AUTH is not set */
+#define FINSH_USING_MSH
+#define FINSH_USING_MSH_DEFAULT
+/* FINSH_USING_MSH_ONLY is not set */
+
+/* Device virtual file system */
+
+#define RT_USING_DFS
+#define DFS_USING_WORKDIR
+#define DFS_FILESYSTEMS_MAX 2
+#define DFS_FILESYSTEM_TYPES_MAX 2
+#define DFS_FD_MAX 4
+#define RT_USING_DFS_ELMFAT
+
+/* elm-chan's FatFs, Generic FAT Filesystem Module */
+
+#define RT_DFS_ELM_CODE_PAGE 437
+#define RT_DFS_ELM_WORD_ACCESS
+#define RT_DFS_ELM_USE_LFN_0
+/* RT_DFS_ELM_USE_LFN_1 is not set */
+/* RT_DFS_ELM_USE_LFN_2 is not set */
+/* RT_DFS_ELM_USE_LFN_3 is not set */
+#define RT_DFS_ELM_USE_LFN 0
+#define RT_DFS_ELM_MAX_LFN 255
+#define RT_DFS_ELM_DRIVES 2
+#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
+/* RT_DFS_ELM_USE_ERASE is not set */
+#define RT_DFS_ELM_REENTRANT
+#define RT_USING_DFS_DEVFS
+/* RT_USING_DFS_NET is not set */
+/* RT_USING_DFS_ROMFS is not set */
+/* RT_USING_DFS_RAMFS is not set */
+/* RT_USING_DFS_UFFS is not set */
+/* RT_USING_DFS_JFFS2 is not set */
+/* RT_USING_DFS_NFS is not set */
+
+/* Device Drivers */
+
+#define RT_USING_DEVICE_IPC
+#define RT_USING_SERIAL
+/* RT_USING_CAN is not set */
+/* RT_USING_HWTIMER is not set */
+/* RT_USING_CPUTIME is not set */
+/* RT_USING_I2C is not set */
+#define RT_USING_PIN
+/* RT_USING_MTD_NOR is not set */
+/* RT_USING_MTD_NAND is not set */
+/* RT_USING_RTC is not set */
+/* RT_USING_SDIO is not set */
+/* RT_USING_SPI is not set */
+/* RT_USING_WDT is not set */
+/* RT_USING_WIFI is not set */
+
+/* Using USB */
+
+/* RT_USING_USB_HOST is not set */
+/* RT_USING_USB_DEVICE is not set */
+
+/* POSIX layer and C standard library */
+
+#define RT_USING_LIBC
+/* RT_USING_PTHREADS is not set */
+#define RT_USING_POSIX
+/* RT_USING_POSIX_MMAP is not set */
+/* RT_USING_POSIX_TERMIOS is not set */
+/* RT_USING_POSIX_AIO is not set */
+
+/* Network stack */
+
+/* light weight TCP/IP stack */
+
+/* RT_USING_LWIP is not set */
+
+/* Modbus master and slave stack */
+
+/* RT_USING_MODBUS is not set */
+
+/* RT-Thread UI Engine */
+
+/* RT_USING_GUIENGINE is not set */
+
+/* VBUS(Virtual Software BUS) */
+
+/* RT_USING_VBUS is not set */
+
+/* Utilities */
+
+/* RT_USING_LOGTRACE is not set */
+/* RT_USING_RYM is not set */
+
+/* RT-Thread online packages */
+
+/* system packages */
+
+/* PKG_USING_LWEXT4 is not set */
+/* PKG_USING_PARTITION is not set */
+/* PKG_USING_PERSIMMON is not set */
+/* PKG_USING_SQLITE is not set */
+/* PKG_USING_RTI is not set */
+
+/* IoT - internet of things */
+
+/* PKG_USING_PAHOMQTT is not set */
+/* PKG_USING_WEBCLIENT is not set */
+/* PKG_USING_MONGOOSE is not set */
+/* PKG_USING_WEBTERMINAL is not set */
+/* PKG_USING_CJSON is not set */
+/* PKG_USING_LJSON is not set */
+/* PKG_USING_EZXML is not set */
+/* PKG_USING_NANOPB is not set */
+/* PKG_USING_GAGENT_CLOUD is not set */
+
+/* Wi-Fi */
+
+/* Marvell WiFi */
+
+/* PKG_USING_WLANMARVELL is not set */
+
+/* Wiced WiFi */
+
+/* PKG_USING_WLAN_WICED is not set */
+/* PKG_USING_COAP is not set */
+/* PKG_USING_NOPOLL is not set */
+
+/* security packages */
+
+/* PKG_USING_MBEDTLS is not set */
+/* PKG_USING_libsodium is not set */
+/* PKG_USING_TINYCRYPT is not set */
+
+/* language packages */
+
+/* PKG_USING_JERRYSCRIPT is not set */
+/* PKG_USING_MICROPYTHON is not set */
+
+/* multimedia packages */
+
+/* PKG_USING_OPENMV is not set */
+
+/* tools packages */
+
+/* PKG_USING_CMBACKTRACE is not set */
+/* PKG_USING_EASYLOGGER is not set */
+/* PKG_USING_SYSTEMVIEW is not set */
+/* PKG_USING_IPERF is not set */
+
+/* miscellaneous packages */
+
+/* PKG_USING_FASTLZ is not set */
+/* PKG_USING_MINILZO is not set */
+
+/* example package: hello */
+
+/* PKG_USING_HELLO is not set */
+/* PKG_USING_MULTIBUTTON is not set */
+#define TINA_USING_UART0
+/* TINA_USING_UART1 is not set */
+#define TINA_USING_UART2
+#define RT_USING_CPU_FFS
+#define RT_MAIN_THREAD_STACK_SIZE 2048
+
+#endif
diff --git a/bsp/allwinner_tina/rtconfig.py b/bsp/allwinner_tina/rtconfig.py
new file mode 100644
index 0000000000..f3c4f699ab
--- /dev/null
+++ b/bsp/allwinner_tina/rtconfig.py
@@ -0,0 +1,58 @@
+import os
+
+# toolchains options
+ARCH ='arm'
+CPU ='R6'
+CROSS_TOOL ='gcc'
+
+if os.getenv('RTT_ROOT'):
+ RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+ RTT_ROOT = '../..'
+
+if os.getenv('RTT_CC'):
+ CROSS_TOOL = os.getenv('RTT_CC')
+
+if CROSS_TOOL == 'gcc':
+ PLATFORM = 'gcc'
+ EXEC_PATH = r'E:\work\env\tools\gnu_gcc\arm_gcc\mingw\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 = 'release'
+# BUILD = 'debug'
+
+if PLATFORM == 'gcc':
+ # toolchains
+ PREFIX = 'arm-none-eabi-'
+ 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'
+
+ DEVICE = ' -mcpu=arm926ej-s -ffunction-sections -fdata-sections'
+ CFLAGS = DEVICE + ' -Wall'
+ AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
+ LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds'
+ CPATH = ''
+ LPATH = ''
+
+ if BUILD == 'debug':
+ CFLAGS += ' -O0 -gdwarf-2'
+ AFLAGS += ' -gdwarf-2'
+ else:
+ CFLAGS += ' -O2'
+
+ CXXFLAGS = CFLAGS
+
+DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n'
+POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' \ No newline at end of file