From 9bf2a755e05d472435c8f90c161154d8480357b1 Mon Sep 17 00:00:00 2001 From: uestczyh222 Date: Thu, 8 Feb 2018 15:27:53 +0800 Subject: [PATCH] [Bsp][New BSP]New bsp for allwinner tina --- .travis.yml | 1 + bsp/allwinner_tina/.config | 265 ++++++++ bsp/allwinner_tina/Kconfig | 29 + bsp/allwinner_tina/README.md | 132 ++++ bsp/allwinner_tina/SConscript | 14 + bsp/allwinner_tina/SConstruct | 27 + bsp/allwinner_tina/applications/SConscript | 9 + bsp/allwinner_tina/applications/main.c | 36 ++ bsp/allwinner_tina/drivers/Kconfig | 16 + bsp/allwinner_tina/drivers/SConscript | 16 + bsp/allwinner_tina/drivers/board.c | 117 ++++ bsp/allwinner_tina/drivers/board.h | 38 ++ bsp/allwinner_tina/drivers/drv_clock.c | 527 ++++++++++++++++ bsp/allwinner_tina/drivers/drv_clock.h | 252 ++++++++ bsp/allwinner_tina/drivers/drv_gpio.c | 564 ++++++++++++++++++ bsp/allwinner_tina/drivers/drv_gpio.h | 244 ++++++++ bsp/allwinner_tina/drivers/drv_uart.c | 324 ++++++++++ bsp/allwinner_tina/drivers/drv_uart.h | 83 +++ bsp/allwinner_tina/libcpu/SConscript | 13 + bsp/allwinner_tina/libcpu/context_gcc.S | 92 +++ bsp/allwinner_tina/libcpu/cpu.c | 41 ++ bsp/allwinner_tina/libcpu/cpuport.c | 229 +++++++ bsp/allwinner_tina/libcpu/interrupt.c | 206 +++++++ bsp/allwinner_tina/libcpu/interrupt.h | 107 ++++ bsp/allwinner_tina/libcpu/mmu.c | 457 ++++++++++++++ bsp/allwinner_tina/libcpu/mmu.h | 65 ++ bsp/allwinner_tina/libcpu/rt_low_level_init.c | 81 +++ bsp/allwinner_tina/libcpu/stack.c | 81 +++ bsp/allwinner_tina/libcpu/start_gcc.S | 346 +++++++++++ bsp/allwinner_tina/libcpu/trap.c | 223 +++++++ bsp/allwinner_tina/link.lds | 148 +++++ bsp/allwinner_tina/rtconfig.h | 235 ++++++++ bsp/allwinner_tina/rtconfig.py | 58 ++ 33 files changed, 5076 insertions(+) create mode 100644 bsp/allwinner_tina/.config create mode 100644 bsp/allwinner_tina/Kconfig create mode 100644 bsp/allwinner_tina/README.md create mode 100644 bsp/allwinner_tina/SConscript create mode 100644 bsp/allwinner_tina/SConstruct create mode 100644 bsp/allwinner_tina/applications/SConscript create mode 100644 bsp/allwinner_tina/applications/main.c create mode 100644 bsp/allwinner_tina/drivers/Kconfig create mode 100644 bsp/allwinner_tina/drivers/SConscript create mode 100644 bsp/allwinner_tina/drivers/board.c create mode 100644 bsp/allwinner_tina/drivers/board.h create mode 100644 bsp/allwinner_tina/drivers/drv_clock.c create mode 100644 bsp/allwinner_tina/drivers/drv_clock.h create mode 100644 bsp/allwinner_tina/drivers/drv_gpio.c create mode 100644 bsp/allwinner_tina/drivers/drv_gpio.h create mode 100644 bsp/allwinner_tina/drivers/drv_uart.c create mode 100644 bsp/allwinner_tina/drivers/drv_uart.h create mode 100644 bsp/allwinner_tina/libcpu/SConscript create mode 100644 bsp/allwinner_tina/libcpu/context_gcc.S create mode 100644 bsp/allwinner_tina/libcpu/cpu.c create mode 100644 bsp/allwinner_tina/libcpu/cpuport.c create mode 100644 bsp/allwinner_tina/libcpu/interrupt.c create mode 100644 bsp/allwinner_tina/libcpu/interrupt.h create mode 100644 bsp/allwinner_tina/libcpu/mmu.c create mode 100644 bsp/allwinner_tina/libcpu/mmu.h create mode 100644 bsp/allwinner_tina/libcpu/rt_low_level_init.c create mode 100644 bsp/allwinner_tina/libcpu/stack.c create mode 100644 bsp/allwinner_tina/libcpu/start_gcc.S create mode 100644 bsp/allwinner_tina/libcpu/trap.c create mode 100644 bsp/allwinner_tina/link.lds create mode 100644 bsp/allwinner_tina/rtconfig.h create mode 100644 bsp/allwinner_tina/rtconfig.py diff --git a/.travis.yml b/.travis.yml index d7589e23a..fbcb1241f 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 000000000..0d06a6d22 --- /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 000000000..fd1b6f9ab --- /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 000000000..82616e1f5 --- /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] < [lymz@foxmail.com][5] > + + + [1]: https://www.rt-thread.org/page/download.html + [4]: https://github.com/uestczyh222 + [5]: mailto:lymz@foxmail.com diff --git a/bsp/allwinner_tina/SConscript b/bsp/allwinner_tina/SConscript new file mode 100644 index 000000000..c7ef7659e --- /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 000000000..f0c508ba6 --- /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 000000000..e1255c80c --- /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 000000000..7aaf1f8db --- /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 000000000..b7efb5de2 --- /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 000000000..d42736afe --- /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 000000000..e3b54b353 --- /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 +#include + +#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 000000000..11c6a9a15 --- /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 + +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 000000000..8c8431b91 --- /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 +#include + +#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 000000000..4818d06dc --- /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 000000000..ba31cca0e --- /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 +#include + +#include "drv_gpio.h" +#include "interrupt.h" + +#define DBG_ENABLE +#define DBG_SECTION_NAME "[GPIO]" +#define DBG_LEVEL DBG_WARNING +#define DBG_COLOR +#include + + +#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 + +#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 000000000..35d368f1c --- /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 000000000..1c48c53dc --- /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 +#include +#include + +#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 000000000..a4e648ffa --- /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 000000000..aa13c2b17 --- /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 000000000..5152618d2 --- /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 000000000..23953dea4 --- /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 +#include + +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 000000000..5def9905f --- /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 +#include + +#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 000000000..af9b054da --- /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 +#include + +#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 000000000..5389f0655 --- /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 000000000..177668a23 --- /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 000000000..b73f59c28 --- /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 + +#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 000000000..807b9b203 --- /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 000000000..8f4c218ee --- /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 + +/*****************************/ +/* 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 000000000..94c985a37 --- /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 000000000..84bb3e7f8 --- /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 +#include + +#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 000000000..eb974dea0 --- /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 000000000..ea0bbf8de --- /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 000000000..f3c4f699a --- /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