[Bsp][New BSP]New bsp for allwinner tina
This commit is contained in:
parent
174787ce69
commit
9bf2a755e0
|
@ -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'
|
||||
|
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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')
|
|
@ -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)
|
|
@ -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')
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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')
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* File : board.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-5-30 Bernard the first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_uart.h"
|
||||
#include "interrupt.h"
|
||||
#include "mmu.h"
|
||||
|
||||
static void os_clock_irq_handle(int irqno, void *param)
|
||||
{
|
||||
volatile rt_uint32_t *temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x04);
|
||||
|
||||
/* clear timer */
|
||||
*temp_addr |= 0x01;
|
||||
|
||||
rt_tick_increase();
|
||||
}
|
||||
|
||||
static void mmu_init(void)
|
||||
{
|
||||
struct mem_desc r6_mem_desc[] =
|
||||
{
|
||||
{ 0x00000000, 0xFFFFFFFF, 0x00000000, RW_NCNB }, /* None cached for 4G memory */
|
||||
{ 0x80000000, 0x82000000 - 1, 0x80000000, RW_CB }, /* 32M cached SDRAM memory */
|
||||
//{ 0x00000000, 0x00001000-1, 0x80000000, RW_CB }, /* isr vector table */
|
||||
//here not set mmu
|
||||
//start_gcc.S Copy vector to the correct address
|
||||
};
|
||||
|
||||
rt_hw_mmu_init(r6_mem_desc, sizeof(r6_mem_desc) / sizeof(r6_mem_desc[0]));
|
||||
}
|
||||
|
||||
static void os_clock_init(void)
|
||||
{
|
||||
rt_uint32_t temp;
|
||||
volatile rt_uint32_t *temp_addr;
|
||||
|
||||
/* reload value */
|
||||
temp = 0xB71B00 / RT_TICK_PER_SECOND;
|
||||
temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x14);
|
||||
*temp_addr = temp;
|
||||
|
||||
/* continuous | /2 | 24Mhz | reload*/
|
||||
temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1);
|
||||
temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x10);
|
||||
*temp_addr &= 0xffffff00;
|
||||
*temp_addr |= temp;
|
||||
|
||||
/* open timer irq */
|
||||
temp = 0x01 << 0;
|
||||
temp_addr = (rt_uint32_t *)(0x01C20C00);
|
||||
*temp_addr |= temp;
|
||||
|
||||
/* set init value */
|
||||
temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x18);
|
||||
*temp_addr = 0;
|
||||
|
||||
/* begin run timer */
|
||||
temp = 0x01 << 0;
|
||||
temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x10);
|
||||
*temp_addr |= temp;
|
||||
|
||||
temp_addr = (rt_uint32_t *)(0x01C20C00);
|
||||
/* set irq handle */
|
||||
rt_hw_interrupt_install(TIMER0_INTERRUPT, os_clock_irq_handle, (void *)temp_addr, "timer");
|
||||
rt_hw_interrupt_umask(TIMER0_INTERRUPT);
|
||||
|
||||
}
|
||||
|
||||
void rt_hw_board_init(void)
|
||||
{
|
||||
mmu_init();
|
||||
|
||||
rt_hw_interrupt_init();
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
/* init memory system */
|
||||
rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
|
||||
#endif
|
||||
/* init hardware interrupt */
|
||||
rt_hw_uart_init();
|
||||
|
||||
#ifdef RT_USING_CONSOLE
|
||||
/* set console device */
|
||||
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
#endif /* RT_USING_CONSOLE */
|
||||
|
||||
os_clock_init();
|
||||
|
||||
#ifdef RT_USING_COMPONENTS_INIT
|
||||
rt_components_board_init();
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* File : board.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-5-30 Bernard the first version
|
||||
*/
|
||||
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern unsigned char __bss_start;
|
||||
extern unsigned char __bss_end;
|
||||
|
||||
#define RT_HW_HEAP_BEGIN (void*)&__bss_end
|
||||
#define RT_HW_HEAP_END (void*)(0x80000000 + 32 * 1024 * 1024)
|
||||
|
||||
void rt_hw_board_init(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,527 @@
|
|||
/*
|
||||
* File : drv_clock.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 RT-Thread the first version
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#include "drv_clock.h"
|
||||
|
||||
int cpu_get_pll_clk(void)
|
||||
{
|
||||
rt_uint32_t reg;
|
||||
int n, k, m, p;
|
||||
|
||||
reg = CCU->pll_cpu_ctrl;
|
||||
if (!(reg & (0x01 << 31)))
|
||||
return 0;
|
||||
|
||||
p = PLL_CPU_DIV_P(reg) + 1;
|
||||
n = PLL_CPU_FACTOR_N(reg) + 1;
|
||||
k = PLL_CPU_FACTOR_K(reg) + 1;
|
||||
m = PLL_CPU_FACTOR_M(reg) + 1;
|
||||
//(24MHz*n*k)/(m*p)
|
||||
return (_24MHZ_ * n * k) / (m * p);
|
||||
}
|
||||
|
||||
int audio_get_pll_clk(void)
|
||||
{
|
||||
rt_uint32_t reg;
|
||||
unsigned char n, m;
|
||||
|
||||
reg = CCU->pll_audio_ctrl;
|
||||
if (!(reg & (0x01 << 31)))
|
||||
return 0;
|
||||
|
||||
n = PLL_AUDIO_FACTOR_N(reg) + 1;
|
||||
m = PLL_AUDIO_PREDIV_M(reg) + 1;
|
||||
|
||||
//24MHz*n*2/m
|
||||
return _24MHZ_ * 2 * n / m;
|
||||
}
|
||||
|
||||
int video_get_pll_clk(void)
|
||||
{
|
||||
rt_uint32_t reg;
|
||||
int n, m;
|
||||
|
||||
reg = CCU->pll_video_ctrl;
|
||||
if (!(reg & (0x01 << 31)))
|
||||
return 0;
|
||||
|
||||
if (reg & PLL_VIDEO_MODE_SEL)
|
||||
{
|
||||
//(24MHz*n)/m
|
||||
n = PLL_VIDEO_FACTOR_N(reg) + 1;
|
||||
m = PLL_VIDEO_PREDIV_M(reg) + 1;
|
||||
return (_24MHZ_ * n) / m;
|
||||
}
|
||||
|
||||
if (reg & PLL_VIDEO_FRAC_CLK_OUT)
|
||||
return 270000000;
|
||||
else
|
||||
return 297000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ve_get_pll_clk(void)
|
||||
{
|
||||
rt_uint32_t reg;
|
||||
int n, m;
|
||||
|
||||
reg = CCU->pll_ve_ctrl;
|
||||
if (!(reg & (0x01 << 31)))
|
||||
return 0;
|
||||
|
||||
if (reg & PLL_VE_MODE_SEL)
|
||||
{
|
||||
//(24MHz*n)/m
|
||||
n = PLL_VE_FACTOR_N(reg) + 1;
|
||||
m = PLL_VE_PREDIV_M(reg) + 1;
|
||||
|
||||
return (_24MHZ_ * n) / m;
|
||||
}
|
||||
|
||||
if (reg & PLL_VE_FRAC_CLK_OUT)
|
||||
return 297000000;
|
||||
else
|
||||
return 270000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ddr_get_pll_clk(void)
|
||||
{
|
||||
rt_uint32_t reg;
|
||||
int n, k, m;
|
||||
|
||||
reg = CCU->pll_ddr_ctrl;
|
||||
if (!(reg & (0x01 << 31)))
|
||||
return 0;
|
||||
|
||||
n = PLL_DDR_FACTOR_N(reg) + 1;
|
||||
k = PLL_DDR_FACTOR_K(reg) + 1;
|
||||
m = PLL_DDR_FACTOR_M(reg) + 1;
|
||||
|
||||
//(24MHz*n*k)/m
|
||||
return (_24MHZ_ * n * k) / m;
|
||||
}
|
||||
|
||||
int periph_get_pll_clk(void)
|
||||
{
|
||||
rt_uint32_t reg;
|
||||
int n, k;
|
||||
|
||||
reg = CCU->pll_periph_ctrl;
|
||||
if (!(reg & (0x01 << 31)))
|
||||
return 0;
|
||||
|
||||
n = PLL_PERIPH_FACTOR_N(reg) + 1;
|
||||
k = PLL_PERIPH_FACTOR_K(reg) + 1;
|
||||
|
||||
return _24MHZ_ * n * k;
|
||||
}
|
||||
|
||||
static int cpu_get_clk_src(void)
|
||||
{
|
||||
return (CCU->cpu_clk_src >> 16) & 0x3;
|
||||
}
|
||||
|
||||
int cpu_get_clk(void)
|
||||
{
|
||||
rt_uint32_t reg;
|
||||
int cpusrc;
|
||||
|
||||
reg = CCU->ahb_apb_hclkc_cfg;
|
||||
cpusrc = cpu_get_clk_src();
|
||||
|
||||
if (cpusrc == CLK_PLL_SRC)
|
||||
return (cpu_get_pll_clk() / (HCLKC_DIV(reg) + 1));
|
||||
else if (cpusrc == CLK_OSC24M_SRC)
|
||||
return _24MHZ_ / (HCLKC_DIV(reg) + 1);
|
||||
else
|
||||
return _32KHZ_ / (HCLKC_DIV(reg) + 1); //猜测 内部32KHz时钟
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ahb_get_clk(void)
|
||||
{
|
||||
rt_uint32_t reg;
|
||||
int sel, spd;
|
||||
|
||||
reg = CCU->ahb_apb_hclkc_cfg;
|
||||
sel = AHB_SRC_SEL(reg);
|
||||
|
||||
if (sel == CLK_PLL_SRC)
|
||||
{
|
||||
spd = cpu_get_clk();
|
||||
return spd / (1 << AHB_CLK_DIV(reg));
|
||||
}
|
||||
else if (sel == PRE_DIV_SRC)
|
||||
{
|
||||
spd = periph_get_pll_clk();
|
||||
return spd / (AHB_PRE_DIV(reg) + 1) / (1 << AHB_CLK_DIV(reg));
|
||||
}
|
||||
else if (sel == CLK_OSC24M_SRC)
|
||||
return _24MHZ_ / (1 << AHB_CLK_DIV(reg));
|
||||
else
|
||||
return _32KHZ_ / (1 << AHB_CLK_DIV(reg));
|
||||
}
|
||||
|
||||
int apb_get_clk(void)
|
||||
{
|
||||
rt_uint32_t reg;
|
||||
int spd;
|
||||
|
||||
reg = CCU->ahb_apb_hclkc_cfg;
|
||||
spd = ahb_get_clk();
|
||||
// 0x:/2 10:/4 11:/8
|
||||
if (!(APH_CLK_PATIO(reg) & 0x1))
|
||||
return spd / 2;
|
||||
else
|
||||
return spd / (1 << APH_CLK_PATIO(reg));
|
||||
}
|
||||
|
||||
|
||||
static rt_err_t wait_pll_stable(rt_uint32_t base)
|
||||
{
|
||||
rt_uint32_t rval = 0;
|
||||
volatile int time = 0xfff;
|
||||
|
||||
do
|
||||
{
|
||||
rval = *((volatile rt_uint32_t *)base);
|
||||
time--;
|
||||
}
|
||||
while (time && !(rval & (1 << 28)));
|
||||
|
||||
return !time;
|
||||
}
|
||||
|
||||
rt_err_t cpu_set_pll_clk(int clk)
|
||||
{
|
||||
rt_uint32_t cpu_src;
|
||||
int p = 0, k = 1, m = 1, n = 0;
|
||||
|
||||
if (clk == 0)
|
||||
return RT_EINVAL;
|
||||
|
||||
if (clk > 1152000000)
|
||||
{
|
||||
k = 2;
|
||||
}
|
||||
else if (clk > 768000000)
|
||||
{
|
||||
k = 3;
|
||||
m = 2;
|
||||
}
|
||||
|
||||
n = clk / (_24MHZ_ * k / m) - 1;
|
||||
cpu_src = (CCU->cpu_clk_src >> 16) & 0x3;
|
||||
CCU->cpu_clk_src = CLK_OSC24M_SRC << 16;
|
||||
CCU->pll_cpu_ctrl &= ~(0x1 << 31);
|
||||
//PLL1 rate = ((24000000 * n * k) >> 0) / m (p is ignored)
|
||||
CCU->pll_cpu_ctrl = (0x1 << 31) | (m << 0) | (k << 4) | (n << 8) | (p << 16);
|
||||
if (wait_pll_stable((rt_uint32_t)(&CCU->pll_cpu_ctrl)))
|
||||
return RT_ERROR;
|
||||
|
||||
CCU->cpu_clk_src = cpu_src << 16;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t audio_set_pll_clk(int clk)
|
||||
{
|
||||
int n = 0, m = 0;
|
||||
int n_temp = clk;
|
||||
int m_temp = _24MHZ_ * 2;
|
||||
|
||||
if ((clk > 200000000) || (clk < 20000000))
|
||||
return RT_EINVAL;
|
||||
|
||||
if (clk == 0)
|
||||
{
|
||||
CCU->pll_audio_ctrl &= ~(0x1 << 31);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
while (n_temp != m_temp)
|
||||
{
|
||||
if (n_temp > m_temp)
|
||||
{
|
||||
n_temp = n_temp - m_temp;
|
||||
}
|
||||
else if (m_temp > n_temp)
|
||||
{
|
||||
m_temp = m_temp - n_temp;
|
||||
}
|
||||
}
|
||||
|
||||
n = clk / n_temp;
|
||||
m = _24MHZ_ * 2 / m_temp;
|
||||
if ((n > 128) || (m > 32) || (clk != (_24MHZ_ * n * 2) / m))
|
||||
return RT_ERROR;
|
||||
|
||||
CCU->pll_audio_ctrl &= ~(0x1 << 31);
|
||||
n = (n - 1) & 0x7f;
|
||||
m = (m - 1) & 0x1f;
|
||||
//clk = (24 * n * 2) / m
|
||||
CCU->pll_audio_ctrl = (0x1 << 31) | (0x0 << 24) | (n << 8) | m;
|
||||
|
||||
if (wait_pll_stable((rt_uint32_t)(&CCU->pll_audio_ctrl)))
|
||||
return RT_ERROR;
|
||||
else
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t video_set_pll_clk(int clk)
|
||||
{
|
||||
int n = 0, m = 0;
|
||||
int n_temp = clk;
|
||||
int m_temp = _24MHZ_;
|
||||
|
||||
if ((clk > 600000000) || (clk < 30000000))
|
||||
return RT_EINVAL;
|
||||
|
||||
if (clk == 0)
|
||||
{
|
||||
CCU->pll_video_ctrl &= ~(0x1 << 31);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
while (n_temp != m_temp)
|
||||
{
|
||||
if (n_temp > m_temp)
|
||||
{
|
||||
n_temp = n_temp - m_temp;
|
||||
}
|
||||
else if (m_temp > n_temp)
|
||||
{
|
||||
m_temp = m_temp - n_temp;
|
||||
}
|
||||
}
|
||||
|
||||
n = clk / n_temp;
|
||||
m = _24MHZ_ / m_temp;
|
||||
|
||||
if ((n > 128) || (m > 16) || (clk != (_24MHZ_ * n) / m))
|
||||
return RT_ERROR;
|
||||
|
||||
CCU->pll_video_ctrl &= ~(0x1 << 31);
|
||||
n = (n - 1) & 0x7f;
|
||||
m = (m - 1) & 0xf;
|
||||
//speed = (24*n)/m
|
||||
CCU->pll_video_ctrl = (0x1 << 31) | (0x0 << 30) | (0x1 << 24) | (n << 8) | m;
|
||||
|
||||
if (wait_pll_stable((rt_uint32_t)(&CCU->pll_video_ctrl)))
|
||||
return RT_ERROR;
|
||||
else
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t ve_set_pll_clk(int clk)
|
||||
{
|
||||
int n = 0, m = 0;
|
||||
int n_temp = clk;
|
||||
int m_temp = _24MHZ_;
|
||||
|
||||
if ((clk > 600000000) || (clk < 30000000))
|
||||
return RT_EINVAL;
|
||||
|
||||
if (clk == 0)
|
||||
{
|
||||
CCU->pll_ve_ctrl &= ~(0x1 << 31);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
while (n_temp != m_temp)
|
||||
{
|
||||
if (n_temp > m_temp)
|
||||
{
|
||||
n_temp = n_temp - m_temp;
|
||||
}
|
||||
else if (m_temp > n_temp)
|
||||
{
|
||||
m_temp = m_temp - n_temp;
|
||||
}
|
||||
}
|
||||
|
||||
n = clk / n_temp;
|
||||
m = _24MHZ_ / m_temp;
|
||||
|
||||
if ((n > 128) || (m > 16) || (clk != (_24MHZ_ * n) / m))
|
||||
return RT_ERROR;
|
||||
|
||||
CCU->pll_ve_ctrl &= ~(0x1 << 31);
|
||||
n = (n - 1) & 0x7f;
|
||||
m = (m - 1) & 0xf;
|
||||
//clk = (24 * n) / m
|
||||
CCU->pll_ve_ctrl = (0x1 << 31) | (0x1 << 24) | (n << 8) | m;
|
||||
if (wait_pll_stable((rt_uint32_t)(&CCU->pll_ve_ctrl)))
|
||||
return RT_ERROR;
|
||||
else
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t periph_set_pll_clk(int clk)
|
||||
{
|
||||
rt_uint32_t clk_src;
|
||||
rt_uint32_t temp_data;
|
||||
int n = 0, k = 0;
|
||||
|
||||
if ((clk > 1800000000) || (clk < 200000000) || (clk == 0) || (clk % _24MHZ_ != 0))
|
||||
return RT_EINVAL;
|
||||
|
||||
n = clk / _24MHZ_;
|
||||
|
||||
for (k = 2; ((n > 32) || (k < 5)); k++)
|
||||
{
|
||||
if ((n % k) != 0)
|
||||
n /= k;
|
||||
}
|
||||
|
||||
if ((n > 32) || (k > 4) || (clk != (_24MHZ_ * n * k)))
|
||||
return RT_ERROR;
|
||||
temp_data = CCU->ahb_apb_hclkc_cfg;
|
||||
clk_src = (temp_data >> 12) & 0x3;
|
||||
temp_data &= ~(0x3 << 12);
|
||||
temp_data |= (CLK_PLL_SRC << 12);
|
||||
CCU->ahb_apb_hclkc_cfg = temp_data;
|
||||
CCU->pll_periph_ctrl &= ~(0x1 << 31);
|
||||
n = (n - 1) & 0x1f;
|
||||
k = (k - 1) & 0x3;
|
||||
//clk = 24 * n *k
|
||||
CCU->pll_periph_ctrl = (0x1 << 31) | (0x1 << 18) | (n << 8) | (k << 4) || (0x1);
|
||||
if (wait_pll_stable((rt_uint32_t)(&CCU->pll_periph_ctrl)))
|
||||
return RT_ERROR;
|
||||
|
||||
temp_data = CCU->ahb_apb_hclkc_cfg;
|
||||
temp_data &= ~(0x3 << 12);
|
||||
temp_data |= (clk_src << 12);
|
||||
CCU->ahb_apb_hclkc_cfg = temp_data;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t cpu_set_clk(int clk)
|
||||
{
|
||||
if (clk < _24MHZ_)
|
||||
return RT_EINVAL;
|
||||
|
||||
if (clk == cpu_get_clk())
|
||||
return RT_EOK;
|
||||
|
||||
CCU->cpu_clk_src = CLK_OSC24M_SRC << 16;
|
||||
if (clk == _24MHZ_)
|
||||
return RT_EOK;
|
||||
|
||||
if (cpu_set_pll_clk(clk))
|
||||
return RT_ERROR;
|
||||
|
||||
CCU->ahb_apb_hclkc_cfg &= ~(0x3 << 16);
|
||||
CCU->cpu_clk_src = CLK_PLL_SRC << 16;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t bus_gate_clk_enalbe(enum bus_gate bus)
|
||||
{
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t gate_reg;
|
||||
|
||||
offset = bus & 0xfff;
|
||||
gate_reg = bus >> BUS_GATE_OFFSET_BIT;
|
||||
|
||||
if (gate_reg == 0x00)
|
||||
CCU->bus_clk_gating0 |= (0x1 << offset);
|
||||
else if (gate_reg == 0x01)
|
||||
CCU->bus_clk_gating1 |= (0x1 << offset);
|
||||
else if (gate_reg == 0x02)
|
||||
CCU->bus_clk_gating2 |= (0x1 << offset);
|
||||
else
|
||||
return RT_EINVAL;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t bus_gate_clk_disalbe(enum bus_gate bus)
|
||||
{
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t gate_reg;
|
||||
|
||||
offset = bus & 0xfff;
|
||||
gate_reg = bus >> BUS_GATE_OFFSET_BIT;
|
||||
|
||||
if (gate_reg == 0x00)
|
||||
CCU->bus_clk_gating0 &= ~(0x1 << offset);
|
||||
else if (gate_reg == 0x01)
|
||||
CCU->bus_clk_gating1 &= ~(0x1 << offset);
|
||||
else if (gate_reg == 0x02)
|
||||
CCU->bus_clk_gating2 &= ~(0x1 << offset);
|
||||
else
|
||||
return RT_EINVAL;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t bus_software_reset_enalbe(enum bus_gate bus)
|
||||
{
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t gate_reg;
|
||||
|
||||
offset = bus & 0xfff;
|
||||
gate_reg = bus >> BUS_GATE_OFFSET_BIT;
|
||||
|
||||
if (gate_reg == 0x00)
|
||||
CCU->bus_soft_rst0 |= (0x1 << offset);
|
||||
else if (gate_reg == 0x01)
|
||||
CCU->bus_soft_rst1 |= (0x1 << offset);
|
||||
else if (gate_reg == 0x02)
|
||||
CCU->bus_soft_rst2 |= (0x1 << offset);
|
||||
else
|
||||
return RT_EINVAL;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t bus_software_reset_disalbe(enum bus_gate bus)
|
||||
{
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t gate_reg;
|
||||
|
||||
offset = bus & 0xfff;
|
||||
gate_reg = bus >> BUS_GATE_OFFSET_BIT;
|
||||
|
||||
if (gate_reg == 0x00)
|
||||
CCU->bus_soft_rst0 &= ~(0x1 << offset);
|
||||
else if (gate_reg == 0x01)
|
||||
CCU->bus_soft_rst1 &= ~(0x1 << offset);
|
||||
else if (gate_reg == 0x02)
|
||||
CCU->bus_soft_rst2 &= ~(0x1 << offset);
|
||||
else
|
||||
return RT_EINVAL;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -0,0 +1,564 @@
|
|||
/*
|
||||
* File : drv_gpio.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 RT-Thread the first version
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#include "drv_gpio.h"
|
||||
#include "interrupt.h"
|
||||
|
||||
#define DBG_ENABLE
|
||||
#define DBG_SECTION_NAME "[GPIO]"
|
||||
#define DBG_LEVEL DBG_WARNING
|
||||
#define DBG_COLOR
|
||||
#include <rtdbg.h>
|
||||
|
||||
|
||||
#define readl(addr) (*(volatile unsigned int *)(addr))
|
||||
#define writel(value,addr) (*(volatile unsigned int *)(addr) = (value))
|
||||
|
||||
// Todo: add RT_ASSERT.
|
||||
|
||||
/*********************************************************
|
||||
** IO
|
||||
*********************************************************/
|
||||
int gpio_set_func(enum gpio_port port, enum gpio_pin pin, rt_uint8_t func)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
if (func & 0x8)
|
||||
{
|
||||
dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
|
||||
return RT_EINVAL;
|
||||
}
|
||||
|
||||
addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
|
||||
offset = (pin % 8) * 4;
|
||||
|
||||
data = readl(addr);
|
||||
data &= ~(0x7 << offset);
|
||||
data |= func << offset;
|
||||
writel(data, addr);
|
||||
|
||||
dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int gpio_set_value(enum gpio_port port, enum gpio_pin pin, rt_uint8_t value)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
if (value & 0xE)
|
||||
{
|
||||
dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
|
||||
return RT_EINVAL;
|
||||
}
|
||||
|
||||
addr = GPIOn_DATA_ADDR(port);
|
||||
offset = pin;
|
||||
|
||||
data = readl(addr);
|
||||
data &= ~(0x1 << offset);
|
||||
data |= value << offset;
|
||||
writel(data, addr);
|
||||
|
||||
dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int gpio_get_value(enum gpio_port port, enum gpio_pin pin)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
addr = GPIOn_DATA_ADDR(port);
|
||||
offset = pin;
|
||||
|
||||
data = readl(addr);
|
||||
|
||||
dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
|
||||
return (data >> offset) & 0x01;
|
||||
}
|
||||
|
||||
int gpio_set_pull_mode(enum gpio_port port, enum gpio_pin pin, enum gpio_pull pull)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
if (pull & 0xC)
|
||||
{
|
||||
dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
|
||||
return RT_EINVAL;
|
||||
}
|
||||
|
||||
addr = GPIOn_PUL_ADDR(port);
|
||||
addr += pin > GPIO_PIN_15 ? 0x4 : 0x0;
|
||||
offset = (pin & 0xf) << 1;
|
||||
|
||||
data = readl(addr);
|
||||
data &= ~(0x3 << offset);
|
||||
data |= pull << offset;
|
||||
writel(data, addr);
|
||||
|
||||
dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
int gpio_set_drive_level(enum gpio_port port, enum gpio_pin pin, enum gpio_drv_level level)
|
||||
{
|
||||
volatile rt_uint32_t addr;
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
if (level & 0xC)
|
||||
{
|
||||
dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
|
||||
return RT_EINVAL;
|
||||
}
|
||||
|
||||
addr = GPIOn_DRV_ADDR(port);
|
||||
addr += pin > GPIO_PIN_15 ? 0x4 : 0x0;
|
||||
offset = (pin & 0xf) << 1;
|
||||
|
||||
data = readl(addr);
|
||||
data &= ~(0x3 << offset);
|
||||
data |= level << offset;
|
||||
writel(data, addr);
|
||||
|
||||
dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
void gpio_direction_input(enum gpio_port port, enum gpio_pin pin)
|
||||
{
|
||||
volatile rt_uint32_t addr;
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
|
||||
offset = (pin % 8) * 4;
|
||||
|
||||
data = readl(addr);
|
||||
data &= ~(0x7 << offset);
|
||||
data |= IO_INPUT << offset;
|
||||
writel(data, addr);
|
||||
|
||||
dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
|
||||
}
|
||||
|
||||
void gpio_direction_output(enum gpio_port port, enum gpio_pin pin, int value)
|
||||
{
|
||||
volatile rt_uint32_t addr;
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
gpio_set_value(port, pin, value);
|
||||
addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
|
||||
offset = (pin % 8) * 4;
|
||||
|
||||
data = readl(addr);
|
||||
data &= ~(0x7 << offset);
|
||||
data |= IO_OUTPUT << offset;
|
||||
writel(data, addr);
|
||||
|
||||
dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
|
||||
}
|
||||
/*********************************************************
|
||||
** IRQ
|
||||
*********************************************************/
|
||||
static void gpio_ack_irq(enum gpio_port port, enum gpio_pin pin)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
rt_uint32_t data;
|
||||
|
||||
addr = GPIOn_INT_STA_ADDR(port);
|
||||
data = readl(addr);
|
||||
data |= 0x1 << pin;
|
||||
writel(data, addr);
|
||||
}
|
||||
|
||||
void gpio_select_irq_clock(enum gpio_port port, enum gpio_irq_clock clock)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
|
||||
|
||||
addr = GPIOn_INT_DEB_ADDR(port - GPIO_PORT_D);
|
||||
|
||||
data = readl(addr);
|
||||
data &= ~0x01;
|
||||
data |= clock;
|
||||
writel(data, addr);
|
||||
dbg_log(DBG_LOG, "[line]:%d addr:%08x data:%08x\n", __LINE__, addr, *((rt_uint32_t *)addr));
|
||||
}
|
||||
|
||||
void gpio_set_debounce(enum gpio_port port, enum gpio_direction_type prescaler)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
|
||||
|
||||
addr = GPIOn_INT_DEB_ADDR(port - GPIO_PORT_D);
|
||||
|
||||
data = readl(addr);
|
||||
data &= ~(0x07 << 4);
|
||||
data |= prescaler << 4;
|
||||
writel(data, addr);
|
||||
dbg_log(DBG_LOG, "[line]:%d addr:%08x data:%08x\n", __LINE__, addr, *((rt_uint32_t *)addr));
|
||||
}
|
||||
|
||||
void gpio_irq_enable(enum gpio_port port, enum gpio_pin pin)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
addr = GPIOn_INT_CTRL_ADDR(port - GPIO_PORT_D);
|
||||
offset = pin;
|
||||
|
||||
data = readl(addr);
|
||||
data |= 0x1 << offset;
|
||||
writel(data, addr);
|
||||
gpio_select_irq_clock(port, GPIO_IRQ_HOSC_24MHZ);
|
||||
dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
|
||||
}
|
||||
|
||||
void gpio_irq_disable(enum gpio_port port, enum gpio_pin pin)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
gpio_ack_irq(port - GPIO_PORT_D, pin);
|
||||
addr = GPIOn_INT_CTRL_ADDR(port - GPIO_PORT_D);
|
||||
offset = pin;
|
||||
|
||||
data = readl(addr);
|
||||
data &= ~(0x1 << offset);
|
||||
|
||||
writel(data, addr);
|
||||
dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
|
||||
}
|
||||
|
||||
void gpio_set_irq_type(enum gpio_port port, enum gpio_pin pin, enum gpio_irq_type irq_type)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
rt_uint32_t offset;
|
||||
rt_uint32_t data;
|
||||
|
||||
RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
addr = GPIOn_INT_CFG_ADDR(port - GPIO_PORT_D) + (pin / 8) * 4;
|
||||
offset = (pin % 8) * 4;
|
||||
|
||||
data = readl(addr);
|
||||
data &= ~(0x7 << offset);
|
||||
data |= irq_type << offset;
|
||||
writel(data, addr);
|
||||
|
||||
dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
|
||||
}
|
||||
|
||||
static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_PORT_NUM];
|
||||
|
||||
void gpio_set_irq_callback(enum gpio_port port, enum gpio_pin pin, void (*irq_cb)(void *), void *irq_arg)
|
||||
{
|
||||
RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
|
||||
RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
|
||||
|
||||
_g_gpio_irq_tbl[port].irq_cb[pin] = irq_cb;
|
||||
_g_gpio_irq_tbl[port].irq_arg[pin] = irq_arg;
|
||||
}
|
||||
|
||||
void gpio_clear_irq_callback(enum gpio_port port, enum gpio_pin pin)
|
||||
{
|
||||
gpio_irq_disable(port, pin);
|
||||
|
||||
_g_gpio_irq_tbl[port].irq_cb[pin] = RT_NULL;
|
||||
_g_gpio_irq_tbl[port].irq_arg[pin] = RT_NULL;
|
||||
}
|
||||
|
||||
static void gpio_irq_handler(int irq, void *param)
|
||||
{
|
||||
struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param;
|
||||
rt_uint32_t pend, enable;
|
||||
int port, pin;
|
||||
rt_uint32_t addr;
|
||||
|
||||
pin = 0;
|
||||
port = irq - PIOD_INTERRUPT;
|
||||
addr = GPIOn_INT_STA_ADDR(port);
|
||||
pend = readl(addr);
|
||||
addr = GPIOn_INT_CTRL_ADDR(port);
|
||||
enable = readl(addr);
|
||||
pend &= enable;
|
||||
|
||||
while (pend)
|
||||
{
|
||||
if ((pend & 0x1) && (irq_def->irq_cb[pin] != RT_NULL))
|
||||
{
|
||||
dbg_log(DBG_LOG, "do irq callback...\n", port, pin);
|
||||
irq_def->irq_cb[pin](irq_def->irq_arg[pin]);
|
||||
}
|
||||
pin++;
|
||||
pend = pend >> 1;
|
||||
gpio_ack_irq(port, pin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef RT_USING_PIN
|
||||
#include <rtdevice.h>
|
||||
|
||||
#define PIN_MAGIC (0x5A)
|
||||
#define PIN_NUM(_N) (sizeof(_N) / sizeof(_N[0]))
|
||||
|
||||
struct _pin_index
|
||||
{
|
||||
rt_uint8_t id;
|
||||
rt_uint8_t pin_port;
|
||||
rt_uint8_t pin;
|
||||
rt_uint8_t magic;
|
||||
};
|
||||
|
||||
static struct _pin_index pin_index[] =
|
||||
{
|
||||
{0, 0, 0, 0},
|
||||
{1, 0, 0, 0},
|
||||
{2, 0, 0, 0},
|
||||
{3, 0, 0, 0},
|
||||
{4, 0, 0, 0},
|
||||
{5, 0, 0, 0},
|
||||
{6, GPIO_PORT_D, GPIO_PIN_0, PIN_MAGIC},
|
||||
{7, GPIO_PORT_D, GPIO_PIN_1, PIN_MAGIC},
|
||||
{8, GPIO_PORT_D, GPIO_PIN_2, PIN_MAGIC},
|
||||
{9, GPIO_PORT_D, GPIO_PIN_3, PIN_MAGIC},
|
||||
{10, GPIO_PORT_D, GPIO_PIN_4, PIN_MAGIC},
|
||||
{11, GPIO_PORT_D, GPIO_PIN_5, PIN_MAGIC},
|
||||
{12, GPIO_PORT_D, GPIO_PIN_6, PIN_MAGIC},
|
||||
{13, GPIO_PORT_D, GPIO_PIN_7, PIN_MAGIC},
|
||||
{14, GPIO_PORT_D, GPIO_PIN_8, PIN_MAGIC},
|
||||
{15, GPIO_PORT_D, GPIO_PIN_9, PIN_MAGIC},
|
||||
{16, GPIO_PORT_D, GPIO_PIN_10, PIN_MAGIC},
|
||||
{17, GPIO_PORT_D, GPIO_PIN_11, PIN_MAGIC},
|
||||
{18, GPIO_PORT_D, GPIO_PIN_12, PIN_MAGIC},
|
||||
{19, GPIO_PORT_D, GPIO_PIN_13, PIN_MAGIC},
|
||||
{20, 0, 0, 0},
|
||||
{21, GPIO_PORT_D, GPIO_PIN_14, PIN_MAGIC},
|
||||
{22, 0, 0, 0},
|
||||
{23, GPIO_PORT_D, GPIO_PIN_15, PIN_MAGIC},
|
||||
{24, GPIO_PORT_D, GPIO_PIN_16, PIN_MAGIC},
|
||||
{25, GPIO_PORT_D, GPIO_PIN_17, PIN_MAGIC},
|
||||
{26, GPIO_PORT_D, GPIO_PIN_18, PIN_MAGIC},
|
||||
{27, GPIO_PORT_D, GPIO_PIN_19, PIN_MAGIC},
|
||||
{28, GPIO_PORT_D, GPIO_PIN_20, PIN_MAGIC},
|
||||
{29, GPIO_PORT_D, GPIO_PIN_21, PIN_MAGIC},
|
||||
{30, 0, 0, 0},
|
||||
{31, 0, 0, 0},
|
||||
{32, 0, 0, 0},
|
||||
{33, 0, 0, 0},
|
||||
{34, 0, 0, 0},
|
||||
{35, 0, 0, 0},
|
||||
{36, 0, 0, 0},
|
||||
{37, GPIO_PORT_E, GPIO_PIN_12, PIN_MAGIC},
|
||||
{38, GPIO_PORT_E, GPIO_PIN_11, PIN_MAGIC},
|
||||
{39, GPIO_PORT_E, GPIO_PIN_10, PIN_MAGIC},
|
||||
{40, GPIO_PORT_E, GPIO_PIN_9, PIN_MAGIC},
|
||||
{41, GPIO_PORT_E, GPIO_PIN_8, PIN_MAGIC},
|
||||
{42, GPIO_PORT_E, GPIO_PIN_7, PIN_MAGIC},
|
||||
{43, GPIO_PORT_E, GPIO_PIN_6, PIN_MAGIC},
|
||||
{44, GPIO_PORT_E, GPIO_PIN_5, PIN_MAGIC},
|
||||
{45, GPIO_PORT_E, GPIO_PIN_4, PIN_MAGIC},
|
||||
{46, GPIO_PORT_E, GPIO_PIN_3, PIN_MAGIC},
|
||||
{47, GPIO_PORT_E, GPIO_PIN_2, PIN_MAGIC},
|
||||
{48, GPIO_PORT_E, GPIO_PIN_1, PIN_MAGIC},
|
||||
{49, GPIO_PORT_E, GPIO_PIN_0, PIN_MAGIC},
|
||||
{50, 0, 0, 0},
|
||||
{51, 0, 0, 0},
|
||||
{52, 0, 0, 0},
|
||||
{53, GPIO_PORT_F, GPIO_PIN_5, PIN_MAGIC},
|
||||
{54, GPIO_PORT_F, GPIO_PIN_4, PIN_MAGIC},
|
||||
{55, GPIO_PORT_F, GPIO_PIN_3, PIN_MAGIC},
|
||||
{56, GPIO_PORT_F, GPIO_PIN_2, PIN_MAGIC},
|
||||
{57, GPIO_PORT_F, GPIO_PIN_1, PIN_MAGIC},
|
||||
{58, GPIO_PORT_F, GPIO_PIN_0, PIN_MAGIC},
|
||||
{59, GPIO_PORT_C, GPIO_PIN_0, PIN_MAGIC},
|
||||
{60, GPIO_PORT_C, GPIO_PIN_1, PIN_MAGIC},
|
||||
{61, GPIO_PORT_C, GPIO_PIN_2, PIN_MAGIC},
|
||||
{62, GPIO_PORT_C, GPIO_PIN_3, PIN_MAGIC},
|
||||
{63, GPIO_PORT_A, GPIO_PIN_3, PIN_MAGIC},
|
||||
{64, GPIO_PORT_A, GPIO_PIN_2, PIN_MAGIC},
|
||||
{65, GPIO_PORT_A, GPIO_PIN_1, PIN_MAGIC},
|
||||
{66, GPIO_PORT_A, GPIO_PIN_0, PIN_MAGIC},
|
||||
};
|
||||
|
||||
static void pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
|
||||
{
|
||||
if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
|
||||
{
|
||||
dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_set_func(pin_index[pin].pin_port, pin_index[pin].pin, mode);
|
||||
}
|
||||
|
||||
static void pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
|
||||
{
|
||||
if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
|
||||
{
|
||||
dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_set_value(pin_index[pin].pin_port, pin_index[pin].pin, value);
|
||||
}
|
||||
|
||||
static int pin_read(struct rt_device *device, rt_base_t pin)
|
||||
{
|
||||
if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
|
||||
{
|
||||
dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return gpio_get_value(pin_index[pin].pin_port, pin_index[pin].pin);
|
||||
}
|
||||
|
||||
static rt_err_t pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args)
|
||||
{
|
||||
if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
|
||||
{
|
||||
dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
gpio_set_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin, hdr, args);
|
||||
gpio_set_irq_type(pin_index[pin].pin_port, pin_index[pin].pin, mode);
|
||||
return RT_EOK;
|
||||
}
|
||||
static rt_err_t pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
|
||||
{
|
||||
if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
|
||||
{
|
||||
dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
gpio_clear_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
|
||||
{
|
||||
if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
|
||||
{
|
||||
dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
gpio_irq_enable(pin_index[pin].pin_port, pin_index[pin].pin);
|
||||
else
|
||||
gpio_irq_disable(pin_index[pin].pin_port, pin_index[pin].pin);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/*
|
||||
ID GPIO ID GPIO ID GPIO ID GPIO ID GPIO ID GPIO ID GPIO
|
||||
6 PD0 13 PD7 21 PD14 29 PD21 43 PE6 53 PF5 60 PC1
|
||||
7 PD1 14 PD8 23 PD15 37 PE12 44 PE5 54 PF4 61 PC2
|
||||
8 PD2 15 PD9 24 PD16 38 PE11 45 PE4 55 PF3 62 PC3
|
||||
9 PD3 16 PD10 25 PD17 39 PE10 46 PE3 56 PF2 63 PA3
|
||||
10 PD4 17 PD11 26 PD18 40 PE9 47 PE2 57 PF1 64 PA2
|
||||
11 PD5 18 PD12 27 PD19 41 PE8 48 PE1 58 PF0 65 PA1
|
||||
12 PD6 19 PD13 28 PD20 42 PE7 49 PE0 59 PC0 66 PA0
|
||||
*/
|
||||
|
||||
static const struct rt_pin_ops ops =
|
||||
{
|
||||
pin_mode,
|
||||
pin_write,
|
||||
pin_read,
|
||||
pin_attach_irq,
|
||||
pin_dettach_irq,
|
||||
pin_irq_enable,
|
||||
};
|
||||
#endif
|
||||
|
||||
int rt_hw_gpio_init(void)
|
||||
{
|
||||
#ifdef RT_USING_PIN
|
||||
rt_device_pin_register("gpio", &ops, RT_NULL);
|
||||
#endif
|
||||
/* install ISR */
|
||||
rt_hw_interrupt_install(PIOD_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_D], "gpiod_irq");
|
||||
rt_hw_interrupt_umask(PIOD_INTERRUPT);
|
||||
|
||||
rt_hw_interrupt_install(PIOE_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_E], "gpioe_irq");
|
||||
rt_hw_interrupt_umask(PIOE_INTERRUPT);
|
||||
|
||||
rt_hw_interrupt_install(PIOF_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_F], "gpiof_irq");
|
||||
rt_hw_interrupt_umask(PIOF_INTERRUPT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(rt_hw_gpio_init);
|
|
@ -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__ */
|
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* File : drv_uart.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 RT-Thread the first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "drv_uart.h"
|
||||
#include "interrupt.h"
|
||||
|
||||
#include "drv_gpio.h"
|
||||
#include "drv_clock.h"
|
||||
|
||||
#define readl(addr) (*(volatile unsigned int *)(addr))
|
||||
#define writel(value,addr) (*(volatile unsigned int *)(addr) = (value))
|
||||
|
||||
#ifdef RT_USING_SERIAL
|
||||
|
||||
struct device_uart
|
||||
{
|
||||
rt_uint32_t hw_base;
|
||||
rt_uint32_t irqno;
|
||||
char name[RT_NAME_MAX];
|
||||
rt_uint32_t gpio_rx_port;
|
||||
rt_uint32_t gpio_tx_port;
|
||||
rt_uint32_t gpio_rx_pin;
|
||||
rt_uint32_t gpio_tx_pin;
|
||||
rt_uint32_t gpio_rx_fun;
|
||||
rt_uint32_t gpio_tx_fun;
|
||||
};
|
||||
|
||||
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
|
||||
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg);
|
||||
static int uart_putc(struct rt_serial_device *serial, char c);
|
||||
static int uart_getc(struct rt_serial_device *serial);
|
||||
static rt_size_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
|
||||
|
||||
void uart_irq_handler(int irqno, void *param);
|
||||
|
||||
const struct rt_uart_ops _uart_ops =
|
||||
{
|
||||
uart_configure,
|
||||
uart_control,
|
||||
uart_putc,
|
||||
uart_getc,
|
||||
uart_dma_transmit
|
||||
};
|
||||
|
||||
/*
|
||||
* UART Initiation
|
||||
*/
|
||||
int rt_hw_uart_init(void)
|
||||
{
|
||||
struct rt_serial_device *serial;
|
||||
struct device_uart *uart;
|
||||
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||
|
||||
#ifdef TINA_USING_UART0
|
||||
{
|
||||
static struct rt_serial_device serial0;
|
||||
static struct device_uart uart0;
|
||||
|
||||
serial = &serial0;
|
||||
uart = &uart0;
|
||||
|
||||
serial->ops = &_uart_ops;
|
||||
serial->config = config;
|
||||
serial->config.baud_rate = 115200;
|
||||
|
||||
uart->hw_base = UART0_BASE_ADDR; // UART0_BASE;
|
||||
uart->irqno = UART0_INTERRUPT; // IRQ_UART0;
|
||||
uart->gpio_rx_port = GPIO_PORT_E;
|
||||
uart->gpio_tx_port = GPIO_PORT_E;
|
||||
uart->gpio_rx_pin = GPIO_PIN_0;
|
||||
uart->gpio_tx_pin = GPIO_PIN_1;
|
||||
uart->gpio_rx_fun = IO_FUN_4;
|
||||
uart->gpio_tx_fun = IO_FUN_4;
|
||||
|
||||
rt_hw_serial_register(serial,
|
||||
"uart0",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
uart);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TINA_USING_UART1
|
||||
{
|
||||
static struct rt_serial_device serial1;
|
||||
static struct device_uart uart1;
|
||||
|
||||
serial = &serial1;
|
||||
uart = &uart1;
|
||||
|
||||
serial->ops = &_uart_ops;
|
||||
serial->config = config;
|
||||
serial->config.baud_rate = 115200;
|
||||
|
||||
uart->hw_base = UART1_BASE_ADDR; // UART1_BASE;
|
||||
uart->irqno = UART1_INTERRUPT; // IRQ_UART1;
|
||||
uart->gpio_rx_port = GPIO_PORT_A;
|
||||
uart->gpio_tx_port = GPIO_PORT_A;
|
||||
uart->gpio_rx_pin = GPIO_PIN_3;
|
||||
uart->gpio_tx_pin = GPIO_PIN_2;
|
||||
uart->gpio_rx_fun = IO_FUN_4;
|
||||
uart->gpio_tx_fun = IO_FUN_4;
|
||||
|
||||
rt_hw_serial_register(serial,
|
||||
"uart1",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
uart);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TINA_USING_UART2
|
||||
{
|
||||
static struct rt_serial_device serial2;
|
||||
static struct device_uart uart2;
|
||||
|
||||
serial = &serial2;
|
||||
uart = &uart2;
|
||||
|
||||
serial->ops = &_uart_ops;
|
||||
serial->config = config;
|
||||
serial->config.baud_rate = 115200;
|
||||
|
||||
uart->hw_base = UART2_BASE_ADDR; // UART1_BASE;
|
||||
uart->irqno = UART2_INTERRUPT; // IRQ_UART1;
|
||||
uart->gpio_rx_port = GPIO_PORT_E;
|
||||
uart->gpio_tx_port = GPIO_PORT_E;
|
||||
uart->gpio_rx_pin = GPIO_PIN_8;
|
||||
uart->gpio_tx_pin = GPIO_PIN_7;
|
||||
uart->gpio_rx_fun = IO_FUN_2;
|
||||
uart->gpio_tx_fun = IO_FUN_2;
|
||||
|
||||
rt_hw_serial_register(serial,
|
||||
"uart2",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
uart);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* UART interface
|
||||
*/
|
||||
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
|
||||
{
|
||||
rt_uint32_t addr, val;
|
||||
struct device_uart *uart;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
serial->config = *cfg;
|
||||
|
||||
uart = serial->parent.user_data;
|
||||
RT_ASSERT(uart != RT_NULL);
|
||||
/* config gpio port */
|
||||
gpio_set_func(uart->gpio_rx_port, uart->gpio_rx_pin, uart->gpio_rx_fun);
|
||||
gpio_set_func(uart->gpio_tx_port, uart->gpio_tx_pin, uart->gpio_tx_fun);
|
||||
/* Enable UART clock */
|
||||
/* Open the clock gate for uart */
|
||||
if ((rt_uint32_t)(uart->hw_base) == UART0_BASE_ADDR)
|
||||
{
|
||||
bus_gate_clk_enalbe(UART0_GATING);
|
||||
bus_software_reset_enalbe(UART0_GATING);
|
||||
}
|
||||
else if ((rt_uint32_t)(uart->hw_base) == UART1_BASE_ADDR)
|
||||
{
|
||||
bus_gate_clk_enalbe(UART1_GATING);
|
||||
bus_software_reset_enalbe(UART1_GATING);
|
||||
}
|
||||
else if ((rt_uint32_t)(uart->hw_base) == UART2_BASE_ADDR)
|
||||
{
|
||||
bus_gate_clk_enalbe(UART2_GATING);
|
||||
bus_software_reset_enalbe(UART2_GATING);
|
||||
}
|
||||
else
|
||||
RT_ASSERT(0);
|
||||
/* Config uart0 to 115200-8-1-0 */
|
||||
addr = uart->hw_base;
|
||||
/* close uart irq */
|
||||
writel(0x0, addr + UART_IER);
|
||||
/* config fifo */
|
||||
writel(0x37, addr + UART_FCR);
|
||||
/* config modem */
|
||||
writel(0x0, addr + UART_MCR);
|
||||
/* config baud */
|
||||
val = readl(addr + UART_LCR);
|
||||
val |= (1 << 7);
|
||||
writel(val, addr + UART_LCR);
|
||||
val = apb_get_clk() / 16 / serial->config.baud_rate;
|
||||
writel(val & 0xff, addr + UART_DLL);
|
||||
writel((val >> 8) & 0xff, addr + UART_DLH);
|
||||
val = readl(addr + UART_LCR);
|
||||
val &= ~(1 << 7);
|
||||
writel(val, addr + UART_LCR);
|
||||
|
||||
val = readl(addr + UART_LCR);
|
||||
val &= ~0x1f;
|
||||
val |= ((serial->config.data_bits - DATA_BITS_5) << 0) | (0 << 2) | (0x0 << 3);
|
||||
writel(val, addr + UART_LCR);
|
||||
|
||||
writel(0xf, addr + UART_TFL);
|
||||
writel(0x3F, addr + UART_RFL);
|
||||
|
||||
writel(0x1, addr + UART_IER);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
|
||||
{
|
||||
struct device_uart *uart;
|
||||
|
||||
uart = serial->parent.user_data;
|
||||
|
||||
RT_ASSERT(uart != RT_NULL);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_CLR_INT:
|
||||
/* Disable the UART Interrupt */
|
||||
rt_hw_interrupt_mask(uart->irqno);
|
||||
writel(0x00, uart->hw_base + UART_IER);
|
||||
break;
|
||||
|
||||
case RT_DEVICE_CTRL_SET_INT:
|
||||
/* install interrupt */
|
||||
rt_hw_interrupt_install(uart->irqno, uart_irq_handler,
|
||||
serial, uart->name);
|
||||
rt_hw_interrupt_umask(uart->irqno);
|
||||
writel(0x01, uart->hw_base + UART_IER);
|
||||
/* Enable the UART Interrupt */
|
||||
break;
|
||||
}
|
||||
|
||||
return (RT_EOK);
|
||||
}
|
||||
|
||||
|
||||
static int uart_putc(struct rt_serial_device *serial, char c)
|
||||
{
|
||||
struct device_uart *uart;
|
||||
volatile rt_uint32_t *sed_buf;
|
||||
volatile rt_uint32_t *sta;
|
||||
|
||||
uart = serial->parent.user_data;
|
||||
sed_buf = (rt_uint32_t *)(uart->hw_base + UART_THR);
|
||||
sta = (rt_uint32_t *)(uart->hw_base + UART_USR);
|
||||
/* FIFO status, contain valid data */
|
||||
while (!(*sta & 0x02));
|
||||
*sed_buf = c;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int uart_getc(struct rt_serial_device *serial)
|
||||
{
|
||||
int ch = -1;
|
||||
volatile rt_uint32_t *rec_buf;
|
||||
volatile rt_uint32_t *sta;
|
||||
struct device_uart *uart = serial->parent.user_data;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
|
||||
rec_buf = (rt_uint32_t *)(uart->hw_base + UART_RHB);
|
||||
sta = (rt_uint32_t *)(uart->hw_base + UART_USR);
|
||||
/* Receive Data Available */
|
||||
if (*sta & 0x08)
|
||||
{
|
||||
ch = *rec_buf & 0xff;
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
static rt_size_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* UART ISR */
|
||||
void uart_irq_handler(int irqno, void *param)
|
||||
{
|
||||
rt_uint32_t val;
|
||||
struct rt_serial_device *serial = (struct rt_serial_device *)param;
|
||||
struct device_uart *uart = serial->parent.user_data;
|
||||
|
||||
val = readl(uart->hw_base + 0x08) & 0x0F;
|
||||
/* read interrupt status and clear it */
|
||||
if (val & 0x4) /* rx ind */
|
||||
{
|
||||
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
|
||||
}
|
||||
|
||||
if (0) /* tx done */
|
||||
{
|
||||
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -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__ */
|
|
@ -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')
|
|
@ -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
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* File : cpu.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 RT-Thread the first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
RT_WEAK void machine_reset(void)
|
||||
{
|
||||
rt_kprintf("reboot system...\n");
|
||||
rt_hw_interrupt_disable();
|
||||
while (1);
|
||||
}
|
||||
|
||||
RT_WEAK void machine_shutdown(void)
|
||||
{
|
||||
rt_kprintf("shutdown...\n");
|
||||
rt_hw_interrupt_disable();
|
||||
while (1);
|
||||
}
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* File : cpuport.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 RT-Thread the first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#define ICACHE_MASK (rt_uint32_t)(1 << 12)
|
||||
#define DCACHE_MASK (rt_uint32_t)(1 << 2)
|
||||
|
||||
extern void machine_reset(void);
|
||||
extern void machine_shutdown(void);
|
||||
|
||||
#if defined(__GNUC__) || defined(__ICCARM__)
|
||||
rt_inline rt_uint32_t cp15_rd(void)
|
||||
{
|
||||
rt_uint32_t i;
|
||||
|
||||
__asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r"(i));
|
||||
return i;
|
||||
}
|
||||
|
||||
rt_inline void cache_enable(rt_uint32_t bit)
|
||||
{
|
||||
__asm volatile(\
|
||||
"mrc p15,0,r0,c1,c0,0\n\t" \
|
||||
"orr r0,r0,%0\n\t" \
|
||||
"mcr p15,0,r0,c1,c0,0" \
|
||||
: \
|
||||
: "r"(bit) \
|
||||
: "memory");
|
||||
}
|
||||
|
||||
rt_inline void cache_disable(rt_uint32_t bit)
|
||||
{
|
||||
__asm volatile(\
|
||||
"mrc p15,0,r0,c1,c0,0\n\t" \
|
||||
"bic r0,r0,%0\n\t" \
|
||||
"mcr p15,0,r0,c1,c0,0" \
|
||||
: \
|
||||
: "r"(bit) \
|
||||
: "memory");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
rt_inline rt_uint32_t cp15_rd(void)
|
||||
{
|
||||
rt_uint32_t i;
|
||||
|
||||
__asm volatile
|
||||
{
|
||||
mrc p15, 0, i, c1, c0, 0
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
rt_inline void cache_enable(rt_uint32_t bit)
|
||||
{
|
||||
rt_uint32_t value;
|
||||
|
||||
__asm volatile
|
||||
{
|
||||
mrc p15, 0, value, c1, c0, 0
|
||||
orr value, value, bit
|
||||
mcr p15, 0, value, c1, c0, 0
|
||||
}
|
||||
}
|
||||
|
||||
rt_inline void cache_disable(rt_uint32_t bit)
|
||||
{
|
||||
rt_uint32_t value;
|
||||
|
||||
__asm volatile
|
||||
{
|
||||
mrc p15, 0, value, c1, c0, 0
|
||||
bic value, value, bit
|
||||
mcr p15, 0, value, c1, c0, 0
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* enable I-Cache
|
||||
*
|
||||
*/
|
||||
void rt_hw_cpu_icache_enable()
|
||||
{
|
||||
cache_enable(ICACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* disable I-Cache
|
||||
*
|
||||
*/
|
||||
void rt_hw_cpu_icache_disable()
|
||||
{
|
||||
cache_disable(ICACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the status of I-Cache
|
||||
*
|
||||
*/
|
||||
rt_base_t rt_hw_cpu_icache_status()
|
||||
{
|
||||
return (cp15_rd() & ICACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* enable D-Cache
|
||||
*
|
||||
*/
|
||||
void rt_hw_cpu_dcache_enable()
|
||||
{
|
||||
cache_enable(DCACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* disable D-Cache
|
||||
*
|
||||
*/
|
||||
void rt_hw_cpu_dcache_disable()
|
||||
{
|
||||
cache_disable(DCACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the status of D-Cache
|
||||
*
|
||||
*/
|
||||
rt_base_t rt_hw_cpu_dcache_status()
|
||||
{
|
||||
return (cp15_rd() & DCACHE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* reset cpu by dog's time-out
|
||||
*
|
||||
*/
|
||||
void rt_hw_cpu_reset()
|
||||
{
|
||||
|
||||
rt_kprintf("Restarting system...\n");
|
||||
machine_reset();
|
||||
|
||||
while (1); /* loop forever and wait for reset to happen */
|
||||
|
||||
/* NEVER REACHED */
|
||||
}
|
||||
|
||||
/**
|
||||
* shutdown CPU
|
||||
*
|
||||
*/
|
||||
void rt_hw_cpu_shutdown()
|
||||
{
|
||||
rt_uint32_t level;
|
||||
rt_kprintf("shutdown...\n");
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
machine_shutdown();
|
||||
while (level)
|
||||
{
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RT_USING_CPU_FFS
|
||||
/**
|
||||
* This function finds the first bit set (beginning with the least significant bit)
|
||||
* in value and return the index of that bit.
|
||||
*
|
||||
* Bits are numbered starting at 1 (the least significant bit). A return value of
|
||||
* zero from any of these functions means that the argument was zero.
|
||||
*
|
||||
* @return return the index of the first bit set. If value is 0, then this function
|
||||
* shall return 0.
|
||||
*/
|
||||
#if defined(__CC_ARM)
|
||||
int __rt_ffs(int value)
|
||||
{
|
||||
register rt_uint32_t x;
|
||||
|
||||
if (value == 0)
|
||||
return value;
|
||||
|
||||
__asm
|
||||
{
|
||||
rsb x, value, #0
|
||||
and x, x, value
|
||||
clz x, x
|
||||
rsb x, x, #32
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
#elif defined(__GNUC__) || defined(__ICCARM__)
|
||||
int __rt_ffs(int value)
|
||||
{
|
||||
return __builtin_ffs(value);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*@}*/
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* File : interrupt.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 RT-Thread the first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "interrupt.h"
|
||||
|
||||
extern rt_uint32_t rt_interrupt_nest;
|
||||
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||
rt_uint32_t rt_thread_switch_interrupt_flag;
|
||||
|
||||
static struct rt_irq_desc isr_table[INTERRUPTS_MAX];
|
||||
|
||||
static void rt_hw_interrupt_handler(int vector, void *param)
|
||||
{
|
||||
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
||||
}
|
||||
|
||||
#define readl(addr) (*(volatile unsigned int *)(addr))
|
||||
#define writel(value,addr) (*(volatile unsigned int *)(addr) = (value))
|
||||
|
||||
/**
|
||||
* This function will initialize hardware interrupt
|
||||
*/
|
||||
void rt_hw_interrupt_init(void)
|
||||
{
|
||||
rt_int32_t idx;
|
||||
|
||||
rt_memset(isr_table, 0x00, sizeof(isr_table));
|
||||
for (idx = 0; idx < INTERRUPTS_MAX; idx ++)
|
||||
{
|
||||
isr_table[idx].handler = rt_hw_interrupt_handler;
|
||||
}
|
||||
|
||||
/* init interrupt nest, and context in thread sp */
|
||||
rt_interrupt_nest = 0;
|
||||
rt_interrupt_from_thread = 0;
|
||||
rt_interrupt_to_thread = 0;
|
||||
rt_thread_switch_interrupt_flag = 0;
|
||||
|
||||
/* set base_addr reg */
|
||||
INTC->base_addr_reg = 0x00000000;
|
||||
/* clear enable */
|
||||
INTC->en_reg0 = 0x00000000;
|
||||
INTC->en_reg1 = 0x00000000;
|
||||
/* mask interrupt */
|
||||
INTC->mask_reg0 = 0xFFFFFFFF;
|
||||
INTC->mask_reg1 = 0xFFFFFFFF;
|
||||
/* clear pending */
|
||||
INTC->pend_reg0 = 0x00000000;
|
||||
INTC->pend_reg1 = 0x00000000;
|
||||
/* set priority */
|
||||
INTC->resp_reg0 = 0x00000000;
|
||||
INTC->resp_reg1 = 0x00000000;
|
||||
/* close fiq interrupt */
|
||||
INTC->ff_reg0 = 0x00000000;
|
||||
INTC->ff_reg1 = 0x00000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_mask(int vector)
|
||||
{
|
||||
rt_uint32_t mask_addr, data;
|
||||
|
||||
if ((vector < 0) || (vector > INTERRUPTS_MAX))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mask_addr = (rt_uint32_t)(&INTC->mask_reg0);
|
||||
mask_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
|
||||
|
||||
vector &= 0x1F;
|
||||
data = readl(mask_addr);
|
||||
data |= 0x1 << vector;
|
||||
writel(data, mask_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will un-mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_umask(int vector)
|
||||
{
|
||||
rt_uint32_t mask_addr, data;
|
||||
|
||||
if ((vector < 0) || (vector > INTERRUPTS_MAX))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mask_addr = (rt_uint32_t)(&INTC->mask_reg0);
|
||||
mask_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
|
||||
|
||||
vector &= 0x1F;
|
||||
data = readl(mask_addr);
|
||||
data &= ~(0x1 << vector);
|
||||
writel(data, mask_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will install a interrupt service routine to a interrupt.
|
||||
* @param vector the interrupt number
|
||||
* @param handler the interrupt service routine to be installed
|
||||
* @param param the interrupt service function parameter
|
||||
* @param name the interrupt name
|
||||
* @return old handler
|
||||
*/
|
||||
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
||||
void *param, char *name)
|
||||
{
|
||||
rt_isr_handler_t old_handler = RT_NULL;
|
||||
rt_uint32_t pend_addr, en_addr, data;
|
||||
|
||||
if ((vector < 0) || (vector > INTERRUPTS_MAX))
|
||||
{
|
||||
return old_handler;
|
||||
}
|
||||
|
||||
old_handler = isr_table[vector].handler;
|
||||
|
||||
#ifdef RT_USING_INTERRUPT_INFO
|
||||
rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
|
||||
#endif /* RT_USING_INTERRUPT_INFO */
|
||||
isr_table[vector].handler = handler;
|
||||
isr_table[vector].param = param;
|
||||
|
||||
pend_addr = (rt_uint32_t)(&INTC->pend_reg0);
|
||||
en_addr = (rt_uint32_t)(&INTC->en_reg0);
|
||||
pend_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
|
||||
en_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
|
||||
|
||||
vector &= 0x1F;
|
||||
data = readl(pend_addr);
|
||||
data &= ~(0x1 << vector);
|
||||
writel(data, pend_addr);
|
||||
|
||||
data = readl(en_addr);
|
||||
data |= 0x1 << vector;
|
||||
writel(data, en_addr);
|
||||
|
||||
return old_handler;
|
||||
}
|
||||
|
||||
void rt_interrupt_dispatch(void)
|
||||
{
|
||||
void *param;
|
||||
int vector;
|
||||
rt_isr_handler_t isr_func;
|
||||
rt_uint32_t pend_addr, data;
|
||||
|
||||
vector = INTC->vector_reg - INTC->base_addr_reg;
|
||||
vector = vector >> 2;
|
||||
|
||||
isr_func = isr_table[vector].handler;
|
||||
param = isr_table[vector].param;
|
||||
|
||||
/* jump to fun */
|
||||
isr_func(vector, param);
|
||||
/* clear pend bit */
|
||||
pend_addr = (rt_uint32_t)(&INTC->pend_reg0);
|
||||
pend_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
|
||||
|
||||
vector &= 0x1F;
|
||||
data = readl(pend_addr);
|
||||
data &= ~(0x1 << vector);
|
||||
writel(data, pend_addr);
|
||||
|
||||
#ifdef RT_USING_INTERRUPT_INFO
|
||||
isr_table[vector].counter ++;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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__ */
|
|
@ -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();
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* File : mmu.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 RT-Thread the first version
|
||||
*/
|
||||
#ifndef __MMU_H__
|
||||
#define __MMU_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#define CACHE_LINE_SIZE 32
|
||||
|
||||
#define DESC_SEC (0x2|(1<<4))
|
||||
#define CB (3<<2) //cache_on, write_back
|
||||
#define CNB (2<<2) //cache_on, write_through
|
||||
#define NCB (1<<2) //cache_off,WR_BUF on
|
||||
#define NCNB (0<<2) //cache_off,WR_BUF off
|
||||
#define AP_RW (3<<10) //supervisor=RW, user=RW
|
||||
#define AP_RO (2<<10) //supervisor=RW, user=RO
|
||||
|
||||
#define DOMAIN_FAULT (0x0)
|
||||
#define DOMAIN_CHK (0x1)
|
||||
#define DOMAIN_NOTCHK (0x3)
|
||||
#define DOMAIN0 (0x0<<5)
|
||||
#define DOMAIN1 (0x1<<5)
|
||||
|
||||
#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
|
||||
#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
|
||||
|
||||
#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */
|
||||
#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */
|
||||
#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
|
||||
#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
|
||||
|
||||
struct mem_desc
|
||||
{
|
||||
rt_uint32_t vaddr_start;
|
||||
rt_uint32_t vaddr_end;
|
||||
rt_uint32_t paddr_start;
|
||||
rt_uint32_t attr;
|
||||
};
|
||||
|
||||
void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size);
|
||||
void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size);
|
||||
void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size);
|
||||
void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size);
|
||||
#endif
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* File : stack.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 RT-Thread the first version
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
|
||||
/*****************************/
|
||||
/* CPU Mode */
|
||||
/*****************************/
|
||||
#define USERMODE 0x10
|
||||
#define FIQMODE 0x11
|
||||
#define IRQMODE 0x12
|
||||
#define SVCMODE 0x13
|
||||
#define ABORTMODE 0x17
|
||||
#define UNDEFMODE 0x1b
|
||||
#define MODEMASK 0x1f
|
||||
#define NOINT 0xc0
|
||||
|
||||
/**
|
||||
* This function will initialize thread stack
|
||||
*
|
||||
* @param tentry the entry of thread
|
||||
* @param parameter the parameter of entry
|
||||
* @param stack_addr the beginning stack address
|
||||
* @param texit the function will be called when thread exit
|
||||
*
|
||||
* @return stack address
|
||||
*/
|
||||
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
||||
rt_uint8_t *stack_addr, void *texit)
|
||||
{
|
||||
rt_uint32_t *stk;
|
||||
|
||||
//stk = (rt_uint32_t*)stack_addr;
|
||||
stack_addr += sizeof(rt_uint32_t);
|
||||
stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
|
||||
stk = (rt_uint32_t *)stack_addr;
|
||||
|
||||
*(--stk) = (rt_uint32_t)tentry; /* entry point */
|
||||
*(--stk) = (rt_uint32_t)texit; /* lr */
|
||||
*(--stk) = 0xdeadbeef; /* r12 */
|
||||
*(--stk) = 0xdeadbeef; /* r11 */
|
||||
*(--stk) = 0xdeadbeef; /* r10 */
|
||||
*(--stk) = 0xdeadbeef; /* r9 */
|
||||
*(--stk) = 0xdeadbeef; /* r8 */
|
||||
*(--stk) = 0xdeadbeef; /* r7 */
|
||||
*(--stk) = 0xdeadbeef; /* r6 */
|
||||
*(--stk) = 0xdeadbeef; /* r5 */
|
||||
*(--stk) = 0xdeadbeef; /* r4 */
|
||||
*(--stk) = 0xdeadbeef; /* r3 */
|
||||
*(--stk) = 0xdeadbeef; /* r2 */
|
||||
*(--stk) = 0xdeadbeef; /* r1 */
|
||||
*(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
|
||||
/* cpsr */
|
||||
if ((rt_uint32_t)tentry & 0x01)
|
||||
*(--stk) = SVCMODE | 0x20; /* thumb mode */
|
||||
else
|
||||
*(--stk) = SVCMODE; /* arm mode */
|
||||
|
||||
/* return task's current stack address */
|
||||
return (rt_uint8_t *)stk;
|
||||
}
|
|
@ -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 .
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* File : trap.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2017, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-02-08 RT-Thread the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#define INT_IRQ 0x00
|
||||
#define INT_FIQ 0x01
|
||||
|
||||
extern struct rt_thread *rt_current_thread;
|
||||
#ifdef RT_USING_FINSH
|
||||
extern long list_thread(void);
|
||||
#endif
|
||||
|
||||
struct rt_hw_register
|
||||
{
|
||||
rt_uint32_t r0;
|
||||
rt_uint32_t r1;
|
||||
rt_uint32_t r2;
|
||||
rt_uint32_t r3;
|
||||
rt_uint32_t r4;
|
||||
rt_uint32_t r5;
|
||||
rt_uint32_t r6;
|
||||
rt_uint32_t r7;
|
||||
rt_uint32_t r8;
|
||||
rt_uint32_t r9;
|
||||
rt_uint32_t r10;
|
||||
rt_uint32_t fp;
|
||||
rt_uint32_t ip;
|
||||
rt_uint32_t sp;
|
||||
rt_uint32_t lr;
|
||||
rt_uint32_t pc;
|
||||
rt_uint32_t cpsr;
|
||||
rt_uint32_t ORIG_r0;
|
||||
};
|
||||
static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
|
||||
void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context))
|
||||
{
|
||||
rt_exception_hook = exception_handle;
|
||||
}
|
||||
/**
|
||||
* this function will show registers of CPU
|
||||
*
|
||||
* @param regs the registers point
|
||||
*/
|
||||
|
||||
void rt_hw_show_register(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_kprintf("Execption:\n");
|
||||
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n",
|
||||
regs->r0, regs->r1, regs->r2, regs->r3);
|
||||
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n",
|
||||
regs->r4, regs->r5, regs->r6, regs->r7);
|
||||
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n",
|
||||
regs->r8, regs->r9, regs->r10);
|
||||
rt_kprintf("fp :0x%08x ip :0x%08x\n",
|
||||
regs->fp, regs->ip);
|
||||
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n",
|
||||
regs->sp, regs->lr, regs->pc);
|
||||
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
|
||||
}
|
||||
|
||||
/**
|
||||
* When ARM7TDMI comes across an instruction which it cannot handle,
|
||||
* it takes the undefined instruction trap.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_udef(struct rt_hw_register *regs)
|
||||
{
|
||||
if (rt_exception_hook != RT_NULL)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_exception_hook(regs);
|
||||
if (result == RT_EOK) return;
|
||||
}
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("undefined instruction\n");
|
||||
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* The software interrupt instruction (SWI) is used for entering
|
||||
* Supervisor mode, usually to request a particular supervisor
|
||||
* function.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_swi(struct rt_hw_register *regs)
|
||||
{
|
||||
if (rt_exception_hook != RT_NULL)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_exception_hook(regs);
|
||||
if (result == RT_EOK) return;
|
||||
}
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("software interrupt\n");
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abort indicates that the current memory access cannot be completed,
|
||||
* which occurs during an instruction prefetch.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_pabt(struct rt_hw_register *regs)
|
||||
{
|
||||
if (rt_exception_hook != RT_NULL)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_exception_hook(regs);
|
||||
if (result == RT_EOK) return;
|
||||
}
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("prefetch abort\n");
|
||||
rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abort indicates that the current memory access cannot be completed,
|
||||
* which occurs during a data access.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_dabt(struct rt_hw_register *regs)
|
||||
{
|
||||
if (rt_exception_hook != RT_NULL)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_exception_hook(regs);
|
||||
if (result == RT_EOK) return;
|
||||
}
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("data abort\n");
|
||||
rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally, system will never reach here
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_resv(struct rt_hw_register *regs)
|
||||
{
|
||||
if (rt_exception_hook != RT_NULL)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_exception_hook(regs);
|
||||
if (result == RT_EOK) return;
|
||||
}
|
||||
rt_kprintf("not used\n");
|
||||
rt_hw_show_register(regs);
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
extern void rt_interrupt_dispatch(void);
|
||||
|
||||
void rt_hw_trap_irq(void)
|
||||
{
|
||||
rt_interrupt_dispatch();
|
||||
}
|
||||
|
||||
void rt_hw_trap_fiq(void)
|
||||
{
|
||||
rt_interrupt_dispatch();
|
||||
}
|
|
@ -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 = .;
|
||||
}
|
|
@ -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
|
|
@ -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'
|
Loading…
Reference in New Issue