mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-02-07 18:02:15 +08:00
Merge branch 'master' into mutexrevert
This commit is contained in:
8
.github/workflows/action.yml
vendored
8
.github/workflows/action.yml
vendored
@@ -149,10 +149,10 @@ jobs:
|
||||
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-arm' && success() }}
|
||||
shell: bash
|
||||
run: |
|
||||
wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/arm-2017q2-v6/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2
|
||||
sudo tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 -C /opt
|
||||
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc --version
|
||||
echo "RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-6-2017-q2-update/bin" >> $GITHUB_ENV
|
||||
wget -q https://developer.arm.com/-/media/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
|
||||
sudo tar xjf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -C /opt
|
||||
/opt/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc --version
|
||||
echo "RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-10-2020-q4-major/bin" >> $GITHUB_ENV
|
||||
|
||||
- name: Install Mips ToolChains
|
||||
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-mips' && success() }}
|
||||
|
||||
10
.github/workflows/action_utest.yml
vendored
10
.github/workflows/action_utest.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
legs:
|
||||
- {UTEST: "kernel/ipc", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"}
|
||||
- {UTEST: "kernel/mem", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/kernel/config.h"}
|
||||
- {UTEST: "components/utest", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "vexpress-a9", CONFIG_FILE: "examples/utest/configs/utest_self/config.h"}
|
||||
|
||||
env:
|
||||
@@ -23,12 +23,12 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update > /dev/null
|
||||
sudo apt-get -yqq install scons qemu-system-arm git
|
||||
wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/arm-2017q2-v6/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2
|
||||
sudo tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 -C /opt
|
||||
wget -q https://developer.arm.com/-/media/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
|
||||
sudo tar xjf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -C /opt
|
||||
- name: Build bsp
|
||||
run: |
|
||||
export RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-6-2017-q2-update/bin
|
||||
/opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc --version
|
||||
export RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-10-2020-q4-major/bin
|
||||
/opt/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc --version
|
||||
cp $TEST_CONFIG_FILE $TEST_BSP_ROOT/rtconfig.h
|
||||
scons -j$(nproc) -C $TEST_BSP_ROOT
|
||||
- name: Start test
|
||||
|
||||
725
bsp/ft2004/.config
Normal file
725
bsp/ft2004/.config
Normal file
File diff suppressed because it is too large
Load Diff
31
bsp/ft2004/Kconfig
Normal file
31
bsp/ft2004/Kconfig
Normal file
@@ -0,0 +1,31 @@
|
||||
mainmenu "RT-Thread Project Configuration"
|
||||
|
||||
config BSP_DIR
|
||||
string
|
||||
option env="BSP_ROOT"
|
||||
default "."
|
||||
|
||||
config RTT_DIR
|
||||
string
|
||||
option env="RTT_ROOT"
|
||||
default "../.."
|
||||
|
||||
config PKGS_DIR
|
||||
string
|
||||
option env="PKGS_ROOT"
|
||||
default "packages"
|
||||
|
||||
source "$RTT_DIR/Kconfig"
|
||||
source "$PKGS_DIR/Kconfig"
|
||||
|
||||
|
||||
config FT2004
|
||||
bool
|
||||
select ARCH_ARM_CORTEX_A
|
||||
select RT_USING_COMPONENTS_INIT
|
||||
select RT_USING_USER_MAIN
|
||||
select RT_USING_GIC_V3
|
||||
default y
|
||||
|
||||
|
||||
source "./libraries/Kconfig"
|
||||
236
bsp/ft2004/README.md
Normal file
236
bsp/ft2004/README.md
Normal file
@@ -0,0 +1,236 @@
|
||||
# ft2004 四核开发板 BSP 说明
|
||||
|
||||
## 简介
|
||||
|
||||
本文档为 飞腾技术公司 ft2000/4 开发板的 BSP (板级支持包) 说明。
|
||||
|
||||
主要内容如下:
|
||||
|
||||
- 开发板资源介绍
|
||||
- BSP 外设支持
|
||||
- 使用方法
|
||||
- 相关实验
|
||||
|
||||
### 1. 开发板资源介绍
|
||||
|
||||
FT-2000/4 是一款面向桌面应用的高性能通用 4 核处理器。每 2 个核构成 1
|
||||
个处理器核簇(Cluster),并共享 L2 Cache。主要技术特征如下:
|
||||
|
||||
- 兼容 ARM v8 64 位指令系统,兼容 32 位指令
|
||||
- 支持单精度、双精度浮点运算指令
|
||||
- 支持 ASIMD 处理指令
|
||||
- 集成 2 个 DDR4 通道,可对 DDR 存储数据进行实时加密
|
||||
- 集成 34 Lane PCIE3.0 接口:2 个 X16(每个可拆分成 2 个 X8),2 个 X1
|
||||
- 集成 2 个 GMAC,RGMII 接口,支持 10/100/1000 自适应
|
||||
- 集成 1 个 SD 卡控制器,兼容 SD 2.0 规范
|
||||
- 集成 1 个 HDAudio,支持音频输出,可同时支持最多 4 个 Codec
|
||||
- 集成 SM2、SM3、SM4 模块
|
||||
- 集成 4 个 UART,1 个 LPC,32 个 GPIO,4 个 I2C,1 个 QSPI,2 个通
|
||||
用 SPI,2 个 WDT,16 个外部中断(和 GPIO 共用 IO)
|
||||
- 集成温度传感器
|
||||
|
||||
### 2. BSP 外设支持
|
||||
|
||||
| 外设名 | 支持情况 | 备注 |
|
||||
| -------- | -------- | ---------------------- |
|
||||
| ft_gicv3 | 支持 | gicv3 中断控制器 |
|
||||
| ft_gmac | 支持 | ft gmac 千兆网卡控制器 |
|
||||
| ft_i2c | 支持 | FT I2C |
|
||||
| ft_qspi | 支持 | FT qspi 控制器 |
|
||||
| ft_sd | 支持 | FT mmcsd 控制器 |
|
||||
| ft_uart | 支持 | PrimeCell PL011 |
|
||||
| ft_spi | 支持 | FT spi 控制器 |
|
||||
| ft_gpio | 支持 | FT gpio 控制器 |
|
||||
| ft_can | 支持 | FT can 控制器 |
|
||||
|
||||
### 3. 使用方法
|
||||
|
||||
#### ubuntu 上环境搭建
|
||||
|
||||
1. 在 ubuntu 环境下通过指令,下载并安装交叉编译链
|
||||
|
||||
```
|
||||
sudo apt-get install gcc-arm-none-eabi
|
||||
```
|
||||
|
||||
2. 安装之后,通过指令,确定交叉编译链安装完毕
|
||||
|
||||
```
|
||||
arm-none-eabi-gcc -v
|
||||
```
|
||||
|
||||
3. 搭建 tftp 环境
|
||||
|
||||
- 在主机安装 tftp 服务
|
||||
> 使用 ubuntu 完成下列操作
|
||||
|
||||
```
|
||||
sudo apt-get install tftp-hpa tftpd-hpa
|
||||
sudo apt-get install xinetd
|
||||
```
|
||||
|
||||
- 新建 tftboot 目录,如:
|
||||
`/mnt/d/tftboot`
|
||||
|
||||
> 需要给 tftboot 目录执行权限`chmod 777 /**/tftboot`
|
||||
|
||||
- 配置主机 tftpboot 服务
|
||||
|
||||
新建并配置文件/etc/xinetd.d/tftp
|
||||
|
||||
```
|
||||
# /etc/xinetd.d/tftp
|
||||
|
||||
server tftp
|
||||
{
|
||||
socket_type = dgram
|
||||
protocol = udp
|
||||
wait = yes
|
||||
user = root
|
||||
server = /usr/sbin/in.tftpd
|
||||
server_args = -s /mnt/d/tftboot
|
||||
disable = no
|
||||
per_source = 11
|
||||
cps = 100 2
|
||||
flags = IPv4
|
||||
}
|
||||
```
|
||||
|
||||
- 启动主机 tftp 服务
|
||||
|
||||
```
|
||||
sudo service tftpd-hpa start
|
||||
```
|
||||
|
||||
- 修改主机 tftp 配置
|
||||
修改/etc/default/tftpd-hpa
|
||||
|
||||
```
|
||||
sudo nano /etc/default/tftpd-hpa
|
||||
# /etc/default/tftpd-hpa
|
||||
|
||||
TFTP_USERNAME="tftp"
|
||||
TFTP_DIRECTORY="/mnt/d/tftboot"
|
||||
TFTP_ADDRESS=":69"
|
||||
TFTP_OPTIONS="-l -c -s"
|
||||
```
|
||||
|
||||
- 重启主机 tftp 服务
|
||||
> 每次开机要重启一次
|
||||
|
||||
```
|
||||
sudo service tftpd-hpa restart
|
||||
```
|
||||
|
||||
- 测试主机 tftp 服务的可用性
|
||||
> 登录 tftp 服务,获取一个文件
|
||||
|
||||
```
|
||||
$ tftp 192.168.4.50
|
||||
tftp> get test1234
|
||||
tftp> q
|
||||
```
|
||||
|
||||
#### 执行
|
||||
|
||||
1. 将本 bsp 包拷贝至 RT-THREAD bsp/目录下
|
||||
|
||||
1. 在 Ubuntu 终端下,切换至 bsp 目录
|
||||
|
||||
```
|
||||
cd rt-thread/bsp/ft2004
|
||||
```
|
||||
|
||||
3. 使用 scons -c 清空工程缓存
|
||||
|
||||
4. 使用 scons --menuconfig 配置需要的外设
|
||||
|
||||

|
||||
|
||||
5. 使用 scons 编译代码,得到 rtthread.bin,并将 rtthread.bin 放入之前配置的 tftp 路径下。
|
||||
|
||||
6. 连接开发板对应串口到 PC, 在终端工具里打开相应的串口(115200-8-1-N)。
|
||||
|
||||
7. 将开发板网线接入局域网中
|
||||
|
||||
8. 本开发板自带 uboot,使用 uboot 自带 指令进行将 bin 文件下载至 ram 中
|
||||
|
||||
```
|
||||
setenv ipaddr 192.168.x.x # 设置开发板ip
|
||||
setenv serverip 192.168.x.x # 设置tftp服务器ip
|
||||
setenv gatewayip 192.168.x.x # 设置网关ip
|
||||
tftpboot 80100000 rtthread.bin # 在主机 /tftpboot目录中的rtthread.bin文件下载到开发板内存的80100000地址中。
|
||||
```
|
||||
|
||||
7. 执行跳转指令,便可以正常执行
|
||||
|
||||
```
|
||||
bootvx32 80100000
|
||||
或
|
||||
boot32 80100000
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 5. 相关实验
|
||||
|
||||
#### 网卡
|
||||
|
||||
- 主机 ping 本机 指令 sudo ping 192.168.3.20 (默认)
|
||||
|
||||
- rtt ping 主机 指令 ping 192.168.x.x (根据实际情况)
|
||||
|
||||
- 通过界面
|
||||
|
||||

|
||||
|
||||
#### sd 卡调试
|
||||
|
||||
- 通过基本命令进行,mv ,echo ,ls ,cd ,rm ....
|
||||
|
||||

|
||||
|
||||
#### spi flash 卡调试
|
||||
|
||||
- 找一块有 spi flash 插槽的 ft-2004 开发板,插入 sf25s 或 gd25q 系列 spi flash
|
||||
- 配置 rt-thread 的编译选项,打开 BSP_USE_SPI 和 BSP_USE_GPIO 配置,关闭 BSP_USE_QSPI 配置,打开 rt-thread 的 SFUD 调试开关
|
||||
- 编译 rt-thread,加载版本启动,启动后显示 spi flash probe 成功
|
||||
- 执行 sf 基本操作,read, write, erase
|
||||
|
||||
#### 推荐指令
|
||||
|
||||
1. sf probe S25FS256
|
||||
|
||||
2. sf read 0x1FFF000 16
|
||||
|
||||
3. sf write 0x1FFF000 16 25 68 78 95 15 75 20
|
||||
|
||||
4. sf read 0x1FFF000 16
|
||||
|
||||
5. sf erase 0x1FFF000 16
|
||||
|
||||
#### can 测试
|
||||
|
||||
1. 使用 scons menuconfig 选中 Enable Can
|
||||
|
||||
2. 然后选中 Enable can0 ,Enable can0 work in loop back
|
||||
|
||||
3. 烧录程序并且烧录
|
||||
|
||||
4. 打开 can 盒,将波特率设为 1000000
|
||||
|
||||
5. 然后通过 can 盒发送对应的数据(标准帧,扩展帧),就可以看见回复同样的内容
|
||||
|
||||
## 6. 参考资源
|
||||
|
||||
- ARM Architecture Reference Manual
|
||||
|
||||
- FT-2000/4 软件编程手册-V1.4
|
||||
|
||||
## 7. 联系人信息
|
||||
|
||||
请联系飞腾嵌入式软件部
|
||||
|
||||
huanghe@phytium.com.cn
|
||||
|
||||
zhugengyu@phytium.com.cn
|
||||
14
bsp/ft2004/SConscript
Normal file
14
bsp/ft2004/SConscript
Normal file
@@ -0,0 +1,14 @@
|
||||
# for module compiling
|
||||
import os
|
||||
Import('RTT_ROOT')
|
||||
|
||||
cwd = str(Dir('#'))
|
||||
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')
|
||||
32
bsp/ft2004/SConstruct
Normal file
32
bsp/ft2004/SConstruct
Normal file
@@ -0,0 +1,32 @@
|
||||
import os
|
||||
import sys
|
||||
import rtconfig
|
||||
|
||||
if os.getenv('RTT_ROOT'):
|
||||
RTT_ROOT = os.getenv('RTT_ROOT')
|
||||
else:
|
||||
RTT_ROOT = os.path.join(os.getcwd(), '..', '..')
|
||||
|
||||
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
|
||||
from building import *
|
||||
|
||||
TARGET = 'ft2004.' + rtconfig.TARGET_EXT
|
||||
|
||||
DefaultEnvironment(tools=[])
|
||||
env = Environment(tools = ['mingw'],
|
||||
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
|
||||
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
|
||||
CXX= rtconfig.CXX, CXXFLAGS = rtconfig.CFLAGS,
|
||||
AR = rtconfig.AR, ARFLAGS = '-rc',
|
||||
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
|
||||
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
|
||||
env['ASCOM'] = env['ASPPCOM']
|
||||
|
||||
Export('RTT_ROOT')
|
||||
Export('rtconfig')
|
||||
|
||||
# prepare building environment
|
||||
objs = PrepareBuilding(env, RTT_ROOT)
|
||||
|
||||
# make a building
|
||||
DoBuilding(TARGET, objs)
|
||||
11
bsp/ft2004/applications/SConscript
Normal file
11
bsp/ft2004/applications/SConscript
Normal file
@@ -0,0 +1,11 @@
|
||||
Import('RTT_ROOT')
|
||||
Import('rtconfig')
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
77
bsp/ft2004/applications/main.c
Normal file
77
bsp/ft2004/applications/main.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2012-12-05 Bernard the first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include "ft_cpu.h"
|
||||
#include "ft_generic_timer.h"
|
||||
|
||||
#include <board.h>
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
|
||||
struct rt_thread test_core[RT_CPUS_NR];
|
||||
static char *core_thread_name[RT_CPUS_NR] = {
|
||||
"core0_test",
|
||||
"core1_test",
|
||||
"core2_test",
|
||||
"core3_test"};
|
||||
static rt_uint8_t core_stack[RT_CPUS_NR][1024];
|
||||
|
||||
static void demo_core_thread(void *parameter)
|
||||
{
|
||||
rt_base_t level;
|
||||
while (1)
|
||||
{
|
||||
/* code */
|
||||
level = rt_cpus_lock();
|
||||
rt_kprintf("Hi, core%d \r\n", FCpu_IdGet());
|
||||
rt_cpus_unlock(level);
|
||||
rt_thread_mdelay(20000);
|
||||
}
|
||||
}
|
||||
|
||||
void demo_core(void)
|
||||
{
|
||||
rt_ubase_t i;
|
||||
rt_uint8_t cpu_id = 0;
|
||||
for (i = 0; i < RT_CPUS_NR; i++)
|
||||
{
|
||||
cpu_id = i;
|
||||
rt_thread_init(&test_core[i],
|
||||
core_thread_name[i],
|
||||
demo_core_thread,
|
||||
RT_NULL,
|
||||
&core_stack[i],
|
||||
1024,
|
||||
20,
|
||||
32);
|
||||
|
||||
rt_thread_control(&test_core[i], RT_THREAD_CTRL_BIND_CPU, (void *)cpu_id);
|
||||
rt_thread_startup(&test_core[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int count = 1;
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
demo_core();
|
||||
#endif
|
||||
|
||||
while (count++)
|
||||
{
|
||||
rt_thread_mdelay(2000);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
14
bsp/ft2004/drivers/SConscript
Normal file
14
bsp/ft2004/drivers/SConscript
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.S')
|
||||
src += Glob('*.c')
|
||||
|
||||
|
||||
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
155
bsp/ft2004/drivers/board.c
Normal file
155
bsp/ft2004/drivers/board.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-03-04 Carl the first version
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "ft_printf.h"
|
||||
#include "ft_assert.h"
|
||||
#include "ft_cpu.h"
|
||||
#include "ft_psci.h"
|
||||
#include "ft_parameters.h"
|
||||
#include "board.h"
|
||||
#include "gtimer.h"
|
||||
#include "ft_generic_timer.h"
|
||||
#include <gicv3.h>
|
||||
|
||||
#include "interrupt.h"
|
||||
#include <mmu.h>
|
||||
#include "cp15.h"
|
||||
#include "ft2004.h"
|
||||
|
||||
#define DDR_MEM (SHARED | AP_RW | DOMAIN0 | MEMWT | DESC_SEC)
|
||||
|
||||
struct mem_desc platform_mem_desc[] = {
|
||||
{0x80000000,
|
||||
0x80000000 + 0x7f000000,
|
||||
0x80000000,
|
||||
DDR_MEM},
|
||||
{0, //< QSPI
|
||||
0x1FFFFFFF,
|
||||
0,
|
||||
DEVICE_MEM},
|
||||
{0x20000000, //<! LPC
|
||||
0x27FFFFFF,
|
||||
0x20000000,
|
||||
DEVICE_MEM},
|
||||
{FT_DEV_BASE_ADDR, //<! Device register
|
||||
FT_DEV_END_ADDR,
|
||||
FT_DEV_BASE_ADDR,
|
||||
DEVICE_MEM},
|
||||
{0x30000000, //<! debug
|
||||
0x39FFFFFF,
|
||||
0x30000000,
|
||||
DEVICE_MEM},
|
||||
{0x3A000000, //<! Internal register space in the on-chip network
|
||||
0x3AFFFFFF,
|
||||
0x3A000000,
|
||||
DEVICE_MEM},
|
||||
{FT_PCI_CONFIG_BASEADDR,
|
||||
FT_PCI_CONFIG_BASEADDR + FT_PCI_CONFIG_REG_LENGTH,
|
||||
FT_PCI_CONFIG_BASEADDR,
|
||||
DEVICE_MEM},
|
||||
{FT_PCI_IO_CONFIG_BASEADDR,
|
||||
FT_PCI_IO_CONFIG_BASEADDR + FT_PCI_IO_CONFIG_REG_LENGTH,
|
||||
FT_PCI_IO_CONFIG_BASEADDR,
|
||||
DEVICE_MEM},
|
||||
{FT_PCI_MEM32_BASEADDR,
|
||||
FT_PCI_MEM32_BASEADDR + FT_PCI_MEM32_REG_LENGTH,
|
||||
FT_PCI_MEM32_BASEADDR,
|
||||
DEVICE_MEM},
|
||||
};
|
||||
|
||||
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]);
|
||||
|
||||
rt_uint32_t platform_get_gic_dist_base(void)
|
||||
{
|
||||
return FT_GICV3_DISTRIBUTOR_BASEADDRESS;
|
||||
}
|
||||
|
||||
static rt_uint32_t timerStep;
|
||||
|
||||
void rt_hw_timer_isr(int vector, void *parameter)
|
||||
{
|
||||
gtimer_set_load_value(timerStep);
|
||||
rt_tick_increase();
|
||||
}
|
||||
|
||||
int rt_hw_timer_init(void)
|
||||
{
|
||||
rt_hw_interrupt_install(30, rt_hw_timer_isr, RT_NULL, "tick");
|
||||
rt_hw_interrupt_umask(30);
|
||||
timerStep = gtimer_get_counter_frequency();
|
||||
timerStep /= RT_TICK_PER_SECOND;
|
||||
gtimer_set_load_value(timerStep);
|
||||
gtimer_set_control(1);
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_timer_init);
|
||||
|
||||
static void AssertCallback(const char *File, s32 Line)
|
||||
{
|
||||
Ft_printf("Assert Error is %s : %d \r\n", File, Line);
|
||||
}
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will initialize hardware board
|
||||
*/
|
||||
void rt_hw_board_init(void)
|
||||
{
|
||||
/* bsp debug */
|
||||
FCpu_SpinLockInit();
|
||||
Ft_GenericTimer_Init(0, RT_NULL);
|
||||
Ft_vsprintfRegister((vsprintf_p)rt_vsprintf);
|
||||
Ft_assertSetCallBack((Ft_assertCallback)AssertCallback);
|
||||
|
||||
/* interrupt init */
|
||||
arm_gic_redist_address_set(0, FT_GICV3_RD_BASEADDRESS + 0, 0);
|
||||
|
||||
#if RT_CPUS_NR == 2
|
||||
Ft_printf("arm_gic_redist_address_set is 2 \r\n");
|
||||
arm_gic_redist_address_set(0, FT_GICV3_RD_BASEADDRESS + (2U << 16), 1);
|
||||
#elif RT_CPUS_NR == 3
|
||||
arm_gic_redist_address_set(0, FT_GICV3_RD_BASEADDRESS + (2U << 16), 1);
|
||||
arm_gic_redist_address_set(0, FT_GICV3_RD_BASEADDRESS + 2 * (2U << 16), 2);
|
||||
#elif RT_CPUS_NR == 4
|
||||
arm_gic_redist_address_set(0, FT_GICV3_RD_BASEADDRESS + (2U << 16), 1);
|
||||
arm_gic_redist_address_set(0, FT_GICV3_RD_BASEADDRESS + 2 * (2U << 16), 2);
|
||||
arm_gic_redist_address_set(0, FT_GICV3_RD_BASEADDRESS + 3 * (2U << 16), 3);
|
||||
#endif
|
||||
|
||||
rt_hw_interrupt_init();
|
||||
|
||||
rt_components_board_init();
|
||||
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
|
||||
/* 初始化内存池 */
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_system_heap_init(HEAP_BEGIN, HEAP_END);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
/* install IPI handle */
|
||||
rt_hw_interrupt_set_priority(RT_SCHEDULE_IPI, 16);
|
||||
rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler);
|
||||
rt_hw_interrupt_umask(RT_SCHEDULE_IPI);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ft_reset(void)
|
||||
{
|
||||
FPsci_Reset();
|
||||
}
|
||||
MSH_CMD_EXPORT_ALIAS(ft_reset, ft_reset, ft_reset);
|
||||
|
||||
/*@}*/
|
||||
29
bsp/ft2004/drivers/board.h
Normal file
29
bsp/ft2004/drivers/board.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2013-07-06 Bernard the first version
|
||||
*/
|
||||
|
||||
#ifndef __BOARD_H__
|
||||
#define __BOARD_H__
|
||||
|
||||
#include "ft_parameters.h"
|
||||
#include "ft2004.h"
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
extern int Image$$RW_IRAM1$$ZI$$Limit;
|
||||
#define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit)
|
||||
#elif defined(__GNUC__)
|
||||
extern int __bss_end;
|
||||
#define HEAP_BEGIN ((void *)&__bss_end)
|
||||
#endif
|
||||
|
||||
#define HEAP_END (void *)(0x80000000 + 1024 * 1024 * 1024)
|
||||
|
||||
void rt_hw_board_init(void);
|
||||
|
||||
#endif
|
||||
270
bsp/ft2004/drivers/drv_can.c
Normal file
270
bsp/ft2004/drivers/drv_can.c
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-05-11 Carl the first version
|
||||
*/
|
||||
|
||||
#include "drv_can.h"
|
||||
#include "interrupt.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef BSP_USE_CAN
|
||||
|
||||
#define LOG_TAG "drv_can"
|
||||
#include <drv_log.h>
|
||||
|
||||
#define _CAN0_NAME "can0"
|
||||
#define _CAN1_NAME "can1"
|
||||
|
||||
#define RTHW_CAN_WAIT(_can) rt_sem_take(&_can->recv_semaphore, RT_WAITING_FOREVER);
|
||||
#define RTHW_CAN_SEND(_can) rt_sem_release(&_can->recv_semaphore);
|
||||
|
||||
#ifdef BSP_USING_CAN0
|
||||
struct ft2004_can drv_can0 =
|
||||
{
|
||||
.name = _CAN0_NAME,
|
||||
.can_handle.Config.InstanceId = 0};
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_CAN1
|
||||
struct ft2004_can drv_can1 =
|
||||
{
|
||||
.name = _CAN1_NAME,
|
||||
.can_handle.Config.InstanceId = 1};
|
||||
#endif
|
||||
|
||||
static void _can_recv_irq(void *args)
|
||||
{
|
||||
struct ft2004_can *drv_can = (struct ft2004_can *)args;
|
||||
RTHW_CAN_SEND(drv_can);
|
||||
}
|
||||
|
||||
static void rt_hw_inner_can_isr(int irqno, void *param)
|
||||
{
|
||||
FCan_IntrHandler(param);
|
||||
}
|
||||
|
||||
static rt_err_t _can_config(struct rt_can_device *can, struct can_configure *cfg)
|
||||
{
|
||||
struct FCan_Bittiming bit_timing = {0};
|
||||
struct ft2004_can *drv_can;
|
||||
RT_ASSERT(can);
|
||||
RT_ASSERT(cfg);
|
||||
drv_can = (struct ft2004_can *)can->parent.user_data;
|
||||
RT_ASSERT(drv_can);
|
||||
|
||||
FCan_CfgInitialize(&drv_can->can_handle, FCan_LookupConfig(drv_can->can_handle.Config.InstanceId));
|
||||
|
||||
FCan_SetHandler(&drv_can->can_handle, FCAN_HANDLER_RECV, _can_recv_irq, drv_can);
|
||||
|
||||
bit_timing.bitrate = cfg->baud_rate;
|
||||
|
||||
if (FCan_CalcBittiming(&bit_timing) != FCAN_SUCCESS)
|
||||
{
|
||||
LOG_E("Setting baud rate %x is not valid \r\n", bit_timing.bitrate);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
FCan_SetTiming(&drv_can->can_handle, &bit_timing);
|
||||
|
||||
rt_hw_interrupt_set_priority(drv_can->can_handle.Config.IrqNum, 16);
|
||||
rt_hw_interrupt_install(drv_can->can_handle.Config.IrqNum, rt_hw_inner_can_isr, &drv_can->can_handle, drv_can->name);
|
||||
rt_hw_interrupt_umask(drv_can->can_handle.Config.IrqNum);
|
||||
|
||||
FCan_Enable(&drv_can->can_handle);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
|
||||
{
|
||||
struct ft2004_can *drv_can;
|
||||
struct rt_can_msg *pmsg = (struct rt_can_msg *)buf;
|
||||
struct FCan_Frame can_frame = {0};
|
||||
RT_ASSERT(can);
|
||||
drv_can = (struct ft2004_can *)can->parent.user_data;
|
||||
RT_ASSERT(drv_can);
|
||||
|
||||
/* Check the parameters */
|
||||
RT_ASSERT(pmsg->len <= 8U);
|
||||
|
||||
if (RT_CAN_STDID == pmsg->ide)
|
||||
{
|
||||
can_frame.CanId = pmsg->id;
|
||||
}
|
||||
else
|
||||
{
|
||||
can_frame.CanId = pmsg->id;
|
||||
can_frame.CanId |= CAN_EFF_FLAG;
|
||||
}
|
||||
|
||||
if (RT_CAN_DTR == pmsg->rtr)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
can_frame.CanId |= CAN_RTR_FLAG;
|
||||
}
|
||||
|
||||
can_frame.CanDlc = pmsg->len & 0x0FU;
|
||||
memcpy(can_frame.data, pmsg->data, 8);
|
||||
|
||||
return (FCan_SendByIrq(&drv_can->can_handle, &can_frame, 1, RT_NULL) == 1) ? RT_EOK : -RT_ERROR;
|
||||
}
|
||||
|
||||
static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
|
||||
{
|
||||
struct ft2004_can *drv_can;
|
||||
struct rt_can_msg *pmsg = (struct rt_can_msg *)buf;
|
||||
RT_ASSERT(can);
|
||||
struct FCan_Frame recv_frame = {0};
|
||||
drv_can = (struct ft2004_can *)can->parent.user_data;
|
||||
RT_ASSERT(drv_can);
|
||||
|
||||
RTHW_CAN_WAIT(drv_can);
|
||||
|
||||
if (FCan_RecvByIrq(&drv_can->can_handle, &recv_frame, 1) == 0)
|
||||
{
|
||||
LOG_E("rx msg is error");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
if (CAN_EFF_FLAG & recv_frame.CanId)
|
||||
{
|
||||
pmsg->ide = RT_CAN_EXTID;
|
||||
pmsg->id = (recv_frame.CanId & ~(RT_CAN_EXTID));
|
||||
}
|
||||
else
|
||||
{
|
||||
pmsg->ide = RT_CAN_STDID;
|
||||
pmsg->id = recv_frame.CanId;
|
||||
}
|
||||
|
||||
if (CAN_RTR_FLAG & recv_frame.CanId)
|
||||
{
|
||||
pmsg->id &= ~CAN_RTR_FLAG;
|
||||
pmsg->rtr = RT_CAN_RTR;
|
||||
}
|
||||
else
|
||||
{
|
||||
pmsg->rtr = RT_CAN_DTR;
|
||||
}
|
||||
|
||||
/* get len */
|
||||
pmsg->len = recv_frame.CanDlc;
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static const struct rt_can_ops _can_ops =
|
||||
{
|
||||
_can_config,
|
||||
_can_control,
|
||||
_can_sendmsg,
|
||||
_can_recvmsg,
|
||||
};
|
||||
|
||||
int rt_hw_can_init(void)
|
||||
{
|
||||
#ifdef BSP_USING_CAN0
|
||||
drv_can0.can_handle.Config.InstanceId = 0;
|
||||
rt_sem_init(&drv_can0.recv_semaphore, "can0_recv", 0, RT_IPC_FLAG_FIFO);
|
||||
drv_can0.device.config.ticks = 20000;
|
||||
drv_can0.device.config.baud_rate = 1000000;
|
||||
rt_hw_can_register(&drv_can0.device,
|
||||
drv_can0.name,
|
||||
&_can_ops,
|
||||
&drv_can0);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_CAN1
|
||||
drv_can1.can_handle.Config.InstanceId = 1;
|
||||
drv_can0.device.config.baud_rate = 1000000;
|
||||
rt_sem_init(&drv_can1.recv_semaphore, "can1_recv", 0, RT_IPC_FLAG_FIFO);
|
||||
rt_hw_can_register(&drv_can1.device,
|
||||
drv_can1.name,
|
||||
&_can_ops,
|
||||
&drv_can1);
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_BOARD_EXPORT(rt_hw_can_init);
|
||||
|
||||
#ifdef BSP_USING_CAN0_DEBUG
|
||||
|
||||
struct can_test_struct
|
||||
{
|
||||
const char *name;
|
||||
struct rt_can_filter_config *filter;
|
||||
rt_device_t candev;
|
||||
struct rt_semaphore _sem;
|
||||
};
|
||||
|
||||
static struct can_test_struct can0_test_obj = {
|
||||
.name = _CAN0_NAME};
|
||||
|
||||
void can_recv_irq(void *param)
|
||||
{
|
||||
struct can_test_struct *_can_obj = (struct can_test_struct *)param;
|
||||
rt_kprintf("can_recv_iqr \r\n");
|
||||
rt_sem_release(&_can_obj->_sem);
|
||||
}
|
||||
|
||||
static void rt_can_test_loopback_thread_entry(void *param)
|
||||
{
|
||||
struct can_test_struct *_can_obj = (struct can_test_struct *)param;
|
||||
struct FCan_Frame recv_frame;
|
||||
struct ft2004_can *drv_can;
|
||||
rt_uint32_t i;
|
||||
_can_obj->candev = rt_device_find(_can_obj->name);
|
||||
RT_ASSERT(_can_obj->candev);
|
||||
drv_can = (struct ft2004_can *)_can_obj->candev->user_data;
|
||||
rt_sem_init(&_can_obj->_sem, "canrx_wait", 0, RT_IPC_FLAG_FIFO);
|
||||
rt_device_open(_can_obj->candev, RT_DEVICE_OFLAG_RDWR);
|
||||
|
||||
while (1)
|
||||
{
|
||||
rt_kprintf(" start to wait loopback \r\n");
|
||||
RTHW_CAN_WAIT(drv_can);
|
||||
while (0 != FCan_RecvByIrq(&drv_can->can_handle, &recv_frame, 1))
|
||||
{
|
||||
rt_kprintf("CanId %x \r\n", recv_frame.CanId);
|
||||
rt_kprintf("CanDlc %x \r\n", recv_frame.CanDlc);
|
||||
for (i = 0; i < recv_frame.CanDlc; i++)
|
||||
{
|
||||
rt_kprintf("data [%d] %x \r\n", i, recv_frame.data[i]);
|
||||
}
|
||||
FCan_SendByIrq(&drv_can->can_handle, &recv_frame, 1, RT_NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int rt_can0_test(void)
|
||||
{
|
||||
rt_thread_t tid;
|
||||
|
||||
tid = rt_thread_create("can0_loopback",
|
||||
rt_can_test_loopback_thread_entry, &can0_test_obj,
|
||||
1024, 16, 20);
|
||||
if (tid != RT_NULL)
|
||||
rt_thread_startup(tid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_APP_EXPORT(rt_can0_test);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
38
bsp/ft2004/drivers/drv_can.h
Normal file
38
bsp/ft2004/drivers/drv_can.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-05-11 Carl the first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_CAN_H__
|
||||
#define __DRV_CAN_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <board.h>
|
||||
#include <rtdevice.h>
|
||||
#include <rtthread.h>
|
||||
#include "ft_can.h"
|
||||
|
||||
struct ft2004_can
|
||||
{
|
||||
const char *name;
|
||||
FCan_t can_handle;
|
||||
struct rt_semaphore recv_semaphore;
|
||||
struct rt_can_device device; /* inherit from can device */
|
||||
};
|
||||
|
||||
int rt_hw_can_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !
|
||||
691
bsp/ft2004/drivers/drv_eth.c
Normal file
691
bsp/ft2004/drivers/drv_eth.c
Normal file
File diff suppressed because it is too large
Load Diff
25
bsp/ft2004/drivers/drv_eth.h
Normal file
25
bsp/ft2004/drivers/drv_eth.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-03-09 Carl the first version
|
||||
*/
|
||||
#ifndef __DRV_ETH_H__
|
||||
#define __DRV_ETH_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define FT_NETIF_LINKUP 0x1U
|
||||
#define FT_NETIF_DOWN 0x2U
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !
|
||||
27
bsp/ft2004/drivers/drv_log.h
Normal file
27
bsp/ft2004/drivers/drv_log.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-15 SummerGift first version
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: DO NOT include this file on the header file.
|
||||
*/
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#define DBG_TAG "drv"
|
||||
#else
|
||||
#define DBG_TAG LOG_TAG
|
||||
#endif /* LOG_TAG */
|
||||
|
||||
#ifdef DRV_DEBUG
|
||||
#define DBG_LVL DBG_LOG
|
||||
#else
|
||||
#define DBG_LVL DBG_INFO
|
||||
#endif /* DRV_DEBUG */
|
||||
|
||||
#include <rtdbg.h>
|
||||
424
bsp/ft2004/drivers/drv_qspi.c
Normal file
424
bsp/ft2004/drivers/drv_qspi.c
Normal file
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-04-11 Carl the first version
|
||||
*/
|
||||
|
||||
#include "drv_qspi.h"
|
||||
#include <rtthread.h>
|
||||
#include "rtdevice.h"
|
||||
#include "ft_qspi.h"
|
||||
#include "ft_parameters.h"
|
||||
|
||||
#ifdef BSP_USE_QSPI
|
||||
|
||||
#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.qspi"
|
||||
#include <drv_log.h>
|
||||
|
||||
struct ft2004_qspi_bus
|
||||
{
|
||||
FQSpi_t fqspi;
|
||||
char *name;
|
||||
rt_uint32_t init; /* 1 is init already */
|
||||
};
|
||||
|
||||
static struct rt_spi_bus _qspi_bus;
|
||||
static struct ft2004_qspi_bus _ft2004_qspi_bus;
|
||||
|
||||
static int ft2004_qspi_init(struct rt_qspi_device *device, struct rt_qspi_configuration *qspi_cfg)
|
||||
{
|
||||
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(qspi_cfg != RT_NULL);
|
||||
|
||||
// struct rt_spi_configuration *cfg = &qspi_cfg->parent;
|
||||
struct ft2004_qspi_bus *qspi_bus_p = device->parent.bus->parent.user_data;
|
||||
|
||||
if (qspi_bus_p->init == 0)
|
||||
{
|
||||
qspi_bus_p->init = 1;
|
||||
FQSpi_CfgInitialize(&qspi_bus_p->fqspi, FQSpi_LookupConfig(0));
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t ft2004_cmdOperation(struct ft2004_qspi_bus *qspi_bus_p, struct rt_spi_message *message)
|
||||
{
|
||||
struct rt_qspi_message *qspi_message = (struct rt_qspi_message *)message;
|
||||
const rt_uint8_t *sndb = message->send_buf;
|
||||
rt_uint8_t *rcvb = message->recv_buf;
|
||||
ft_error_t ret;
|
||||
RT_ASSERT(qspi_bus_p != RT_NULL);
|
||||
RT_ASSERT(message != RT_NULL);
|
||||
|
||||
struct FQSpi_CmdPack cmd_pack = {0};
|
||||
|
||||
if (qspi_message->instruction.qspi_lines == 0)
|
||||
{
|
||||
LOG_E("instruction is not valid");
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
cmd_pack.cmd = qspi_message->instruction.content;
|
||||
|
||||
if (qspi_message->address.qspi_lines != 0)
|
||||
{
|
||||
cmd_pack.flags |= FQSPI_CMD_NEED_ADDR_MASK;
|
||||
cmd_pack.addr = qspi_message->address.content;
|
||||
}
|
||||
|
||||
if (qspi_message->address.size == 24)
|
||||
{
|
||||
cmd_pack.flags |= FQSPI_CMD_ADDRESS_3BYTE_MASK;
|
||||
}
|
||||
else if (qspi_message->address.size == 32)
|
||||
{
|
||||
cmd_pack.flags |= FQSPI_CMD_ADDRESS_4BYTE_MASK;
|
||||
}
|
||||
|
||||
if (qspi_message->qspi_data_lines != 0)
|
||||
{
|
||||
if (sndb && (message->length > 0))
|
||||
{
|
||||
cmd_pack.flags |= FQSPI_CMD_NEED_SET_MASK;
|
||||
cmd_pack.txBuf = sndb;
|
||||
cmd_pack.length = message->length;
|
||||
}
|
||||
else if (rcvb && (message->length > 0))
|
||||
{
|
||||
cmd_pack.flags |= FQSPI_CMD_NEED_GET_MASK;
|
||||
cmd_pack.rxBuf = rcvb;
|
||||
cmd_pack.length = message->length;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd_pack.flags &= ~(FQSPI_CMD_NEED_GET_MASK | FQSPI_CMD_NEED_SET_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
if (qspi_message->dummy_cycles)
|
||||
{
|
||||
cmd_pack.flags |= FQSPI_CMD_NEED_DUMMY_MASK;
|
||||
cmd_pack.dummyCycle = qspi_message->dummy_cycles;
|
||||
}
|
||||
|
||||
if (cmd_pack.cmd == 0x20)
|
||||
{
|
||||
if (qspi_message->address.size == 32)
|
||||
{
|
||||
cmd_pack.cmd = 0xdc;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSP_QSPI_DEBUG
|
||||
LOG_I("flags %x", cmd_pack.flags);
|
||||
#endif
|
||||
|
||||
ret = FQSpi_CmdOperation(&qspi_bus_p->fqspi, &cmd_pack);
|
||||
|
||||
#ifdef BSP_QSPI_DEBUG
|
||||
if (ret == FQSPI_SUCCESS)
|
||||
if (cmd_pack.cmd == 5)
|
||||
{
|
||||
LOG_I("cmd05 0x%x", cmd_pack.rxBuf[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (ret == FQSPI_SUCCESS) ? RT_EOK : RT_ERROR;
|
||||
}
|
||||
|
||||
static rt_uint32_t ft2004_qspi_xfer(struct ft2004_qspi_bus *qspi_bus_p, struct rt_spi_message *message)
|
||||
{
|
||||
struct rt_qspi_message *qspi_message = (struct rt_qspi_message *)message;
|
||||
rt_uint32_t ret_length = 0;
|
||||
const rt_uint8_t *sndb = message->send_buf;
|
||||
rt_uint8_t *rcvb = message->recv_buf;
|
||||
rt_int32_t length = message->length;
|
||||
rt_uint32_t cmd;
|
||||
rt_uint32_t addr;
|
||||
FQSpi_t *qspi_p;
|
||||
FQSpi_Config_t *qspi_config_p;
|
||||
struct FQSpi_DataPack data_pack = {0};
|
||||
qspi_p = &qspi_bus_p->fqspi;
|
||||
qspi_config_p = &qspi_bus_p->fqspi.config;
|
||||
|
||||
cmd = qspi_message->instruction.content;
|
||||
addr = qspi_message->address.content;
|
||||
|
||||
#ifdef BSP_QSPI_DEBUG
|
||||
LOG_I("cmd is %x ", cmd);
|
||||
LOG_I("length %d , rcvb %x sndb %x addr %x dummy_cycles %x ", length, rcvb, sndb, addr, qspi_message->dummy_cycles);
|
||||
#endif
|
||||
|
||||
if (qspi_config_p->channel >= FT_QSPI_MAX_CS_NUM)
|
||||
{
|
||||
LOG_E("invalid channel[%x] ", qspi_config_p->channel);
|
||||
return RT_ERROR;
|
||||
}
|
||||
switch (cmd)
|
||||
{
|
||||
case FQSPI_FLASH_CMD_PP:
|
||||
{
|
||||
if (RT_NULL != sndb)
|
||||
{
|
||||
data_pack.cmd = cmd;
|
||||
data_pack.addr = addr;
|
||||
if (qspi_message->address.size == 24)
|
||||
{
|
||||
data_pack.flags |= FQSPI_DATA_ADDRESS_3BYTE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
data_pack.flags |= FQSPI_DATA_ADDRESS_4BYTE_MASK;
|
||||
}
|
||||
|
||||
LOG_E("write flags %x ", data_pack.flags);
|
||||
data_pack.txBuf = sndb;
|
||||
data_pack.length = length;
|
||||
ret_length = ((FQSpi_Write(qspi_p, &data_pack) == FQSPI_SUCCESS) ? length : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("pp cmd %x sndb is null", cmd);
|
||||
ret_length = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FQSPI_FLASH_CMD_WRDI: /* for sufd qspi fast read */
|
||||
FQSpi_FlashRegSet(qspi_p, cmd, RT_NULL, 0);
|
||||
case FQSPI_FLASH_CMD_READ:
|
||||
{
|
||||
if (RT_NULL != rcvb)
|
||||
{
|
||||
data_pack.cmd = FQSPI_FLASH_CMD_READ;
|
||||
data_pack.addr = addr;
|
||||
if (qspi_message->address.size == 24)
|
||||
{
|
||||
data_pack.flags |= FQSPI_DATA_ADDRESS_3BYTE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
data_pack.flags |= FQSPI_DATA_ADDRESS_4BYTE_MASK;
|
||||
}
|
||||
|
||||
if (qspi_message->dummy_cycles)
|
||||
{
|
||||
data_pack.flags |= FQSPI_DATA_NEED_DUMMY_MASK;
|
||||
data_pack.dummyCycle = qspi_message->dummy_cycles;
|
||||
}
|
||||
data_pack.rxBuf = rcvb;
|
||||
data_pack.length = length;
|
||||
|
||||
ret_length = ((FQSpi_Read(qspi_p, &data_pack) == FQSPI_SUCCESS) ? length : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// LOG_E("read cmd %x rcvb is null", cmd);
|
||||
ret_length = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if (ft2004_cmdOperation(qspi_bus_p, message) == RT_EOK)
|
||||
{
|
||||
ret_length = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("ft2004_cmdOperation error");
|
||||
ret_length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret_length;
|
||||
}
|
||||
|
||||
static rt_uint32_t qspixfer(struct rt_spi_device *device, struct rt_spi_message *message)
|
||||
{
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(device->bus != RT_NULL);
|
||||
struct ft2004_qspi_bus *qspi_bus_p = device->bus->parent.user_data;
|
||||
|
||||
return ft2004_qspi_xfer(qspi_bus_p, message);
|
||||
}
|
||||
|
||||
static rt_err_t qspi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
|
||||
{
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(configuration != RT_NULL);
|
||||
|
||||
struct rt_qspi_device *qspi_device = (struct rt_qspi_device *)device;
|
||||
return ft2004_qspi_init(qspi_device, &qspi_device->config);
|
||||
}
|
||||
|
||||
static const struct rt_spi_ops ft2004_qspi_ops =
|
||||
{
|
||||
.configure = qspi_configure,
|
||||
.xfer = qspixfer,
|
||||
};
|
||||
|
||||
static int ft2004_qspi_register_bus(struct ft2004_qspi_bus *qspi_bus, const char *name)
|
||||
{
|
||||
RT_ASSERT(qspi_bus != RT_NULL);
|
||||
RT_ASSERT(name != RT_NULL);
|
||||
|
||||
_qspi_bus.parent.user_data = qspi_bus;
|
||||
return rt_qspi_bus_register(&_qspi_bus, name, &ft2004_qspi_ops);
|
||||
}
|
||||
|
||||
rt_err_t ft2004_qspi_bus_attach_device(const char *bus_name, const char *device_name, rt_uint8_t data_line_width, void (*enter_qspi_mode)(), void (*exit_qspi_mode)())
|
||||
{
|
||||
struct rt_qspi_device *qspi_device = RT_NULL;
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
RT_ASSERT(bus_name != RT_NULL);
|
||||
RT_ASSERT(device_name != RT_NULL);
|
||||
RT_ASSERT(data_line_width == 1 || data_line_width == 2 || data_line_width == 4);
|
||||
|
||||
qspi_device = (struct rt_qspi_device *)rt_malloc(sizeof(struct rt_qspi_device));
|
||||
if (qspi_device == RT_NULL)
|
||||
{
|
||||
LOG_E("no memory, qspi bus attach device failed!");
|
||||
result = RT_ENOMEM;
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
qspi_device->enter_qspi_mode = enter_qspi_mode;
|
||||
qspi_device->exit_qspi_mode = exit_qspi_mode;
|
||||
qspi_device->config.qspi_dl_width = data_line_width;
|
||||
|
||||
result = rt_spi_bus_attach_device(&qspi_device->parent, device_name, bus_name, RT_NULL);
|
||||
|
||||
__exit:
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
if (qspi_device)
|
||||
{
|
||||
rt_free(qspi_device);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int rt_hw_qspi_bus_init(void)
|
||||
{
|
||||
return ft2004_qspi_register_bus(&_ft2004_qspi_bus, FT2004_QSPI_NAME);
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_qspi_bus_init);
|
||||
#ifdef BSP_QSPI_DEBUG
|
||||
static void cmd05_check(void)
|
||||
{
|
||||
struct FQSpi_CmdPack cmd_pack = {0};
|
||||
u8 rx_buffer[1];
|
||||
|
||||
cmd_pack.cmd = 0x6;
|
||||
FQSpi_CmdOperation(&_ft2004_qspi_bus.fqspi, &cmd_pack);
|
||||
|
||||
rt_memset(&cmd_pack, 0, sizeof(&cmd_pack));
|
||||
cmd_pack.cmd = 0x5;
|
||||
cmd_pack.flags = FQSPI_CMD_NEED_GET_MASK;
|
||||
cmd_pack.rxBuf = rx_buffer;
|
||||
cmd_pack.length = sizeof(rx_buffer);
|
||||
|
||||
FQSpi_CmdOperation(&_ft2004_qspi_bus.fqspi, &cmd_pack);
|
||||
|
||||
for (u32 i = 0; i < cmd_pack.length; i++)
|
||||
{
|
||||
LOG_I("cnt %d, 0x%x ", i, rx_buffer[i]);
|
||||
}
|
||||
|
||||
rt_memset(&cmd_pack, 0, sizeof(&cmd_pack));
|
||||
cmd_pack.cmd = 0x4;
|
||||
FQSpi_CmdOperation(&_ft2004_qspi_bus.fqspi, &cmd_pack);
|
||||
|
||||
rt_memset(&cmd_pack, 0, sizeof(&cmd_pack));
|
||||
cmd_pack.cmd = 0x5;
|
||||
cmd_pack.flags = FQSPI_CMD_NEED_GET_MASK;
|
||||
cmd_pack.rxBuf = rx_buffer;
|
||||
cmd_pack.length = sizeof(rx_buffer);
|
||||
|
||||
FQSpi_CmdOperation(&_ft2004_qspi_bus.fqspi, &cmd_pack);
|
||||
|
||||
for (u32 i = 0; i < cmd_pack.length; i++)
|
||||
{
|
||||
LOG_I("cnt %d, 0x%x ", i, rx_buffer[i]);
|
||||
}
|
||||
}
|
||||
MSH_CMD_EXPORT_ALIAS(cmd05_check, cmd05_check, cmd05_check);
|
||||
#endif
|
||||
|
||||
#ifdef BSP_QSPI_DEBUG
|
||||
static void cmd35_check(void)
|
||||
{
|
||||
struct FQSpi_CmdPack cmd_pack = {0};
|
||||
u8 rx_buffer[1];
|
||||
|
||||
cmd_pack.cmd = 0x6;
|
||||
FQSpi_CmdOperation(&_ft2004_qspi_bus.fqspi, &cmd_pack);
|
||||
|
||||
rt_memset(&cmd_pack, 0, sizeof(&cmd_pack));
|
||||
cmd_pack.cmd = 0x5;
|
||||
cmd_pack.flags = FQSPI_CMD_NEED_GET_MASK;
|
||||
cmd_pack.rxBuf = rx_buffer;
|
||||
cmd_pack.length = sizeof(rx_buffer);
|
||||
|
||||
FQSpi_CmdOperation(&_ft2004_qspi_bus.fqspi, &cmd_pack);
|
||||
|
||||
for (u32 i = 0; i < cmd_pack.length; i++)
|
||||
{
|
||||
LOG_I("cnt %d, 0x%x ", i, rx_buffer[i]);
|
||||
}
|
||||
|
||||
cmd_pack.cmd = 0xB7;
|
||||
FQSpi_CmdOperation(&_ft2004_qspi_bus.fqspi, &cmd_pack);
|
||||
|
||||
rt_memset(&cmd_pack, 0, sizeof(&cmd_pack));
|
||||
cmd_pack.cmd = 0x35;
|
||||
cmd_pack.flags = FQSPI_CMD_NEED_GET_MASK;
|
||||
cmd_pack.rxBuf = rx_buffer;
|
||||
cmd_pack.length = sizeof(rx_buffer);
|
||||
|
||||
FQSpi_CmdOperation(&_ft2004_qspi_bus.fqspi, &cmd_pack);
|
||||
|
||||
for (u32 i = 0; i < cmd_pack.length; i++)
|
||||
{
|
||||
LOG_I("cnt %d, 0x%x ", i, rx_buffer[i]);
|
||||
}
|
||||
}
|
||||
MSH_CMD_EXPORT_ALIAS(cmd35_check, cmd35_check, cmd35_check);
|
||||
#endif
|
||||
#ifdef BSP_QSPI_DEBUG
|
||||
static void cmd15_check(void)
|
||||
{
|
||||
struct FQSpi_CmdPack cmd_pack = {0};
|
||||
u8 rx_buffer[1];
|
||||
|
||||
// cmd_pack.cmd = 0xB7;
|
||||
// FQSpi_CmdOperation(&_ft2004_qspi_bus.fqspi, &cmd_pack);
|
||||
|
||||
rt_memset(&cmd_pack, 0, sizeof(&cmd_pack));
|
||||
cmd_pack.cmd = 0x15;
|
||||
cmd_pack.flags = FQSPI_CMD_NEED_GET_MASK;
|
||||
cmd_pack.rxBuf = rx_buffer;
|
||||
cmd_pack.length = sizeof(rx_buffer);
|
||||
|
||||
FQSpi_CmdOperation(&_ft2004_qspi_bus.fqspi, &cmd_pack);
|
||||
|
||||
for (u32 i = 0; i < cmd_pack.length; i++)
|
||||
{
|
||||
LOG_I("cnt %d, 0x%x ", i, rx_buffer[i]);
|
||||
}
|
||||
}
|
||||
MSH_CMD_EXPORT_ALIAS(cmd15_check, cmd15_check, cmd15_check);
|
||||
#endif
|
||||
#endif
|
||||
29
bsp/ft2004/drivers/drv_qspi.h
Normal file
29
bsp/ft2004/drivers/drv_qspi.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-04-11 Carl the first version
|
||||
*/
|
||||
|
||||
#ifndef __DRT_QSPI_H__
|
||||
#define __DRT_QSPI_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define FT2004_QSPI_NAME "qspi"
|
||||
|
||||
rt_err_t ft2004_qspi_bus_attach_device(const char *bus_name, const char *device_name, rt_uint8_t data_line_width, void (*enter_qspi_mode)(), void (*exit_qspi_mode)());
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !DRT_QSPI_H
|
||||
39
bsp/ft2004/drivers/drv_qspi_flash.c
Normal file
39
bsp/ft2004/drivers/drv_qspi_flash.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-04-08 Carl the first version
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <drv_qspi.h>
|
||||
#include <rtdevice.h>
|
||||
#include <rthw.h>
|
||||
#include <finsh.h>
|
||||
|
||||
#ifdef BSP_USE_QSPI
|
||||
|
||||
#include "spi_flash.h"
|
||||
#include "spi_flash_sfud.h"
|
||||
#define _QSPI_DEVICE_NAME "qspiflash"
|
||||
|
||||
static int
|
||||
rt_hw_qspi_flash_with_sfud_init(void)
|
||||
{
|
||||
ft2004_qspi_bus_attach_device(FT2004_QSPI_NAME, _QSPI_DEVICE_NAME, 1, RT_NULL, RT_NULL);
|
||||
|
||||
/* init gd */
|
||||
rt_kprintf("start rt_sfud_flash_probe \r\n");
|
||||
if (RT_NULL == rt_sfud_flash_probe("GD25LQ256D", _QSPI_DEVICE_NAME))
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_COMPONENT_EXPORT(rt_hw_qspi_flash_with_sfud_init);
|
||||
|
||||
#endif /* BSP_USING_QSPI_FLASH */
|
||||
154
bsp/ft2004/drivers/drv_sdcard.c
Normal file
154
bsp/ft2004/drivers/drv_sdcard.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-03-18 Carl the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef BSP_USING_SDC
|
||||
|
||||
#include <dfs_elm.h>
|
||||
#include <dfs_fs.h>
|
||||
#include <dfs_posix.h>
|
||||
#include "drv_sdctrl.h"
|
||||
|
||||
#define DBG_TAG "app.card"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
static rt_err_t _sdcard_mount(void)
|
||||
{
|
||||
rt_device_t device;
|
||||
|
||||
device = rt_device_find("sd0");
|
||||
rt_kprintf("rt_device_find %x \r\n", device);
|
||||
if (device == NULL)
|
||||
{
|
||||
mmcsd_wait_cd_changed(0);
|
||||
ft2004_mmcsd_change();
|
||||
if (mmcsd_wait_cd_changed(rt_tick_from_millisecond(5000)) == -RT_ETIMEOUT)
|
||||
{
|
||||
rt_kprintf("timeout \r\n");
|
||||
return RT_ERROR;
|
||||
}
|
||||
device = rt_device_find("sd0");
|
||||
}
|
||||
|
||||
rt_thread_mdelay(1000);
|
||||
LOG_I("dfs_mount \r\n");
|
||||
if (device != RT_NULL)
|
||||
{
|
||||
if (dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK)
|
||||
{
|
||||
LOG_I("sd card mount to '/'");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_W("sd card mount to '/' failed!");
|
||||
return RT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static void _sdcard_unmount(void)
|
||||
{
|
||||
rt_thread_mdelay(200);
|
||||
dfs_unmount("/");
|
||||
LOG_I("Unmount \"/\"");
|
||||
|
||||
mmcsd_wait_cd_changed(0);
|
||||
ft2004_mmcsd_change();
|
||||
mmcsd_wait_cd_changed(rt_tick_from_millisecond(5000));
|
||||
LOG_I("Unmount is over \r\n");
|
||||
}
|
||||
|
||||
static void sd_mount(void *parameter)
|
||||
{
|
||||
rt_uint8_t state = 0; /* 1. is valid card ,0 is removal */
|
||||
#ifdef BSP_SDC_IRQ_CARD_REMOVE
|
||||
rt_uint32_t status;
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case 0:
|
||||
if (ft2004_card_status() == 1)
|
||||
{
|
||||
#ifdef BSP_SDC_IRQ_CARD_REMOVE
|
||||
ft2004_card_remove_check(0, RT_NULL); /* Clear removal flag bit */
|
||||
#endif
|
||||
if (_sdcard_mount() == RT_EOK)
|
||||
{
|
||||
state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For the critical case of frequent plug */
|
||||
rt_kprintf("dfs_unmount \r\n");
|
||||
_sdcard_unmount();
|
||||
ft2004_sdctrl_reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_thread_mdelay(100);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
|
||||
#ifdef BSP_SDC_IRQ_CARD_REMOVE
|
||||
if (ft2004_card_remove_check(RT_WAITING_FOREVER, &status) == RT_EOK)
|
||||
{
|
||||
if (status & SDCTR_CARD_REMOVE_FLG)
|
||||
{
|
||||
state = 0;
|
||||
_sdcard_unmount();
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (ft2004_card_status() == 0)
|
||||
{
|
||||
state = 0;
|
||||
_sdcard_unmount();
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
rt_thread_mdelay(100);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ft2004_sdcard_mount(void)
|
||||
{
|
||||
rt_thread_t tid;
|
||||
|
||||
tid = rt_thread_create("sd_mount", sd_mount, RT_NULL,
|
||||
8192, 2, 20);
|
||||
|
||||
if (tid != RT_NULL)
|
||||
{
|
||||
rt_thread_startup(tid);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("create sd_mount thread err!");
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_APP_EXPORT(ft2004_sdcard_mount);
|
||||
|
||||
#endif /* BSP_USING_SDCARD */
|
||||
659
bsp/ft2004/drivers/drv_sdctrl.c
Normal file
659
bsp/ft2004/drivers/drv_sdctrl.c
Normal file
File diff suppressed because it is too large
Load Diff
47
bsp/ft2004/drivers/drv_sdctrl.h
Normal file
47
bsp/ft2004/drivers/drv_sdctrl.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-03-18 Carl the first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_SDCTRL_H__
|
||||
#define __DRV_SDCTRL_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define SDCTR_CMD_IS_COMPLETE_FLG 0x1UL /* Command is complete */
|
||||
#define SDCTR_WRITE_IS_COMPLETE_FLG 0x2UL
|
||||
#define SDCTR_READ_IS_COMPLETE_FLG 0x4UL
|
||||
#define SDCTR_CMD_IS_ERROR_FLG 0x8UL
|
||||
#define SDCTR_CMD_CRC_IS_ERROR_FLG 0x10UL /* Command CRC error */
|
||||
#define SDCTR_DMA_IS_ERROR_FLG 0x20UL /* */
|
||||
#define SDCTR_CARD_REMOVE_FLG 0x40UL /* Card remove */
|
||||
#define SDCTR_CMD_TIMEOUT_FLG 0x70UL /* command timeout */
|
||||
#define SDCTR_CMD_RECEIVE_IS_ERROR_FLG 0x80UL /* CMD receive is error */
|
||||
|
||||
#ifndef SDCTR_BUFF_SIZE
|
||||
#define SDCTR_BUFF_SIZE (512 * 128)
|
||||
#endif
|
||||
|
||||
#ifndef SDCTR_ALIGN_LEN
|
||||
#define SDCTR_ALIGN_LEN (32)
|
||||
#endif
|
||||
|
||||
void ft2004_mmcsd_change(void);
|
||||
rt_bool_t ft2004_card_status(void);
|
||||
rt_err_t ft2004_card_remove_check(rt_int32_t timeout, rt_uint32_t *status);
|
||||
void ft2004_sdctrl_reset(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !
|
||||
449
bsp/ft2004/drivers/drv_spi.c
Normal file
449
bsp/ft2004/drivers/drv_spi.c
Normal file
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-04-25 14:01:29
|
||||
* @LastEditTime: 2021-05-26 15:42:52
|
||||
* @Description: This files is for
|
||||
*
|
||||
* @Modify History:
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#include "drv_spi.h"
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <string.h>
|
||||
#include "ft_spi.h"
|
||||
#include "ft_mux.h"
|
||||
#include "ft_trace.h"
|
||||
#include "ft_generic_timer.h"
|
||||
|
||||
#ifdef BSP_USE_SPI
|
||||
|
||||
#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.spi"
|
||||
#include <drv_log.h>
|
||||
|
||||
typedef void (*spi_cs_handler_t)(const rt_bool_t select);
|
||||
typedef struct
|
||||
{
|
||||
FSpi_Ctrl_t spi_ctrl;
|
||||
struct rt_spi_bus spi_bus;
|
||||
uint16_t spi_cs_pin;
|
||||
spi_cs_handler_t spi_cs_handler;
|
||||
} ft2004_spi_class;
|
||||
|
||||
void ft2004_spi_cs(const rt_bool_t select);
|
||||
static ft2004_spi_class spi_obj = {
|
||||
.spi_cs_handler = ft2004_spi_cs,
|
||||
.spi_ctrl = {
|
||||
.CtrlId = SPI_CTRL_ID_0,
|
||||
.DevId = SPI_DEV_ID_0,
|
||||
.IsReady = FALSE,
|
||||
.CsPin = 5, /* use pin 5 in gpio group a as cs signal pin */
|
||||
},
|
||||
};
|
||||
static const FSpi_Conf_t spi_conf[NUM_OF_SPI_CTRL] =
|
||||
{
|
||||
{
|
||||
.DevAddr = {0x00, 0x00, 0x00, 0x00},
|
||||
.DevAddrLen = SPI_4_BYTE_ADDR,
|
||||
.WorkMode = SPI_CTRL_MASTER_MODE,
|
||||
/* mode 2 CPOL = 1, CPHA = 0 */
|
||||
.Cpol = SPI_CTRL_CPOL_HIGH,
|
||||
.Cpha = SPI_CTRL_CPHA_1EDGE,
|
||||
.BaudRDiv = SPI_SCKDV_4,
|
||||
},
|
||||
{
|
||||
.DevAddr = {0x00, 0x00, 0x00, 0x00},
|
||||
.DevAddrLen = SPI_4_BYTE_ADDR,
|
||||
.WorkMode = SPI_CTRL_MASTER_MODE,
|
||||
.Cpol = SPI_CTRL_CPOL_HIGH,
|
||||
.Cpha = SPI_CTRL_CPHA_1EDGE,
|
||||
.BaudRDiv = SPI_SCKDV_MAX,
|
||||
}};
|
||||
|
||||
inline static ft2004_spi_class *ft2004_spi_get_class()
|
||||
{
|
||||
return &spi_obj;
|
||||
}
|
||||
|
||||
inline static FSpi_Ctrl_t *ft2004_spi_get_ctrl()
|
||||
{
|
||||
return &(ft2004_spi_get_class()->spi_ctrl);
|
||||
}
|
||||
|
||||
static const FSpi_Conf_t *ft2004_lookup_conf(FT_IN FSpi_CtrlId_t CtrlId)
|
||||
{
|
||||
return &spi_conf[CtrlId];
|
||||
}
|
||||
|
||||
void ft2004_spi_cs(const rt_bool_t select)
|
||||
{
|
||||
FSpi_Ctrl_t *ctrl_p = ft2004_spi_get_ctrl();
|
||||
FSpi_SelectSlave(ctrl_p, ctrl_p->DevId, (bool_t)select);
|
||||
}
|
||||
|
||||
/**spi flash operations***/
|
||||
u32 ft2004_spi_transcation(const u8 tx_data, u8 *rx_data_p)
|
||||
{
|
||||
FSpi_Ctrl_t *ctrl_p = ft2004_spi_get_ctrl();
|
||||
u32 ret = ERR_SPI_OK;
|
||||
|
||||
ret = FSpi_ReadWriteByte(ctrl_p, tx_data, rx_data_p);
|
||||
return ret;
|
||||
}
|
||||
/**spi flash operations***/
|
||||
|
||||
static rt_err_t ft2004_spi_init(struct rt_spi_configuration *cfg)
|
||||
{
|
||||
FSpi_Ctrl_t *ctrl_p = ft2004_spi_get_ctrl();
|
||||
FSpi_DevId_t dev_id;
|
||||
u32 ret = ERR_SPI_OK;
|
||||
|
||||
//RT_ASSERT(cfg != RT_NULL);
|
||||
RT_ASSERT(ctrl_p != RT_NULL);
|
||||
dev_id = ctrl_p->DevId;
|
||||
|
||||
/* get spi flash default config */
|
||||
ctrl_p->Config = *(ft2004_lookup_conf(dev_id));
|
||||
|
||||
/* change config according to inputs, cfg could be RT_NULL */
|
||||
|
||||
/* reset ctrl block */
|
||||
ctrl_p->IsReady = FALSE;
|
||||
|
||||
/* set spi pin mux */
|
||||
Ft_setSpiMux(ctrl_p->CtrlId);
|
||||
|
||||
/* init spi ctrl */
|
||||
ret = FSpi_Init(ctrl_p);
|
||||
|
||||
if (ERR_SPI_OK == ret)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static rt_uint32_t spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
|
||||
{
|
||||
rt_size_t message_length, loop;
|
||||
rt_uint8_t *recv_buf;
|
||||
const rt_uint8_t *send_buf;
|
||||
u32 tx_rx_result = ERR_SPI_OK;
|
||||
spi_cs_handler_t cs_handler = ft2004_spi_get_class()->spi_cs_handler;
|
||||
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(device->bus != RT_NULL);
|
||||
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
|
||||
RT_ASSERT(message != RT_NULL);
|
||||
|
||||
if (message->cs_take && cs_handler)
|
||||
{
|
||||
cs_handler(TRUE);
|
||||
}
|
||||
|
||||
message_length = message->length;
|
||||
recv_buf = message->recv_buf;
|
||||
send_buf = message->send_buf;
|
||||
|
||||
/* handle msg */
|
||||
for (loop = 0; loop < message_length; loop++)
|
||||
{
|
||||
/* start data exchange */
|
||||
if ((message->recv_buf) && (message->send_buf))
|
||||
{
|
||||
/* need tx and rx */
|
||||
tx_rx_result |= ft2004_spi_transcation(*send_buf, recv_buf);
|
||||
send_buf++;
|
||||
recv_buf++;
|
||||
}
|
||||
else if (message->send_buf)
|
||||
{
|
||||
/* tx only */
|
||||
tx_rx_result |= ft2004_spi_transcation(*send_buf, RT_NULL);
|
||||
send_buf++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* rx only */
|
||||
tx_rx_result |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, recv_buf);
|
||||
recv_buf++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ERR_SPI_OK != tx_rx_result)
|
||||
{
|
||||
LOG_E("spi transfer error : 0x%x", tx_rx_result);
|
||||
message->length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
if (message->cs_release && cs_handler)
|
||||
{
|
||||
cs_handler(FALSE);
|
||||
}
|
||||
|
||||
return message->length;
|
||||
}
|
||||
|
||||
static rt_err_t spi_configure(struct rt_spi_device *device,
|
||||
struct rt_spi_configuration *configuration)
|
||||
{
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(configuration != RT_NULL);
|
||||
|
||||
return ft2004_spi_init(configuration);
|
||||
}
|
||||
|
||||
static const struct rt_spi_ops ft2004_spi_ops =
|
||||
{
|
||||
.configure = spi_configure,
|
||||
.xfer = spi_xfer,
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach the spi device to SPI bus, this function must be used after initialization.
|
||||
*/
|
||||
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, uint16_t cs_gpio_pin)
|
||||
{
|
||||
rt_err_t result;
|
||||
struct rt_spi_device *spi_device;
|
||||
ft2004_spi_class *spi_class = ft2004_spi_get_class();
|
||||
|
||||
RT_ASSERT(spi_class != RT_NULL);
|
||||
|
||||
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
|
||||
RT_ASSERT(spi_device != RT_NULL);
|
||||
|
||||
result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, RT_NULL);
|
||||
|
||||
LOG_I("attach result 0x%x", result);
|
||||
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
if (spi_device)
|
||||
{
|
||||
rt_free(spi_device);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int rt_hw_spi_bus_init(void)
|
||||
{
|
||||
rt_err_t result;
|
||||
ft2004_spi_class *spi_class = ft2004_spi_get_class();
|
||||
|
||||
LOG_I("init spi ctrl");
|
||||
spi_class->spi_bus.parent.user_data = &spi_class->spi_bus;
|
||||
result = rt_spi_bus_register(&spi_class->spi_bus, SPI_BUS_NAME, &ft2004_spi_ops);
|
||||
return result;
|
||||
}
|
||||
|
||||
int rt_hw_spi_init(void)
|
||||
{
|
||||
return rt_hw_spi_bus_init();
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_spi_init);
|
||||
|
||||
static void rthw_spi_delay(u32 delayCnt)
|
||||
{
|
||||
Ft_GenericTimer_UsDelay(delayCnt);
|
||||
}
|
||||
|
||||
/************spi flash operatiosn implemented for sample test****************/
|
||||
/* definition of s25fs maunfactor id */
|
||||
typedef struct
|
||||
{
|
||||
u8 Mid;
|
||||
u8 MemoryType;
|
||||
u8 Density;
|
||||
u8 RemainBytes;
|
||||
u8 PhySectArch;
|
||||
u8 FamilyID;
|
||||
} ft2004_manuid_t;
|
||||
|
||||
/* definition of cmd for s25fs */
|
||||
#define S25FS_ENABLE_WR 0x06
|
||||
#define S25FS_DISABLE_WR 0x04
|
||||
#define S25FS_READ_ID 0x9F
|
||||
#define S25FS_READ_4BYTE_ADD 0x13
|
||||
#define S25FS_ERASE_4BYTE_ADD 0x21
|
||||
#define S25FS_READ_STATUS_1 0x05
|
||||
#define S25FS_READ_FLASH_PARAM 0x5A
|
||||
|
||||
static void ft2004_dump_manuid(const ft2004_manuid_t *pId)
|
||||
{
|
||||
rt_kprintf("0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\r\n",
|
||||
pId->Mid, pId->MemoryType, pId->Density, pId->RemainBytes,
|
||||
pId->PhySectArch, pId->FamilyID);
|
||||
}
|
||||
|
||||
static u32 ft2004_read_in_4byte_addr(const u32 ReadAddr, const u32 BytesToRead, u8 *pBuf)
|
||||
{
|
||||
u32 ret = ERR_SPI_OK;
|
||||
u32 loop;
|
||||
|
||||
RT_ASSERT(RT_NULL != pBuf);
|
||||
|
||||
ft2004_spi_cs(TRUE);
|
||||
ret |= ft2004_spi_transcation(S25FS_READ_4BYTE_ADD, RT_NULL);
|
||||
/* only 4-bytes address, MSB first */
|
||||
ret |= ft2004_spi_transcation((u8)(ReadAddr >> 24), RT_NULL);
|
||||
ret |= ft2004_spi_transcation((u8)(ReadAddr >> 16), RT_NULL);
|
||||
ret |= ft2004_spi_transcation((u8)(ReadAddr >> 8), RT_NULL);
|
||||
ret |= ft2004_spi_transcation((u8)ReadAddr, RT_NULL);
|
||||
/* read out data */
|
||||
for (loop = 0; loop < BytesToRead; loop++)
|
||||
{
|
||||
ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, pBuf + loop);
|
||||
if (ERR_SPI_OK != ret)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
ft2004_spi_cs(FALSE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 ft2004_spi_enable_wr(const bool_t enable)
|
||||
{
|
||||
u32 ret = ERR_SPI_OK;
|
||||
ft2004_spi_cs(TRUE);
|
||||
if (enable)
|
||||
{
|
||||
ret |= ft2004_spi_transcation(S25FS_ENABLE_WR, RT_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret |= ft2004_spi_transcation(S25FS_DISABLE_WR, RT_NULL);
|
||||
}
|
||||
ft2004_spi_cs(FALSE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 ft2004_erase_sector_in_4byte_addr(const u32 sector_addr)
|
||||
{
|
||||
u32 Ret = ERR_SPI_OK;
|
||||
|
||||
ft2004_spi_enable_wr(TRUE);
|
||||
LOG_I("erase sector 0x%x", Ret);
|
||||
if (ERR_SPI_OK != Ret)
|
||||
{
|
||||
return Ret;
|
||||
}
|
||||
|
||||
ft2004_spi_cs(TRUE);
|
||||
Ret |= ft2004_spi_transcation(S25FS_ERASE_4BYTE_ADD, RT_NULL);
|
||||
Ret |= ft2004_spi_transcation((u8)(sector_addr >> 24), RT_NULL);
|
||||
Ret |= ft2004_spi_transcation((u8)(sector_addr >> 16), RT_NULL);
|
||||
Ret |= ft2004_spi_transcation((u8)(sector_addr >> 8), RT_NULL);
|
||||
Ret |= ft2004_spi_transcation((u8)(sector_addr), RT_NULL);
|
||||
ft2004_spi_cs(FALSE);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
u32 ft2004_spi_read_params(const u32 Addr)
|
||||
{
|
||||
u32 Ret = ERR_SPI_OK;
|
||||
u8 dat[8] = {0};
|
||||
u32 loop;
|
||||
|
||||
ft2004_spi_cs(TRUE);
|
||||
Ret |= ft2004_spi_transcation(S25FS_READ_FLASH_PARAM, RT_NULL);
|
||||
Ret |= ft2004_spi_transcation((u8)(Addr >> 16), RT_NULL);
|
||||
Ret |= ft2004_spi_transcation((u8)(Addr >> 8), RT_NULL);
|
||||
Ret |= ft2004_spi_transcation((u8)(Addr), RT_NULL);
|
||||
for (loop = 0; loop < 8; loop++)
|
||||
{
|
||||
Ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, dat + loop);
|
||||
rt_kprintf("%d: 0x%x", loop, *(dat + loop));
|
||||
}
|
||||
|
||||
ft2004_spi_cs(FALSE);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
static u32 ft2004_spi_readid_for_test(ft2004_manuid_t *pId)
|
||||
{
|
||||
FSpi_Ctrl_t *ctrl_p = ft2004_spi_get_ctrl();
|
||||
u32 ret = ERR_SPI_OK;
|
||||
|
||||
if (!ctrl_p->IsReady)
|
||||
{
|
||||
return ERR_SPI_NOT_READY;
|
||||
}
|
||||
|
||||
RT_ASSERT(RT_NULL != pId);
|
||||
|
||||
ft2004_spi_cs(TRUE);
|
||||
|
||||
/* shifting the command code “90H” followed by a 24-bit address */
|
||||
ret |= ft2004_spi_transcation(S25FS_READ_ID, RT_NULL);
|
||||
|
||||
/* Manufacturer ID and the Device ID are shifted out */
|
||||
ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->Mid);
|
||||
ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->MemoryType);
|
||||
ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->Density);
|
||||
ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->RemainBytes);
|
||||
ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->PhySectArch);
|
||||
ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->FamilyID);
|
||||
ft2004_spi_cs(FALSE);
|
||||
|
||||
if (ERR_SPI_OK == ret)
|
||||
{
|
||||
ft2004_dump_manuid(pId);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spi_9f_s25fs_sample(int argc, char *argv[])
|
||||
{
|
||||
ft2004_manuid_t dev_id;
|
||||
u32 ret = ERR_SPI_OK;
|
||||
u32 delay = SPI_TIMEOUT * 10;
|
||||
|
||||
rt_kprintf("test s25fs spi flash\r\n");
|
||||
ret |= ft2004_spi_init(RT_NULL);
|
||||
ret |= ft2004_spi_readid_for_test(&dev_id);
|
||||
|
||||
rt_kprintf("result is: 0x%x \r\n", ret);
|
||||
while (--delay)
|
||||
{
|
||||
rthw_spi_delay(10);
|
||||
}
|
||||
}
|
||||
MSH_CMD_EXPORT(spi_9f_s25fs_sample, "spi s25fs cmd 9fH sample");
|
||||
|
||||
static u8 read_buf[256];
|
||||
static void spi_5a_s25fs_sample(int argc, char *argv[])
|
||||
{
|
||||
u32 ret = ERR_SPI_OK;
|
||||
u32 delay = SPI_TIMEOUT * 10;
|
||||
u32 read_addr = 0x0000;
|
||||
|
||||
rt_kprintf("test s25fs spi flash\r\n");
|
||||
ret |= ft2004_spi_init(RT_NULL);
|
||||
ret |= ft2004_spi_read_params(read_addr);
|
||||
ret |= ft2004_read_in_4byte_addr(read_addr, 256, read_buf);
|
||||
rt_kprintf("result is: 0x%x \r\n", ret);
|
||||
while (--delay)
|
||||
{
|
||||
rthw_spi_delay(10);
|
||||
}
|
||||
}
|
||||
MSH_CMD_EXPORT(spi_5a_s25fs_sample, "spi s25fs cmd 5aH sample");
|
||||
|
||||
#endif
|
||||
29
bsp/ft2004/drivers/drv_spi.h
Normal file
29
bsp/ft2004/drivers/drv_spi.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-04-25 14:01:39
|
||||
* @LastEditTime: 2021-04-29 09:40:13
|
||||
* @Description: This files is for
|
||||
*
|
||||
* @Modify History:
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
#ifndef FT_DRIVERS_RTT_SPI_H
|
||||
#define FT_DRIVERS_RTT_SPI_H
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#define SPI_BUS_NAME "spi0"
|
||||
#define SPI_DEV_NAME "S25FS256"
|
||||
|
||||
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, uint16_t cs_gpio_pin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#endif
|
||||
43
bsp/ft2004/drivers/drv_spi_flash.c
Normal file
43
bsp/ft2004/drivers/drv_spi_flash.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-04-25 14:01:16
|
||||
* @LastEditTime: 2021-04-30 14:43:12
|
||||
* @Description: This files is for
|
||||
*
|
||||
* @Modify History:
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <drv_spi.h>
|
||||
#include <rtdevice.h>
|
||||
#include <rthw.h>
|
||||
#include <finsh.h>
|
||||
#include "ft_spi.h"
|
||||
|
||||
#ifdef BSP_USE_SPI
|
||||
|
||||
#include "spi_flash.h"
|
||||
#include "spi_flash_sfud.h"
|
||||
|
||||
static int rt_hw_spi_flash_init(void)
|
||||
{
|
||||
uint16_t cs_pin = 5;
|
||||
rt_hw_spi_device_attach(SPI_BUS_NAME, SPI_DEV_NAME, cs_pin);
|
||||
|
||||
rt_kprintf("attach spi flash\r\n");
|
||||
/* lookup flah */
|
||||
if (RT_NULL == rt_sfud_flash_probe("S25FS256S", SPI_DEV_NAME))
|
||||
{
|
||||
rt_kprintf("attach spi flash failed\r\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
|
||||
#endif
|
||||
192
bsp/ft2004/drivers/drv_usart.c
Normal file
192
bsp/ft2004/drivers/drv_usart.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-03-04 Carl the first version
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_usart.h"
|
||||
#include "interrupt.h"
|
||||
#include "serial.h"
|
||||
#include "rtconfig.h"
|
||||
|
||||
#ifdef RT_USING_SERIAL
|
||||
|
||||
extern u32 FUart_GetInterruptMask(Ft_Uart *uart_ptr);
|
||||
|
||||
static void Ft_Os_Uart_Callback(void *Args, u32 Event, u32 EventData);
|
||||
|
||||
static void rt_hw_uart_isr(int irqno, void *param)
|
||||
{
|
||||
Ft_Uart *uart_ptr = (Ft_Uart *)param;
|
||||
FUart_InterruptHandler(uart_ptr);
|
||||
}
|
||||
|
||||
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
|
||||
{
|
||||
struct drv_usart *uart = RT_NULL;
|
||||
Ft_Uart *uart_ptr = RT_NULL;
|
||||
u32 RegTemp;
|
||||
u32 ret;
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
RT_ASSERT(cfg != RT_NULL);
|
||||
uart = rt_container_of(serial, struct drv_usart, serial);
|
||||
uart_ptr = uart->handle;
|
||||
|
||||
RT_ASSERT(FUart_CfgInitialize(uart_ptr, FUart_LookupConfig(uart_ptr->Config.InstanceId)) == FST_SUCCESS);
|
||||
FUart_SetHandler(uart_ptr, Ft_Os_Uart_Callback, serial);
|
||||
rt_hw_interrupt_install(uart_ptr->Config.IsrNum, rt_hw_uart_isr, uart_ptr, "uart");
|
||||
rt_hw_interrupt_umask(uart_ptr->Config.IsrNum);
|
||||
|
||||
//<! 设置波特率
|
||||
ret = FUart_SetBaudRate(uart_ptr, cfg->baud_rate);
|
||||
RT_ASSERT(ret == FST_SUCCESS);
|
||||
|
||||
//<! 打开接收中断
|
||||
RegTemp = FUart_GetInterruptMask(uart_ptr);
|
||||
RegTemp |= UARTMIS_RTMIS;
|
||||
FUart_SetInterruptMask(uart_ptr, RegTemp);
|
||||
FUart_SetOptions(uart_ptr, FUART_OPTION_UARTEN | FUART_OPTION_RXEN | FUART_OPTION_TXEN | FUART_OPTION_FIFOEN);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
|
||||
{
|
||||
struct drv_usart *uart = RT_NULL;
|
||||
Ft_Uart *uart_ptr = RT_NULL;
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
|
||||
uart = rt_container_of(serial, struct drv_usart, serial);
|
||||
uart_ptr = uart->handle;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_CLR_INT:
|
||||
/* disable rx irq */
|
||||
rt_hw_interrupt_mask(uart_ptr->Config.IsrNum);
|
||||
break;
|
||||
|
||||
case RT_DEVICE_CTRL_SET_INT:
|
||||
/* enable rx irq */
|
||||
rt_hw_interrupt_umask(uart_ptr->Config.IsrNum);
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static void Ft_Os_Uart_Callback(void *Args, u32 Event, u32 EventData)
|
||||
{
|
||||
struct rt_serial_device *serial = (struct rt_serial_device *)Args;
|
||||
|
||||
if (FUART_EVENT_RECV_DATA == Event || FUART_EVENT_RECV_TOUT == Event)
|
||||
{
|
||||
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
|
||||
}
|
||||
else if (FUART_EVENT_RECV_ERROR == Event)
|
||||
{
|
||||
}
|
||||
else if (FUART_EVENT_SENT_DATA == Event)
|
||||
{
|
||||
}
|
||||
else if (FUART_EVENT_PARE_FRAME_BRKE == Event)
|
||||
{
|
||||
}
|
||||
else if (FUART_EVENT_RECV_ORERR == Event)
|
||||
{
|
||||
}
|
||||
|
||||
if (FUART_EVENT_SENT_DATA == Event)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
static int uart_putc(struct rt_serial_device *serial, char c)
|
||||
{
|
||||
struct drv_usart *uart = RT_NULL;
|
||||
Ft_Uart *uart_ptr = RT_NULL;
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
|
||||
uart = rt_container_of(serial, struct drv_usart, serial);
|
||||
uart_ptr = uart->handle;
|
||||
|
||||
FUart_SendByte(uart_ptr->Config.BaseAddress, c);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int uart_getc(struct rt_serial_device *serial)
|
||||
{
|
||||
int ch;
|
||||
struct drv_usart *uart = RT_NULL;
|
||||
Ft_Uart *uart_ptr = RT_NULL;
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
|
||||
uart = rt_container_of(serial, struct drv_usart, serial);
|
||||
uart_ptr = uart->handle;
|
||||
|
||||
ch = FUart_GetChar(uart_ptr->Config.BaseAddress);
|
||||
if (ch == 0xff)
|
||||
ch = -1;
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
static const struct rt_uart_ops _uart_ops =
|
||||
{
|
||||
uart_configure,
|
||||
uart_control,
|
||||
uart_putc,
|
||||
uart_getc,
|
||||
};
|
||||
|
||||
#ifdef RT_USING_UART0
|
||||
static Ft_Uart Ft_Uart0;
|
||||
static struct drv_usart _RtUart0;
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART1
|
||||
static Ft_Uart Ft_Uart1;
|
||||
static struct drv_usart _RtUart1;
|
||||
#endif
|
||||
|
||||
int rt_hw_uart_init(void)
|
||||
{
|
||||
|
||||
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||
|
||||
#ifdef RT_USING_UART0
|
||||
config.bufsz = RT_SERIAL_RB_BUFSZ;
|
||||
_RtUart0.serial.ops = &_uart_ops;
|
||||
_RtUart0.serial.config = config;
|
||||
Ft_Uart0.Config.InstanceId = FT_UART0_ID;
|
||||
_RtUart0.Handle = &Ft_Uart0;
|
||||
|
||||
rt_hw_serial_register(&_RtUart0.serial, "uart0",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
&_RtUart0);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART1
|
||||
config.bufsz = RT_SERIAL_RB_BUFSZ;
|
||||
_RtUart1.serial.ops = &_uart_ops;
|
||||
_RtUart1.serial.config = config;
|
||||
Ft_Uart1.Config.InstanceId = FT_UART1_ID;
|
||||
_RtUart1.handle = &Ft_Uart1;
|
||||
rt_hw_serial_register(&_RtUart1.serial, "uart1",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
&_RtUart1);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_uart_init);
|
||||
|
||||
#endif /* RT_USING_SERIAL */
|
||||
25
bsp/ft2004/drivers/drv_usart.h
Normal file
25
bsp/ft2004/drivers/drv_usart.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-03-04 Carl the first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_USART_H__
|
||||
#define __DRV_USART_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "rtdevice.h"
|
||||
#include "ft_uart.h"
|
||||
|
||||
struct drv_usart
|
||||
{
|
||||
Ft_Uart *handle;
|
||||
|
||||
struct rt_serial_device serial;
|
||||
};
|
||||
|
||||
#endif // !
|
||||
88
bsp/ft2004/drivers/ft2004.c
Normal file
88
bsp/ft2004/drivers/ft2004.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-04-29 Carl the first version
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "ft2004.h"
|
||||
#include "gicv3.h"
|
||||
|
||||
rt_uint64_t get_main_cpu_affval(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
rt_uint32_t arm_gic_cpumask_to_affval(rt_uint32_t *cpu_mask, rt_uint32_t *cluster_id, rt_uint32_t *target_list)
|
||||
{
|
||||
|
||||
if (*cpu_mask == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
*target_list = 0;
|
||||
*cluster_id = 0;
|
||||
|
||||
if (*cpu_mask & 0x3)
|
||||
{
|
||||
if ((*cpu_mask & 0x3) == 0x3)
|
||||
{
|
||||
*target_list = 3;
|
||||
}
|
||||
else if ((*cpu_mask & 0x1))
|
||||
{
|
||||
*target_list = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*target_list = 2;
|
||||
}
|
||||
*cpu_mask &= ~0x3;
|
||||
}
|
||||
else if (*cpu_mask & 0xc)
|
||||
{
|
||||
*cluster_id = 0x100;
|
||||
if ((*cpu_mask & 0xc) == 0xc)
|
||||
{
|
||||
*target_list = 3;
|
||||
}
|
||||
else if ((*cpu_mask & 0x4))
|
||||
{
|
||||
*target_list = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*target_list = 2;
|
||||
}
|
||||
*cpu_mask &= ~0xc;
|
||||
}
|
||||
else
|
||||
{
|
||||
*cpu_mask = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
|
||||
void send_core_isg(void)
|
||||
{
|
||||
for (size_t i = 0; i <= 0xf; i++)
|
||||
{
|
||||
/* code */
|
||||
rt_kprintf("i %x \r\n", i);
|
||||
arm_gic_send_affinity_sgi(0, 0, i, 0);
|
||||
rt_thread_mdelay(100);
|
||||
}
|
||||
}
|
||||
MSH_CMD_EXPORT(send_core_isg, send_core_isg);
|
||||
|
||||
#endif
|
||||
25
bsp/ft2004/drivers/ft2004.h
Normal file
25
bsp/ft2004/drivers/ft2004.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-04-29 Carl the first version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FT2004_H__
|
||||
#define __FT2004_H__
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#define ARM_GIC_NR_IRQS 160
|
||||
#define ARM_GIC_MAX_NR 1
|
||||
#define MAX_HANDLERS 160
|
||||
#define GIC_IRQ_START 0
|
||||
|
||||
rt_uint64_t get_main_cpu_affval(void);
|
||||
|
||||
#endif // !
|
||||
44
bsp/ft2004/drivers/ft2004_cpu.S
Normal file
44
bsp/ft2004/drivers/ft2004_cpu.S
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-04-29 Carl the first version
|
||||
*
|
||||
*/
|
||||
|
||||
#include "rtconfig.h"
|
||||
|
||||
.globl rt_hw_cpu_id
|
||||
rt_hw_cpu_id:
|
||||
mrc p15, 0, r0, c0, c0, 5
|
||||
ubfx r0, r0, #0, #12
|
||||
cmp r0, #0
|
||||
beq core0
|
||||
cmp r0, #1
|
||||
beq core1
|
||||
cmp r0, #256
|
||||
beq core2
|
||||
mov r1 ,#257
|
||||
cmp r0, r1
|
||||
beq core3
|
||||
b default
|
||||
core0:
|
||||
mov r0, #0
|
||||
b return
|
||||
core1:
|
||||
mov r0, #1
|
||||
b return
|
||||
core2:
|
||||
mov r0, #2
|
||||
b return
|
||||
core3:
|
||||
mov r0, #3
|
||||
b return
|
||||
default:
|
||||
and r0, r0, #15
|
||||
return:
|
||||
bx lr
|
||||
|
||||
86
bsp/ft2004/drivers/secondary_cpu.c
Normal file
86
bsp/ft2004/drivers/secondary_cpu.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2020 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-05-26 10:09:45
|
||||
* @LastEditTime: 2021-05-26 10:31:44
|
||||
* @Description: This files is for
|
||||
*
|
||||
* @Modify History:
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "board.h"
|
||||
#include <gicv3.h>
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
#include <interrupt.h>
|
||||
#include "ft_psci.h"
|
||||
#include "ft_generic_timer.h"
|
||||
|
||||
extern int rt_hw_timer_init(void);
|
||||
extern void secondary_cpu_start(void);
|
||||
|
||||
void rt_hw_secondary_cpu_up(void)
|
||||
{
|
||||
|
||||
rt_uint32_t i;
|
||||
rt_uint32_t cpu_mask = 0;
|
||||
|
||||
rt_kprintf("rt_hw_secondary_cpu_up is processing \r\n");
|
||||
for (i = 1; i < RT_CPUS_NR; i++)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
/* code */
|
||||
FPsci_CpuOn(1 << i, (rt_uint32_t)secondary_cpu_start);
|
||||
cpu_mask = 2;
|
||||
}
|
||||
else if (i == 2)
|
||||
{
|
||||
FPsci_CpuOn(1 << i, (rt_uint32_t)secondary_cpu_start);
|
||||
cpu_mask = 4;
|
||||
}
|
||||
else if (i == 3)
|
||||
{
|
||||
FPsci_CpuOn(1 << i, (rt_uint32_t)secondary_cpu_start);
|
||||
cpu_mask = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
__asm__ volatile("dsb" ::
|
||||
: "memory");
|
||||
rt_hw_ipi_send(RT_SCHEDULE_IPI, cpu_mask);
|
||||
Ft_GenericTimer_UsDelay(1000000);
|
||||
}
|
||||
}
|
||||
|
||||
void secondary_cpu_c_start(void)
|
||||
{
|
||||
rt_hw_vector_init();
|
||||
rt_hw_spin_lock(&_cpus_lock);
|
||||
|
||||
arm_gic_cpu_init(0);
|
||||
arm_gic_redist_init(0);
|
||||
|
||||
rt_hw_timer_init();
|
||||
|
||||
rt_hw_interrupt_set_priority(RT_SCHEDULE_IPI, 16);
|
||||
rt_hw_interrupt_umask(RT_SCHEDULE_IPI);
|
||||
|
||||
rt_system_scheduler_start();
|
||||
}
|
||||
|
||||
void rt_hw_secondary_cpu_idle_exec(void)
|
||||
{
|
||||
asm volatile("wfe" ::
|
||||
: "memory", "cc");
|
||||
}
|
||||
|
||||
#endif
|
||||
20
bsp/ft2004/drivers/serial.h
Normal file
20
bsp/ft2004/drivers/serial.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-04-29 Carl the first version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __UART_H__
|
||||
#define __UART_H__
|
||||
|
||||
#include <board.h>
|
||||
|
||||
int rt_hw_uart_init(void);
|
||||
|
||||
#endif
|
||||
|
||||
BIN
bsp/ft2004/figures/onchipPeripheral.png
Normal file
BIN
bsp/ft2004/figures/onchipPeripheral.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
bsp/ft2004/figures/rttPing通过界面.png
Normal file
BIN
bsp/ft2004/figures/rttPing通过界面.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
bsp/ft2004/figures/rttsd调试.png
Normal file
BIN
bsp/ft2004/figures/rttsd调试.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
bsp/ft2004/figures/启动演示图.png
Normal file
BIN
bsp/ft2004/figures/启动演示图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
110
bsp/ft2004/ft_aarch32.lds
Normal file
110
bsp/ft2004/ft_aarch32.lds
Normal file
@@ -0,0 +1,110 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x80100000;
|
||||
|
||||
__text_start = .;
|
||||
.text :
|
||||
{
|
||||
*(.vectors)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
|
||||
/* section information for finsh shell */
|
||||
. = ALIGN(4);
|
||||
__fsymtab_start = .;
|
||||
KEEP(*(FSymTab))
|
||||
__fsymtab_end = .;
|
||||
. = ALIGN(4);
|
||||
__vsymtab_start = .;
|
||||
KEEP(*(VSymTab))
|
||||
__vsymtab_end = .;
|
||||
. = ALIGN(4);
|
||||
|
||||
/* section information for 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.*) }
|
||||
__rodata_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
.ctors :
|
||||
{
|
||||
PROVIDE(__ctors_start__ = .);
|
||||
KEEP(*(SORT(.ctors.*)))
|
||||
KEEP(*(.ctors))
|
||||
PROVIDE(__ctors_end__ = .);
|
||||
}
|
||||
|
||||
.dtors :
|
||||
{
|
||||
PROVIDE(__dtors_start__ = .);
|
||||
KEEP(*(SORT(.dtors.*)))
|
||||
KEEP(*(.dtors))
|
||||
PROVIDE(__dtors_end__ = .);
|
||||
}
|
||||
|
||||
. = ALIGN(16 * 1024);
|
||||
.l1_page_table :
|
||||
{
|
||||
__l1_page_table_start = .;
|
||||
. += 16K;
|
||||
}
|
||||
|
||||
. = ALIGN(8);
|
||||
__data_start = .;
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
}
|
||||
__data_end = .;
|
||||
|
||||
. = ALIGN(8);
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
}
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
|
||||
.heap :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__end__ = .;
|
||||
PROVIDE(end = .);
|
||||
__HeapBase = .;
|
||||
. += 0x400;
|
||||
__HeapLimit = .;
|
||||
__heap_limit = .; /* Add for _sbrk */
|
||||
}
|
||||
|
||||
/* 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) }
|
||||
|
||||
_end = .;
|
||||
}
|
||||
4
bsp/ft2004/libraries/.gitignore
vendored
Normal file
4
bsp/ft2004/libraries/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.o
|
||||
*.elf
|
||||
*.bin
|
||||
*.map
|
||||
146
bsp/ft2004/libraries/Kconfig
Normal file
146
bsp/ft2004/libraries/Kconfig
Normal file
@@ -0,0 +1,146 @@
|
||||
menu "Hardware Drivers Config"
|
||||
|
||||
menu "On-chip Peripheral Drivers"
|
||||
menuconfig BSP_USING_UART
|
||||
bool "Enable UART"
|
||||
default y
|
||||
select RT_USING_SERIAL
|
||||
if BSP_USING_UART
|
||||
config RT_USING_UART1
|
||||
bool "Enable UART1"
|
||||
default y
|
||||
|
||||
config RT_USING_UART0
|
||||
bool "Enable UART0"
|
||||
default n
|
||||
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_SDC
|
||||
bool "Enable sd controller"
|
||||
select RT_USING_SDIO
|
||||
select RT_USING_DFS
|
||||
select RT_USING_DFS_ELMFAT
|
||||
default n
|
||||
|
||||
if BSP_USING_SDC
|
||||
|
||||
config BSP_SDC_DEBUG_PRINT
|
||||
bool "Enable sd controller debug print"
|
||||
default n
|
||||
|
||||
|
||||
config BSP_SDC_USE_IRQ
|
||||
bool "Use interrupt to handle when cmd complete, dma complete"
|
||||
default n
|
||||
|
||||
if BSP_SDC_USE_IRQ
|
||||
config BSP_SDC_IRQ_CARD_REMOVE
|
||||
bool "Use interrupt to determine if the card is pulled out"
|
||||
default n
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_GMAC
|
||||
bool "Enable gmac"
|
||||
default n
|
||||
select RT_USING_NETDEV
|
||||
|
||||
|
||||
if BSP_USING_GMAC
|
||||
config BSP_USING_GMAC0
|
||||
bool "Enable GMAC0"
|
||||
default y
|
||||
|
||||
config BSP_USING_GMAC1
|
||||
bool "Enable GMAC1"
|
||||
default n
|
||||
|
||||
config RT_LWIP_ETH_PAD_SIZE
|
||||
int "set lwip ETH_PAD_SIZE"
|
||||
range 2 256
|
||||
default 2
|
||||
|
||||
config RAW_DATA_PRINT
|
||||
bool "Enable mac raw data print"
|
||||
default n
|
||||
|
||||
if RAW_DATA_PRINT
|
||||
config ETH_RX_DUMP
|
||||
bool "Enable gmac receive raw data print "
|
||||
default n
|
||||
|
||||
config ETH_TX_DUMP
|
||||
bool "Enable gmac send raw data print "
|
||||
default n
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
|
||||
# menuconfig BSP_USE_QSPI
|
||||
# bool "Enable Qspi"
|
||||
# select RT_USING_SFUD
|
||||
# select RT_SFUD_USING_QSPI
|
||||
# default n
|
||||
|
||||
# if BSP_USE_QSPI
|
||||
# config BSP_QSPI_DEBUG
|
||||
# bool "Enable qspi debug print"
|
||||
# default n
|
||||
# endif
|
||||
|
||||
menuconfig BSP_USE_SPI
|
||||
bool "Enable Spi"
|
||||
select RT_USING_SFUD
|
||||
select RT_SFUD_USING_SPI
|
||||
select RT_SFUD_USING_SFDP
|
||||
select RT_SFUD_USING_FLASH_INFO_TABLE
|
||||
select BSP_USE_GPIO
|
||||
default n
|
||||
if BSP_USE_SPI
|
||||
config BSP_SPI_DEBUG
|
||||
bool "Enable spi debug print"
|
||||
default n
|
||||
endif
|
||||
|
||||
menuconfig BSP_USE_GPIO
|
||||
bool "Enable Gpio"
|
||||
default n
|
||||
if BSP_USE_GPIO
|
||||
config BSP_GPIO_DEBUG
|
||||
bool "Enable gpio debug print"
|
||||
default n
|
||||
endif
|
||||
|
||||
menuconfig BSP_USE_CAN
|
||||
bool "Enable Can"
|
||||
select RT_USING_CAN
|
||||
default n
|
||||
|
||||
if BSP_USE_CAN
|
||||
config BSP_USING_CAN0
|
||||
bool "Enable can0"
|
||||
default n
|
||||
config BSP_USING_CAN1
|
||||
bool "Enable can1"
|
||||
default n
|
||||
|
||||
if BSP_USING_CAN0
|
||||
config BSP_USING_CAN0_DEBUG
|
||||
bool "Enable can0 work in loop back"
|
||||
default n
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Board extended module Drivers"
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
202
bsp/ft2004/libraries/LICENSE
Normal file
202
bsp/ft2004/libraries/LICENSE
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
129
bsp/ft2004/libraries/SConscript
Normal file
129
bsp/ft2004/libraries/SConscript
Normal file
@@ -0,0 +1,129 @@
|
||||
'''
|
||||
: Copyright (c) 2020 Phytium Information Technology, Inc.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0.
|
||||
|
||||
Date: 2021-05-24 14:30:13
|
||||
LastEditTime: 2021-05-26 14:58:34
|
||||
Description: This files is for
|
||||
|
||||
Modify History:
|
||||
Ver Who Date Changes
|
||||
----- ------ -------- --------------------------------------
|
||||
'''
|
||||
from building import *
|
||||
import rtconfig
|
||||
Import('RTT_ROOT')
|
||||
|
||||
# get current directory
|
||||
cwd = GetCurrentDir()
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src = Split("""
|
||||
bsp/standlone/ft_assert.c
|
||||
bsp/standlone/ft_generic_timer.c
|
||||
bsp/standlone/ft_printf.c
|
||||
bsp/standlone/ft_trace.c
|
||||
bsp/standlone/ft_mux.c
|
||||
bsp/standlone/inbyte.c
|
||||
bsp/standlone/outbyte.c
|
||||
bsp/standlone/ft_cache.c
|
||||
bsp/standlone/ft_cpu.c
|
||||
bsp/standlone/ft_smc.S
|
||||
bsp/standlone/ft_psci.c
|
||||
bsp/standlone/ft_debug.c
|
||||
""")
|
||||
|
||||
|
||||
|
||||
if GetDepend(['RT_USING_SERIAL']):
|
||||
src += ['bsp/ft_uart/ft_uart_g.c']
|
||||
src += ['bsp/ft_uart/ft_uart_hw.c']
|
||||
src += ['bsp/ft_uart/ft_uart_intr.c']
|
||||
src += ['bsp/ft_uart/ft_uart_options.c']
|
||||
src += ['bsp/ft_uart/ft_uart_selftest.c']
|
||||
src += ['bsp/ft_uart/ft_uart_sinit.c']
|
||||
src += ['bsp/ft_uart/ft_uart.c']
|
||||
|
||||
if GetDepend(['RT_USING_I2C']):
|
||||
None
|
||||
|
||||
if GetDepend(['RT_USING_USB_HOST']) or GetDepend(['RT_USING_USB_DEVICE']):
|
||||
None
|
||||
|
||||
if GetDepend(['BSP_USE_CAN']):
|
||||
src += ['bsp/ft_can/ft_can_g.c']
|
||||
src += ['bsp/ft_can/ft_can_hw.c']
|
||||
src += ['bsp/ft_can/ft_can_intr.c']
|
||||
src += ['bsp/ft_can/ft_can_sinit.c']
|
||||
src += ['bsp/ft_can/ft_can.c']
|
||||
src += ['bsp/ft_can/ft_can_calc.c']
|
||||
None
|
||||
|
||||
|
||||
if GetDepend(['RT_USING_HWTIMER']) or GetDepend(['RT_USING_PWM']):
|
||||
None
|
||||
|
||||
if GetDepend(['RT_USING_ADC']):
|
||||
None
|
||||
|
||||
if GetDepend(['RT_USING_RTC']):
|
||||
None
|
||||
|
||||
if GetDepend(['RT_USING_WDT']):
|
||||
None
|
||||
|
||||
if GetDepend(['RT_USING_AUDIO']):
|
||||
None
|
||||
|
||||
if GetDepend(['BSP_USING_ON_CHIP_FLASH']):
|
||||
None
|
||||
|
||||
if GetDepend(['BSP_USING_GMAC']):
|
||||
src += ['bsp/ft_gmac/ft_gmac_desc.c']
|
||||
src += ['bsp/ft_gmac/ft_gmac_g.c']
|
||||
src += ['bsp/ft_gmac/ft_gmac_hw.c']
|
||||
src += ['bsp/ft_gmac/ft_gmac_intr.c']
|
||||
src += ['bsp/ft_gmac/ft_gmac_sinit.c']
|
||||
src += ['bsp/ft_gmac/ft_gmac.c']
|
||||
|
||||
if GetDepend(['BSP_USING_SDC']):
|
||||
src += ['bsp/ft_sd/ft_sdctrl_option.c']
|
||||
src += ['bsp/ft_sd/ft_sdctrl_sinit.c']
|
||||
src += ['bsp/ft_sd/ft_sdctrl_intr.c']
|
||||
src += ['bsp/ft_sd/ft_sdctrl_g.c']
|
||||
src += ['bsp/ft_sd/ft_sdctrl_hw.c']
|
||||
src += ['bsp/ft_sd/ft_sdctrl.c']
|
||||
|
||||
if GetDepend(['BSP_USE_QSPI']):
|
||||
src += ['bsp/ft_qspi/qspi_g.c']
|
||||
src += ['bsp/ft_qspi/qspi_hw.c']
|
||||
src += ['bsp/ft_qspi/ft_qspi.c']
|
||||
src += ['bsp/ft_qspi/qspi_sinit.c']
|
||||
|
||||
if GetDepend(['BSP_USE_SPI']):
|
||||
src += ['bsp/ft_spi/ft_spi.c']
|
||||
src += ['bsp/ft_spi/ft_spi_irq.c']
|
||||
|
||||
if GetDepend(['BSP_USE_GPIO']):
|
||||
src += ['bsp/ft_gpio/ft_gpio.c']
|
||||
|
||||
path = [cwd + '/bsp/standlone/',
|
||||
cwd + '/bsp/ft_gicv3',
|
||||
cwd + '/bsp/ft_gmac',
|
||||
cwd + '/bsp/ft_uart',
|
||||
cwd + '/bsp/ft_sd',
|
||||
cwd + '/bsp/ft_qspi',
|
||||
cwd + '/bsp/ft_can',
|
||||
cwd + '/bsp/ft_spi',
|
||||
cwd + '/bsp/ft_gpio',
|
||||
cwd + '/bsp/include',
|
||||
cwd + '/include',
|
||||
cwd + '/cpu', ]
|
||||
|
||||
|
||||
CPPDEFINES = ['USE_FT_DRIVER']
|
||||
group = DefineGroup('FT_DRIVER', src, depend=[
|
||||
''], CPPPATH=path, CPPDEFINES=CPPDEFINES)
|
||||
|
||||
Return('group')
|
||||
299
bsp/ft2004/libraries/bsp/ft_can/ft_can.c
Normal file
299
bsp/ft2004/libraries/bsp/ft_can/ft_can.c
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-04-29 10:21:53
|
||||
* @LastEditTime: 2021-05-25 16:41:38
|
||||
* @Description: Description of file
|
||||
* @Modify History:
|
||||
* * * Ver Who Date Changes
|
||||
* * ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#include "ft_can.h"
|
||||
#include "ft_can_hw.h"
|
||||
#include "ft_assert.h"
|
||||
#include "ft_debug.h"
|
||||
#include "string.h"
|
||||
|
||||
#define FT_CAN_DEBUG_TAG "FT_CAN"
|
||||
|
||||
#define FT_CAN_DEBUG_I(format, ...) FT_DEBUG_PRINT_I(FT_CAN_DEBUG_TAG, format, ##__VA_ARGS__)
|
||||
#define FT_CAN_DEBUG_E(format, ...) FT_DEBUG_PRINT_E(FT_CAN_DEBUG_TAG, format, ##__VA_ARGS__)
|
||||
#define FT_CAN_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(FT_CAN_DEBUG_TAG, format, ##__VA_ARGS__)
|
||||
|
||||
ft_error_t
|
||||
FCan_CfgInitialize(FCan_t *Can_p, FCan_Config_t *Config_p)
|
||||
{
|
||||
Ft_assertNonvoid(Can_p != NULL);
|
||||
Ft_assertNonvoid(Config_p != NULL);
|
||||
Can_p->Config = *Config_p;
|
||||
Can_p->IsReady = FT_COMPONENT_IS_READLY;
|
||||
FCan_Reset(Can_p);
|
||||
return FCAN_SUCCESS;
|
||||
}
|
||||
|
||||
void FCan_GetErrorCnt(FCan_t *Can_p, u32 *TxErr, u32 *RxErr)
|
||||
{
|
||||
FCan_Config_t *Config_p;
|
||||
Ft_assertVoid(Can_p != NULL);
|
||||
Ft_assertVoid(Can_p->IsReady == FT_COMPONENT_IS_READLY);
|
||||
Config_p = &Can_p->Config;
|
||||
|
||||
*RxErr = FCan_ReadReg(Config_p->CanBaseAddress, FCAN_ERR_CNT_OFFSET) & FCAN_ERR_CNT_RFN_MASK;
|
||||
*TxErr = (FCan_ReadReg(Config_p->CanBaseAddress, FCAN_ERR_CNT_OFFSET) & FCAN_ERR_CNT_TFN_MASK) >> FCAN_ERR_CNT_TFN_SHIFT;
|
||||
}
|
||||
|
||||
u32 FCan_RecvByIrq(FCan_t *Can_p, struct FCan_Frame *Frame_p, u32 FrameNumber)
|
||||
{
|
||||
u32 FifoCnt = 0;
|
||||
FCan_Config_t *Config_p;
|
||||
u32 CanId;
|
||||
u32 Dlc;
|
||||
u32 CanFrameIndex = 0;
|
||||
u32 RxValue;
|
||||
Ft_assertZeroNum(Can_p != NULL);
|
||||
Ft_assertZeroNum(Can_p->IsReady == FT_COMPONENT_IS_READLY);
|
||||
Config_p = &Can_p->Config;
|
||||
|
||||
FifoCnt = FCan_ReadReg(Config_p->CanBaseAddress, FCAN_FIFO_CNT_OFFSET) & 0x3f;
|
||||
|
||||
if (0 == FifoCnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
FrameNumber = (FrameNumber > FifoCnt) ? FifoCnt : FrameNumber;
|
||||
|
||||
while (FrameNumber)
|
||||
{
|
||||
/* Read a frame from Phytium CAN */
|
||||
CanId = FCan_ReadReg(Config_p->CanBaseAddress, FCAN_RX_FIFO_OFFSET);
|
||||
/* if CanId is big-endian ,use swap change to little-endian */
|
||||
CanId = FT_SWAP32(CanId);
|
||||
/* Identifier extension */
|
||||
if (CanId & FCAN_IDR_IDE_MASK)
|
||||
{
|
||||
Dlc = FCan_ReadReg(Config_p->CanBaseAddress, FCAN_RX_FIFO_OFFSET);
|
||||
Dlc = FT_SWAP32(Dlc);
|
||||
Dlc = ((Dlc & FCAN_IDR_EDLC_MASK) >> FCAN_IDR_EDLC_SHIFT);
|
||||
|
||||
Frame_p[CanFrameIndex].CanId = (CanId & FCAN_IDR_ID1_MASK) >> 3;
|
||||
Frame_p[CanFrameIndex].CanId |= (CanId & FCAN_IDR_ID2_MASK) >> FCAN_IDR_ID2_SHIFT;
|
||||
Frame_p[CanFrameIndex].CanId |= CAN_EFF_FLAG;
|
||||
|
||||
if (CanId & FCAN_IDR_RTR_MASK)
|
||||
{
|
||||
Frame_p[CanFrameIndex].CanId |= CAN_RTR_FLAG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Dlc = ((CanId & FCAN_IDR_DLC_MASK) >> FCAN_IDR_SDLC_SHIFT);
|
||||
|
||||
/* The received frame is a standard format frame */
|
||||
Frame_p[CanFrameIndex].CanId = (CanId & FCAN_IDR_ID1_MASK) >> FCAN_IDR_ID1_SHIFT;
|
||||
if (CanId & FCAN_IDR_SRR_MASK)
|
||||
{
|
||||
Frame_p[CanFrameIndex].CanId |= CAN_RTR_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
Frame_p[CanFrameIndex].CanDlc = (Dlc > sizeof(Frame_p[CanFrameIndex].data)) ? sizeof(Frame_p[CanFrameIndex].data) : Dlc;
|
||||
|
||||
if (!(Frame_p[CanFrameIndex].CanId & CAN_RTR_FLAG))
|
||||
{
|
||||
if (Frame_p[CanFrameIndex].CanDlc > 0)
|
||||
{
|
||||
RxValue = FCan_ReadReg(Config_p->CanBaseAddress, FCAN_RX_FIFO_OFFSET);
|
||||
memcpy(Frame_p[CanFrameIndex].data, &RxValue, sizeof(RxValue));
|
||||
}
|
||||
|
||||
if (Frame_p[CanFrameIndex].CanDlc > 4)
|
||||
{
|
||||
RxValue = FCan_ReadReg(Config_p->CanBaseAddress, FCAN_RX_FIFO_OFFSET);
|
||||
memcpy(&Frame_p[CanFrameIndex].data[4], &RxValue, sizeof(RxValue));
|
||||
}
|
||||
}
|
||||
FrameNumber--;
|
||||
CanFrameIndex++;
|
||||
}
|
||||
|
||||
return (CanFrameIndex + 1);
|
||||
}
|
||||
|
||||
static void FCan_SendFifo(FCan_t *Can_p, struct FCan_Frame *Frame_p)
|
||||
{
|
||||
u32 Id, Dlc;
|
||||
FCan_Config_t *Config_p;
|
||||
u32 SendBuffer = 0;
|
||||
Ft_assertVoid(Can_p != NULL);
|
||||
Ft_assertVoid(Can_p->IsReady == FT_COMPONENT_IS_READLY);
|
||||
Config_p = &Can_p->Config;
|
||||
if (Frame_p->CanId & CAN_EFF_FLAG)
|
||||
{
|
||||
/* Extended CAN ID format */
|
||||
Id = ((Frame_p->CanId & CAN_EFF_MASK) << FCAN_IDR_ID2_SHIFT) &
|
||||
FCAN_IDR_ID2_MASK;
|
||||
Id |= (((Frame_p->CanId & CAN_EFF_MASK) >>
|
||||
(CAN_EFF_ID_BITS - CAN_SFF_ID_BITS))
|
||||
<< FCAN_IDR_ID1_SHIFT) &
|
||||
FCAN_IDR_ID1_MASK;
|
||||
|
||||
Id |= FCAN_IDR_IDE_MASK | FCAN_IDR_SRR_MASK;
|
||||
if (Frame_p->CanId & CAN_RTR_FLAG)
|
||||
{
|
||||
Id |= FCAN_IDR_RTR_MASK;
|
||||
}
|
||||
|
||||
Dlc = Frame_p->CanDlc << FCAN_IDR_EDLC_SHIFT;
|
||||
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_TX_FIFO_OFFSET, FT_SWAP32(Id));
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_TX_FIFO_OFFSET, FT_SWAP32(Dlc));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Standard CAN ID format */
|
||||
Id = ((Frame_p->CanId & CAN_SFF_MASK) << FCAN_IDR_ID1_SHIFT) &
|
||||
FCAN_IDR_ID1_MASK;
|
||||
if (Frame_p->CanId & CAN_RTR_FLAG)
|
||||
Id |= FCAN_IDR_SRR_MASK;
|
||||
|
||||
Dlc = ((Frame_p->CanDlc << FCAN_IDR_SDLC_SHIFT) | FCAN_IDR_PAD_MASK);
|
||||
Id |= Dlc;
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_TX_FIFO_OFFSET, FT_SWAP32(Id));
|
||||
}
|
||||
|
||||
if (!(Frame_p->CanId & CAN_RTR_FLAG))
|
||||
{
|
||||
if (Frame_p->CanDlc > 0)
|
||||
{
|
||||
memcpy(&SendBuffer, Frame_p->data, 4);
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_TX_FIFO_OFFSET, SendBuffer);
|
||||
}
|
||||
|
||||
if (Frame_p->CanDlc > 4)
|
||||
{
|
||||
memcpy(&SendBuffer, &Frame_p->data[4], 4);
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_TX_FIFO_OFFSET, SendBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 FCan_SendByIrq(FCan_t *Can_p,
|
||||
struct FCan_Frame *Frame_p,
|
||||
u32 FrameNumber, void (*UserIrqWait)(void))
|
||||
{
|
||||
FCan_Config_t *Config_p;
|
||||
u32 FrameIndex = 0;
|
||||
u32 NeedSendOnce;
|
||||
u32 cnt = 0;
|
||||
Ft_assertZeroNum(Can_p != NULL);
|
||||
Ft_assertZeroNum(Can_p->IsReady == FT_COMPONENT_IS_READLY);
|
||||
Config_p = &Can_p->Config;
|
||||
|
||||
if (NULL == Frame_p)
|
||||
{
|
||||
FT_CAN_DEBUG_E("Frame_p is NULL , %s: %d", __FILE__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 == FrameNumber)
|
||||
{
|
||||
FT_CAN_DEBUG_E("FrameNumber is 0 , %s: %d", __FILE__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (; 0 < FrameNumber;)
|
||||
{
|
||||
if (FrameNumber > Config_p->TxFifoDeepth)
|
||||
{
|
||||
NeedSendOnce = Config_p->TxFifoDeepth;
|
||||
FrameNumber -= Config_p->TxFifoDeepth;
|
||||
}
|
||||
else
|
||||
{
|
||||
NeedSendOnce = FrameNumber;
|
||||
FrameNumber = 0;
|
||||
}
|
||||
Ft_printf("shut down tranmission \r\n");
|
||||
/*shut down tranmission*/
|
||||
FCan_ClearBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
|
||||
FCan_ClearBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_TXREQ_MASK);
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
|
||||
Ft_printf("NeedSendOnce %d \r\n", NeedSendOnce);
|
||||
for (cnt = 0; cnt < NeedSendOnce; cnt++)
|
||||
{
|
||||
FCan_SendFifo(Can_p, &Frame_p[FrameIndex]);
|
||||
FrameIndex++;
|
||||
}
|
||||
Can_p->TxFifoCnt = NeedSendOnce;
|
||||
|
||||
/* triggers tranmission */
|
||||
FCan_ClearBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_TXREQ_MASK);
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_TXREQ_MASK | FCAN_CTRL_XFER_MASK);
|
||||
|
||||
if (UserIrqWait)
|
||||
{
|
||||
UserIrqWait();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (0 != Can_p->TxFifoCnt)
|
||||
{
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return FrameIndex + 1;
|
||||
}
|
||||
|
||||
ft_error_t FCan_SetTiming(FCan_t *Can_p,
|
||||
struct FCan_Bittiming *Bittiming_p)
|
||||
{
|
||||
u32 Btr = 0;
|
||||
FCan_Config_t *Config_p;
|
||||
u32 IsConfigMode;
|
||||
Ft_assertNonvoid(Can_p != NULL);
|
||||
Ft_assertNonvoid(Can_p->IsReady == FT_COMPONENT_IS_READLY);
|
||||
Config_p = &Can_p->Config;
|
||||
|
||||
Ft_assertNonvoid(Bittiming_p->brp != 0);
|
||||
Ft_assertNonvoid(Bittiming_p->prop_seg != 0);
|
||||
Ft_assertNonvoid(Bittiming_p->phase_seg1 != 0);
|
||||
Ft_assertNonvoid(Bittiming_p->phase_seg2 != 0);
|
||||
|
||||
/* Setting Baud Rate prescalar value in BRPR Register */
|
||||
Btr = (Bittiming_p->brp - 1) << 16;
|
||||
Btr |= (Bittiming_p->prop_seg - 1) << 2;
|
||||
Btr |= (Bittiming_p->phase_seg1 - 1) << 5;
|
||||
Btr |= (Bittiming_p->phase_seg2 - 1) << 8;
|
||||
Btr |= (Bittiming_p->sjw - 1);
|
||||
|
||||
IsConfigMode = (FCan_ReadReg(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET) & FCAN_CTRL_XFER_MASK);
|
||||
|
||||
if (IsConfigMode)
|
||||
{
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
|
||||
}
|
||||
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_DAT_RATE_CTRL_OFFSET, Btr);
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_ARB_RATE_CTRL_OFFSET, Btr);
|
||||
|
||||
/*Enable Transfer*/
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
|
||||
|
||||
return FCAN_SUCCESS;
|
||||
}
|
||||
|
||||
void FCan_Enable(FCan_t *Can_p)
|
||||
{
|
||||
FCan_Config_t *Config_p;
|
||||
Ft_assertVoid(Can_p != NULL);
|
||||
Ft_assertVoid(Can_p->IsReady == FT_COMPONENT_IS_READLY);
|
||||
Config_p = &Can_p->Config;
|
||||
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
|
||||
}
|
||||
142
bsp/ft2004/libraries/bsp/ft_can/ft_can.h
Normal file
142
bsp/ft2004/libraries/bsp/ft_can/ft_can.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-04-27 15:08:44
|
||||
* @LastEditTime: 2021-04-27 15:08:44
|
||||
* @Description: Description of file
|
||||
* @Modify History:
|
||||
* * * Ver Who Date Changes
|
||||
* * ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef FT_CAN_H
|
||||
#define FT_CAN_H
|
||||
|
||||
#include "ft_types.h"
|
||||
#include "ft_error_code.h"
|
||||
|
||||
#define FCAN_SUCCESS FST_SUCCESS /* SUCCESS */
|
||||
#define FCAN_FAILURE FT_MAKE_ERRCODE(errCan, errBspGeneral, FST_FAILURE) /* Normal */
|
||||
#define FCAN_TIMEOUT FT_MAKE_ERRCODE(errCan, errBspGeneral, FST_TIMEOUT) /* Timeout */
|
||||
#define FCAN_EILSEQ FT_MAKE_ERRCODE(errCan, errBspGeneral, FST_EILSEQ) /* Illegal byte sequence. */
|
||||
#define FCAN_INVALID_PARAM FT_MAKE_ERRCODE(errCan, errBspGeneral, FST_INVALID_PARAM) /* Invalid param. */
|
||||
|
||||
#define FCAN_HANDLER_SEND 1U /**< Handler type for frame sending interrupt */
|
||||
#define FCAN_HANDLER_RECV 2U /**< Handler type for frame reception interrupt*/
|
||||
#define FCAN_HANDLER_ERROR 3U /**< Handler type for error interrupt */
|
||||
#define FCAN_DATA_LENGTH 8U
|
||||
|
||||
/* CAN payload length and DLC definitions according to ISO 11898-1 */
|
||||
#define CAN_MAX_DLC 8
|
||||
#define CAN_MAX_DLEN 8
|
||||
#define CAN_MAX_CTL 3
|
||||
#define CAN_SFF_ID_BITS 11
|
||||
#define CAN_EFF_ID_BITS 29
|
||||
|
||||
/* special address description flags for the CAN_ID */
|
||||
#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
|
||||
#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
|
||||
#define CAN_ERR_FLAG 0x20000000U /* error message frame */
|
||||
|
||||
/* valid bits in CAN ID for frame formats */
|
||||
#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
|
||||
#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
|
||||
#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */
|
||||
|
||||
/* Frame type */
|
||||
#define STANDARD_FRAME 0 /* standard frame */
|
||||
#define EXTEND_FRAME 1 /* extended frame */
|
||||
|
||||
typedef void (*FCan_irqHandler_t)(void *Args);
|
||||
|
||||
struct FCan_Frame
|
||||
{
|
||||
u32 CanId;
|
||||
u8 CanDlc;
|
||||
u8 data[FCAN_DATA_LENGTH];
|
||||
};
|
||||
|
||||
struct FCan_Bittiming
|
||||
{
|
||||
u32 bitrate; /* Bit-rate in bits/second */
|
||||
u32 sample_point; /* Sample point in one-tenth of a percent */
|
||||
u32 tq; /* Time quanta (TQ) in nanoseconds */
|
||||
u32 prop_seg; /* Propagation segment in TQs */
|
||||
u32 phase_seg1; /* Phase buffer segment 1 in TQs */
|
||||
u32 phase_seg2; /* Phase buffer segment 2 in TQs */
|
||||
u32 sjw; /* Synchronisation jump width in TQs */
|
||||
u32 brp; /* Bit-rate prescaler */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 InstanceId; /* Id of device */
|
||||
u32 CanBaseAddress; /* Can base Address */
|
||||
u32 IrqNum;
|
||||
u32 BaudRate;
|
||||
u32 TxFifoDeepth; /* The depth of the full frame , */
|
||||
} FCan_Config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FCan_Config_t Config;
|
||||
u32 IsReady; /* Device is initialized and ready */
|
||||
|
||||
volatile u32 TxFifoCnt;
|
||||
|
||||
FCan_irqHandler_t SendHandler;
|
||||
void *SendRef;
|
||||
|
||||
FCan_irqHandler_t RecvHandler;
|
||||
void *RecvRef;
|
||||
|
||||
FCan_irqHandler_t ErrorHandler;
|
||||
void *ErrorRef;
|
||||
|
||||
} FCan_t;
|
||||
|
||||
FCan_Config_t *FCan_LookupConfig(u32 InstanceId);
|
||||
|
||||
/**
|
||||
* @name: FCan_CfgInitialize
|
||||
* @msg: This function initializes a Can instance/driver.
|
||||
* @in param Can_p: Can_p is a pointer to the FCan_t instance.
|
||||
* @in param Config_p: Config_p points to the FCan_t device configuration structure.
|
||||
* @return {*}
|
||||
*/
|
||||
ft_error_t FCan_CfgInitialize(FCan_t *Can_p, FCan_Config_t *Config_p);
|
||||
|
||||
/**
|
||||
* @name: FCan_SetHandler
|
||||
* @msg: This routine installs an asynchronous callback function for the given
|
||||
* @inout param Can_p: Can_p is a pointer to the FCan_t instance.
|
||||
* @in param HandlerType: specifies which handler is to be attached.
|
||||
* @in param IrqCallBackFunc: IrqCallBackFunc is the address of the callback function.
|
||||
* @in param IrqCallBackRef: IrqCallBackRef is a user data item that will be passed to the
|
||||
* callback function when it is invoked.
|
||||
* @return {*}
|
||||
* @param {FCan_t} *Can_p
|
||||
* @param {u32} HandlerType
|
||||
* @param {FCan_irqHandler_t} *IrqCallBackFunc
|
||||
* @param {void} *IrqCallBackRef
|
||||
*/
|
||||
ft_error_t FCan_SetHandler(FCan_t *Can_p, u32 HandlerType, FCan_irqHandler_t IrqCallBackFunc, void *IrqCallBackRef);
|
||||
|
||||
ft_error_t FCan_SetTiming(FCan_t *Can_p,
|
||||
struct FCan_Bittiming *Bittiming_p);
|
||||
|
||||
void FCan_IntrHandler(void *InstancePtr);
|
||||
|
||||
ft_error_t FCan_CalcBittiming(struct FCan_Bittiming *Bt_p);
|
||||
|
||||
u32 FCan_SendByIrq(FCan_t *Can_p,
|
||||
struct FCan_Frame *Frame_p,
|
||||
u32 FrameNumber, void (*UserIrqWait)(void));
|
||||
|
||||
u32 FCan_RecvByIrq(FCan_t *Can_p, struct FCan_Frame *Frame_p, u32 FrameNumber);
|
||||
|
||||
void FCan_Enable(FCan_t *Can_p);
|
||||
|
||||
#endif // !FT_CAN_H
|
||||
269
bsp/ft2004/libraries/bsp/ft_can/ft_can_calc.c
Normal file
269
bsp/ft2004/libraries/bsp/ft_can/ft_can_calc.c
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-05-06 09:30:51
|
||||
* @LastEditTime: 2021-05-25 16:41:10
|
||||
* @Description: Description of file
|
||||
* @Modify History:
|
||||
* * * Ver Who Date Changes
|
||||
* * ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#include "ft_can.h"
|
||||
|
||||
#include "ft_debug.h"
|
||||
#include "string.h"
|
||||
|
||||
#ifndef max
|
||||
#define max(x, y) (((x) < (y)) ? (y) : (x))
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#define FT_CAN_DEBUG_TAG "FT_CAN"
|
||||
|
||||
#define FT_CAN_DEBUG_I(format, ...) FT_DEBUG_PRINT_I(FT_CAN_DEBUG_TAG, format, ##__VA_ARGS__)
|
||||
#define FT_CAN_DEBUG_E(format, ...) FT_DEBUG_PRINT_E(FT_CAN_DEBUG_TAG, format, ##__VA_ARGS__)
|
||||
#define FT_CAN_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(FT_CAN_DEBUG_TAG, format, ##__VA_ARGS__)
|
||||
|
||||
#define CAN_CLK_FREQ 600000000
|
||||
#define CAN_CALC_SYNC_SEG 1
|
||||
#define FCAN_TSEG1_MIN 1
|
||||
#define FCAN_TSEG1_MAX 8
|
||||
#define FCAN_TSEG2_MIN 1
|
||||
#define FCAN_TSEG2_MAX 8
|
||||
#define FCAN_SJW_MAX 4
|
||||
#define FCAN_BRP_MIN 1
|
||||
#define FCAN_BRP_MAX 512
|
||||
#define FCAN_BRP_INC 1
|
||||
#define FCAN_CALC_SYNC_SEG 1
|
||||
#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */
|
||||
#define BEST_BITRATE_ERROR (2147483647 * 2U + 1)
|
||||
|
||||
#define clamp(x, low, high) (min(max(low, x), high))
|
||||
|
||||
typedef struct can_bittiming_const
|
||||
{
|
||||
char name[16]; /* Name of the CAN controller hardware */
|
||||
u32 tseg1_min; /* Time segement 1 = prop_seg + phase_seg1 */
|
||||
u32 tseg1_max;
|
||||
u32 tseg2_min; /* Time segement 2 = phase_seg2 */
|
||||
u32 tseg2_max;
|
||||
u32 sjw_max; /* Synchronisation jump width */
|
||||
u32 brp_min; /* Bit-rate prescaler */
|
||||
u32 brp_max;
|
||||
u32 brp_inc;
|
||||
} FTCAN_BITTIMING_CONST;
|
||||
|
||||
static const struct can_bittiming_const ftcan_bittiming_const = {
|
||||
.name = "vxbftCan",
|
||||
.tseg1_min = 1,
|
||||
.tseg1_max = 8,
|
||||
.tseg2_min = 1,
|
||||
.tseg2_max = 8,
|
||||
.sjw_max = 4,
|
||||
.brp_min = 1,
|
||||
.brp_max = 512,
|
||||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
static int abs(
|
||||
int i /* integer for which to return absolute value */
|
||||
)
|
||||
{
|
||||
return (i >= 0 ? i : -i);
|
||||
}
|
||||
|
||||
static u32 div64_32(u64 *n, u32 base)
|
||||
{
|
||||
u64 rem = *n;
|
||||
u64 b = base;
|
||||
u64 res, d = 1;
|
||||
u32 high = rem >> 32;
|
||||
|
||||
/* Reduce the thing a bit first */
|
||||
res = 0;
|
||||
if (high >= base)
|
||||
{
|
||||
high /= base;
|
||||
res = (u64)high << 32;
|
||||
rem -= (u64)(high * base) << 32;
|
||||
}
|
||||
|
||||
while ((u64)b > 0 && b < rem)
|
||||
{
|
||||
b = b + b;
|
||||
d = d + d;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (rem >= b)
|
||||
{
|
||||
rem -= b;
|
||||
res += d;
|
||||
}
|
||||
b >>= 1;
|
||||
d >>= 1;
|
||||
} while (d);
|
||||
|
||||
*n = res;
|
||||
return rem;
|
||||
}
|
||||
|
||||
s32 can_update_sample_point(const struct can_bittiming_const *btc,
|
||||
u32 sample_point_nominal, u32 tseg,
|
||||
u32 *tseg1_ptr, u32 *tseg2_ptr,
|
||||
u32 *sample_point_error_ptr)
|
||||
{
|
||||
u32 sample_point_error, best_sample_point_error = BEST_BITRATE_ERROR;
|
||||
u32 sample_point, best_sample_point = 0;
|
||||
u32 tseg1, tseg2;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i <= 1; i++)
|
||||
{
|
||||
tseg2 = tseg + CAN_CALC_SYNC_SEG - (sample_point_nominal * (tseg + CAN_CALC_SYNC_SEG)) / 1000 - i;
|
||||
tseg2 = clamp(tseg2, btc->tseg2_min, btc->tseg2_max);
|
||||
tseg1 = tseg - tseg2;
|
||||
if (tseg1 > btc->tseg1_max)
|
||||
{
|
||||
tseg1 = btc->tseg1_max;
|
||||
tseg2 = tseg - tseg1;
|
||||
}
|
||||
|
||||
sample_point = 1000 * (tseg + CAN_CALC_SYNC_SEG - tseg2) / (tseg + CAN_CALC_SYNC_SEG);
|
||||
sample_point_error = abs(sample_point_nominal - sample_point);
|
||||
|
||||
if ((sample_point <= sample_point_nominal) && (sample_point_error < best_sample_point_error))
|
||||
{
|
||||
best_sample_point = sample_point;
|
||||
best_sample_point_error = sample_point_error;
|
||||
*tseg1_ptr = tseg1;
|
||||
*tseg2_ptr = tseg2;
|
||||
}
|
||||
}
|
||||
|
||||
if (sample_point_error_ptr)
|
||||
*sample_point_error_ptr = best_sample_point_error;
|
||||
|
||||
return best_sample_point;
|
||||
}
|
||||
|
||||
ft_error_t FCan_CalcBittiming(struct FCan_Bittiming *Bt_p)
|
||||
{
|
||||
u32 bitrate; /* current bitrate */
|
||||
u32 bitrate_error; /* difference between current and nominal value */
|
||||
u32 best_bitrate_error = BEST_BITRATE_ERROR;
|
||||
u32 sample_point_error; /* difference between current and nominal value */
|
||||
u32 best_sample_point_error = BEST_BITRATE_ERROR;
|
||||
u32 sample_point_nominal; /* nominal sample point */
|
||||
u32 best_tseg = 0; /* current best value for tseg */
|
||||
u32 best_brp = 0; /* current best value for brp */
|
||||
u32 brp, tsegall, tseg, tseg1 = 0, tseg2 = 0;
|
||||
u64 v64;
|
||||
const struct can_bittiming_const *btc = &ftcan_bittiming_const;
|
||||
struct FCan_Bittiming *bt = Bt_p;
|
||||
|
||||
if (bt->sample_point)
|
||||
{
|
||||
sample_point_nominal = bt->sample_point;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bt->bitrate > 800000)
|
||||
sample_point_nominal = 750;
|
||||
else if (bt->bitrate > 500000)
|
||||
sample_point_nominal = 800;
|
||||
else
|
||||
sample_point_nominal = 875;
|
||||
}
|
||||
|
||||
for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1;
|
||||
tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--)
|
||||
{
|
||||
tsegall = CAN_CALC_SYNC_SEG + tseg / 2;
|
||||
|
||||
/* Compute all possible tseg choices (tseg=tseg1+tseg2) */
|
||||
brp = CAN_CLK_FREQ / (tsegall * bt->bitrate) + tseg % 2;
|
||||
|
||||
/* choose brp step which is possible in system */
|
||||
brp = (brp / btc->brp_inc) * btc->brp_inc;
|
||||
|
||||
if ((brp < btc->brp_min) || (brp > btc->brp_max))
|
||||
continue;
|
||||
|
||||
bitrate = CAN_CLK_FREQ / (brp * tsegall);
|
||||
|
||||
bitrate_error = abs(bt->bitrate - bitrate);
|
||||
/* tseg brp biterror */
|
||||
if (bitrate_error > best_bitrate_error)
|
||||
continue;
|
||||
|
||||
/* reset sample point error if we have a better bitrate */
|
||||
if (bitrate_error < best_bitrate_error)
|
||||
best_sample_point_error = BEST_BITRATE_ERROR;
|
||||
|
||||
can_update_sample_point(btc, sample_point_nominal, tseg / 2, &tseg1, &tseg2, &sample_point_error);
|
||||
if (sample_point_error > best_sample_point_error)
|
||||
continue;
|
||||
|
||||
best_sample_point_error = sample_point_error;
|
||||
best_bitrate_error = bitrate_error;
|
||||
best_tseg = tseg / 2;
|
||||
best_brp = brp;
|
||||
|
||||
if (bitrate_error == 0 && sample_point_error == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (best_bitrate_error)
|
||||
{
|
||||
/* Error in one-tenth of a percent */
|
||||
v64 = (u64)best_bitrate_error * 1000;
|
||||
div64_32(&v64, bt->bitrate);
|
||||
bitrate_error = (u32)v64;
|
||||
if (bitrate_error > CAN_CALC_MAX_ERROR)
|
||||
{
|
||||
FT_CAN_DEBUG_E("bitrate error");
|
||||
}
|
||||
return FCAN_FAILURE;
|
||||
FT_CAN_DEBUG_E("bitrate error 2");
|
||||
}
|
||||
|
||||
/* real sample point */
|
||||
bt->sample_point = can_update_sample_point(btc, sample_point_nominal, best_tseg,
|
||||
&tseg1, &tseg2, NULL);
|
||||
|
||||
v64 = (u64)best_brp * 1000 * 1000 * 1000;
|
||||
div64_32(&v64, CAN_CLK_FREQ);
|
||||
bt->tq = (u64)v64;
|
||||
bt->prop_seg = tseg1 / 2;
|
||||
bt->phase_seg1 = tseg1 - bt->prop_seg;
|
||||
bt->phase_seg2 = tseg2;
|
||||
|
||||
/* check for sjw user settings */
|
||||
if (!bt->sjw || !btc->sjw_max)
|
||||
{
|
||||
bt->sjw = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */
|
||||
if (bt->sjw > btc->sjw_max)
|
||||
bt->sjw = btc->sjw_max;
|
||||
/* bt->sjw must not be higher than tseg2 */
|
||||
if (tseg2 < bt->sjw)
|
||||
bt->sjw = tseg2;
|
||||
}
|
||||
|
||||
bt->brp = best_brp;
|
||||
|
||||
/* real bitrate */
|
||||
bt->bitrate = CAN_CLK_FREQ / (bt->brp * (CAN_CALC_SYNC_SEG + tseg1 + tseg2));
|
||||
return FCAN_SUCCESS;
|
||||
}
|
||||
39
bsp/ft2004/libraries/bsp/ft_can/ft_can_g.c
Normal file
39
bsp/ft2004/libraries/bsp/ft_can/ft_can_g.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-04-27 15:31:44
|
||||
* @LastEditTime: 2021-04-27 15:31:44
|
||||
* @Description: Description of file
|
||||
* @Modify History:
|
||||
* * * Ver Who Date Changes
|
||||
* * ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#include "ft_can.h"
|
||||
#include "ft_parameters.h"
|
||||
|
||||
FCan_Config_t FCan_Config[FT_CAN_NUM] =
|
||||
{
|
||||
{
|
||||
.InstanceId = 0, /* Id of device */
|
||||
.CanBaseAddress = FT_CAN0_BASEADDR, /* Can base Address */
|
||||
.IrqNum = FT_CAN0_IRQNUM,
|
||||
.BaudRate = 250000,
|
||||
.TxFifoDeepth = 16,
|
||||
},
|
||||
{
|
||||
.InstanceId = 1, /* Id of device */
|
||||
.CanBaseAddress = FT_CAN1_BASEADDR, /* Can base Address */
|
||||
.IrqNum = FT_CAN1_IRQNUM,
|
||||
.BaudRate = 250000,
|
||||
.TxFifoDeepth = 16,
|
||||
},
|
||||
{
|
||||
.InstanceId = 2, /* Id of device */
|
||||
.CanBaseAddress = FT_CAN2_BASEADDR, /* Can base Address */
|
||||
.IrqNum = FT_CAN2_IRQNUM,
|
||||
.BaudRate = 250000,
|
||||
.TxFifoDeepth = 16,
|
||||
}};
|
||||
55
bsp/ft2004/libraries/bsp/ft_can/ft_can_hw.c
Normal file
55
bsp/ft2004/libraries/bsp/ft_can/ft_can_hw.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-04-27 13:52:41
|
||||
* @LastEditTime: 2021-04-27 13:52:41
|
||||
* @Description: Description of file
|
||||
* @Modify History:
|
||||
* * * Ver Who Date Changes
|
||||
* * ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#include "ft_can_hw.h"
|
||||
#include "ft_can.h"
|
||||
#include "ft_mux.h"
|
||||
#include "ft_parameters.h"
|
||||
#include "ft_math.h"
|
||||
#include "ft_assert.h"
|
||||
#include "ft_debug.h"
|
||||
|
||||
#define CAN_HW_DEBUG_TAG "CAN_HW"
|
||||
|
||||
#define CAN_HW_DEBUG_I(format, ...) FT_DEBUG_PRINT_I(CAN_HW_DEBUG_TAG, format, ##__VA_ARGS__)
|
||||
#define CAN_HW_DEBUG_E(format, ...) FT_DEBUG_PRINT_E(CAN_HW_DEBUG_TAG, format, ##__VA_ARGS__)
|
||||
#define CAN_HW_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(CAN_HW_DEBUG_TAG, format, ##__VA_ARGS__)
|
||||
|
||||
void FCan_Reset(FCan_t *Can_p)
|
||||
{
|
||||
u32 RegValue;
|
||||
FCan_Config_t *Config_p;
|
||||
Ft_assertVoid(Can_p != NULL);
|
||||
Ft_assertVoid(Can_p->IsReady == FT_COMPONENT_IS_READLY);
|
||||
Config_p = &Can_p->Config;
|
||||
|
||||
RegValue = FCan_ReadReg(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET);
|
||||
|
||||
if (RegValue & FCAN_CTRL_XFER_MASK)
|
||||
{
|
||||
CAN_HW_DEBUG_E("FT can is not in configration mode\n");
|
||||
Ft_assertVoid(0);
|
||||
return;
|
||||
}
|
||||
|
||||
FCan_WriteReg(FT_PIN_DEMUX_BASE, FT_PIN_DEMUX_REG204_OFFSET, 0x89999990); // Reuse can IO
|
||||
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_RESET_MASK);
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_AIME_MASK);
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_ACC_ID0_MASK_OFFSET, FCAN_ACC_IDN_MASK);
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_ACC_ID1_MASK_OFFSET, FCAN_ACC_IDN_MASK);
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_ACC_ID2_MASK_OFFSET, FCAN_ACC_IDN_MASK);
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_ACC_ID3_MASK_OFFSET, FCAN_ACC_IDN_MASK);
|
||||
FCan_ClearBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_RESET_MASK);
|
||||
FCan_WriteReg(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, FCAN_INTR_TEIE_MASK | FCAN_INTR_REIE_MASK);
|
||||
}
|
||||
161
bsp/ft2004/libraries/bsp/ft_can/ft_can_hw.h
Normal file
161
bsp/ft2004/libraries/bsp/ft_can/ft_can_hw.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-04-27 13:52:47
|
||||
* @LastEditTime: 2021-04-27 13:52:47
|
||||
* @Description: Description of file
|
||||
* @Modify History:
|
||||
* * * Ver Who Date Changes
|
||||
* * ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef FT_CAN_HW_H
|
||||
#define FT_CAN_HW_H
|
||||
|
||||
#include "ft_types.h"
|
||||
#include "ft_io.h"
|
||||
#include "ft_can.h"
|
||||
|
||||
/***ft CAN REGISTER offset*/
|
||||
#define FCAN_CTRL_OFFSET 0x00 /* Global control register */
|
||||
#define FCAN_INTR_OFFSET 0x04 /* Interrupt register */
|
||||
#define FCAN_ARB_RATE_CTRL_OFFSET 0x08 /* Arbitration rate control register */
|
||||
#define FCAN_DAT_RATE_CTRL_OFFSET 0x0C /* Data rate control register */
|
||||
#define FCAN_ACC_ID0_OFFSET 0x10 /* Acceptance identifier0 register */
|
||||
#define FCAN_ACC_ID1_OFFSET 0x14 /* Acceptance identifier1 register */
|
||||
#define FCAN_ACC_ID2_OFFSET 0x18 /* Acceptance identifier2 register */
|
||||
#define FCAN_ACC_ID3_OFFSET 0x1C /* Acceptance identifier3 register */
|
||||
#define FCAN_ACC_ID0_MASK_OFFSET 0x20 /* Acceptance identifier0 mask register */
|
||||
#define FCAN_ACC_ID1_MASK_OFFSET 0x24 /* Acceptance identifier1 mask register */
|
||||
#define FCAN_ACC_ID2_MASK_OFFSET 0x28 /* Acceptance identifier2 mask register */
|
||||
#define FCAN_ACC_ID3_MASK_OFFSET 0x2C /* Acceptance identifier3 mask register */
|
||||
#define FCAN_XFER_STS_OFFSET 0x30 /* Transfer status register */
|
||||
#define FCAN_ERR_CNT_OFFSET 0x34 /* Error counter register */
|
||||
#define FCAN_FIFO_CNT_OFFSET 0x38 /* FIFO counter register */
|
||||
#define FCAN_DMA_CTRL_OFFSET 0x3C /* DMA request control register */
|
||||
#define FCAN_TX_FIFO_OFFSET 0x100 /* TX FIFO shadow register */
|
||||
#define FCAN_RX_FIFO_OFFSET 0x200 /* RX FIFO shadow register */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* CAN register bit masks - FCAN_<REG>_<BIT>_MASK */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/* FCAN_CTRL mask */
|
||||
#define FCAN_CTRL_XFER_MASK (0x1 << 0) /* RW */ /*Transfer enable*/
|
||||
#define FCAN_CTRL_TXREQ_MASK (0x1 << 1) /* RW */ /*Transmit request*/
|
||||
#define FCAN_CTRL_AIME_MASK (0x1 << 2) /* RW */ /*Acceptance identifier mask enable*/
|
||||
#define FCAN_CTRL_RESET_MASK (0x1 << 6)
|
||||
|
||||
/* FCAN_INTR mask */
|
||||
#define FCAN_INTR_STATUS_MASK (0xFF << 0) /* RO */ /*the interrupt status*/
|
||||
#define FCAN_INTR_BOIS_MASK (0x1 << 0) /* RO */ /*Bus off interrupt status*/
|
||||
#define FCAN_INTR_PWIS_MASK (0x1 << 1) /* RO */ /*Passive warning interrupt status*/
|
||||
#define FCAN_INTR_PEIS_MASK (0x1 << 2) /* RO */ /*Passive error interrupt status*/
|
||||
#define FCAN_INTR_RFIS_MASK (0x1 << 3) /* RO */ /*RX FIFO full interrupt status*/
|
||||
#define FCAN_INTR_TFIS_MASK (0x1 << 4) /* RO */ /*TX FIFO empty interrupt status*/
|
||||
#define FCAN_INTR_REIS_MASK (0x1 << 5) /* RO */ /*RX frame end interrupt status*/
|
||||
#define FCAN_INTR_TEIS_MASK (0x1 << 6) /* RO */ /*TX frame end interrupt status*/
|
||||
#define FCAN_INTR_EIS_MASK (0x1 << 7) /* RO */ /*Error interrupt status*/
|
||||
|
||||
#define FCAN_INTR_EN_MASK (0xFF << 8) /* RO */ /*the interrupt enable*/
|
||||
#define FCAN_INTR_BOIE_MASK (0x1 << 8) /* RW */ /*Bus off interrupt enable*/
|
||||
#define FCAN_INTR_PWIE_MASK (0x1 << 9) /* RW */ /*Passive warning interrupt enable*/
|
||||
#define FCAN_INTR_PEIE_MASK (0x1 << 10) /* RW */ /*Passive error interrupt enable*/
|
||||
#define FCAN_INTR_RFIE_MASK (0x1 << 11) /* RW */ /*RX FIFO full interrupt enable*/
|
||||
#define FCAN_INTR_TFIE_MASK (0x1 << 12) /* RW */ /*TX FIFO empty interrupt enable*/
|
||||
#define FCAN_INTR_REIE_MASK (0x1 << 13) /* RW */ /*RX frame end interrupt enable*/
|
||||
#define FCAN_INTR_TEIE_MASK (0x1 << 14) /* RW */ /*TX frame end interrupt enable*/
|
||||
#define FCAN_INTR_EIE_MASK (0x1 << 15) /* RW */ /*Error interrupt enable*/
|
||||
|
||||
#define FCAN_INTR_BOIC_MASK (0x1 << 16) /* WO */ /*Bus off interrupt clear*/
|
||||
#define FCAN_INTR_PWIC_MASK (0x1 << 17) /* WO */ /*Passive warning interrupt clear*/
|
||||
#define FCAN_INTR_PEIC_MASK (0x1 << 18) /* WO */ /*Passive error interrupt clear*/
|
||||
#define FCAN_INTR_RFIC_MASK (0x1 << 19) /* WO */ /*RX FIFO full interrupt clear*/
|
||||
#define FCAN_INTR_TFIC_MASK (0x1 << 20) /* WO */ /*TX FIFO empty interrupt clear*/
|
||||
#define FCAN_INTR_REIC_MASK (0x1 << 21) /* WO */ /*RX frame end interrupt clear*/
|
||||
#define FCAN_INTR_TEIC_MASK (0x1 << 22) /* WO */ /*TX frame end interrupt clear*/
|
||||
#define FCAN_INTR_EIC_MASK (0x1 << 23) /* WO */ /*Error interrupt clear*/
|
||||
|
||||
/* FCAN_ACC_ID(0-3)_MASK mask */
|
||||
#define FCAN_ACC_IDN_MASK 0x1FFFFFFF /* WO */ /*don’t care the matching */
|
||||
/* FCAN_DAT_RATE_CTRL mask */
|
||||
|
||||
/* FCAN_ERR_CNT_OFFSET mask */
|
||||
#define FCAN_ERR_CNT_RFN_MASK (0xFF << 0) /* RO */ /*Receive error counter*/
|
||||
#define FCAN_ERR_CNT_TFN_MASK (0xFF << 16) /* RO */ /*Transmit error counter*/
|
||||
|
||||
/* FCAN_FIFO_CNT_OFFSET mask */
|
||||
#define FCAN_FIFO_CNT_RFN_MASK (0xFF << 0) /* RO */ /*Receive FIFO valid data number*/
|
||||
#define FCAN_FIFO_CNT_TFN_MASK (0xFF << 16) /* RO */ /*Transmit FIFO valid data number*/
|
||||
|
||||
#define FCAN_ERR_CNT_TFN_SHIFT 16 /* Tx Error Count shift */
|
||||
#define FCAN_FIFO_CNT_TFN_SHIFT 16 /* Tx FIFO Count shift*/
|
||||
#define FCAN_IDR_ID1_SHIFT 21 /* Standard Messg Identifier */
|
||||
#define FCAN_IDR_ID2_SHIFT 1 /* Extended Message Identifier */
|
||||
#define FCAN_IDR_SDLC_SHIFT 14
|
||||
#define FCAN_IDR_EDLC_SHIFT 26
|
||||
#define FCAN_ACC_IDN_SHIFT 18 /*Standard ACC ID shift*/
|
||||
|
||||
#define FCAN_IDR_ID2_MASK 0x0007FFFE /* Extended message ident */
|
||||
#define FCAN_IDR_ID1_MASK 0xFFE00000 /* Standard msg identifier */
|
||||
#define FCAN_IDR_IDE_MASK 0x00080000 /* Identifier extension */
|
||||
#define FCAN_IDR_SRR_MASK 0x00100000 /* Substitute remote TXreq */
|
||||
#define FCAN_IDR_RTR_MASK 0x00000001 /* Extended frames remote TX request */
|
||||
#define FCAN_IDR_DLC_MASK 0x0003C000 /* Standard msg dlc */
|
||||
#define FCAN_IDR_PAD_MASK 0x00003FFF /* Standard msg padding 1 */
|
||||
#define FCAN_IDR_EDLC_MASK 0x3C000000 /* Extended msg dlc */
|
||||
|
||||
/* Can timming */
|
||||
#define FCAN_TSEG1_MIN 1
|
||||
#define FCAN_TSEG1_MAX 8
|
||||
#define FCAN_TSEG2_MIN 1
|
||||
#define FCAN_TSEG2_MAX 8
|
||||
#define FCAN_SJW_MAX 4
|
||||
#define FCAN_BRP_MIN 1
|
||||
#define FCAN_BRP_MAX 512
|
||||
#define FCAN_BRP_INC 1
|
||||
#define FCAN_CALC_SYNC_SEG 1
|
||||
|
||||
/**
|
||||
*
|
||||
* This macro reads the given register.
|
||||
*
|
||||
* @param BaseAddr is the base address of the device.
|
||||
* @param RegOffset is the register offset to be read.
|
||||
*
|
||||
* @return The 32-bit value of the register
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define FCan_ReadReg(BaseAddr, RegOffset) \
|
||||
Ft_in32((BaseAddr) + (u32)(RegOffset))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro writes the given register.
|
||||
*
|
||||
* @param BaseAddr is the base address of the device.
|
||||
* @param RegOffset is the register offset to be written.
|
||||
* @param Data is the 32-bit value to write to the register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define FCan_WriteReg(BaseAddr, RegOffset, Data) \
|
||||
Ft_out32((BaseAddr) + (u32)(RegOffset), (u32)(Data))
|
||||
|
||||
#define FCan_SetBit(BaseAddr, RegOffset, Data) \
|
||||
Ft_setBit32((BaseAddr) + (u32)(RegOffset), (u32)(Data))
|
||||
|
||||
#define FCan_ClearBit(BaseAddr, RegOffset, Data) \
|
||||
Ft_clearBit32((BaseAddr) + (u32)(RegOffset), (u32)(Data))
|
||||
|
||||
void FCan_Reset(FCan_t *Can_p);
|
||||
|
||||
#endif // !
|
||||
118
bsp/ft2004/libraries/bsp/ft_can/ft_can_intr.c
Normal file
118
bsp/ft2004/libraries/bsp/ft_can/ft_can_intr.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-04-29 10:40:47
|
||||
* @LastEditTime: 2021-04-29 10:40:47
|
||||
* @Description: Description of file
|
||||
* @Modify History:
|
||||
* * * Ver Who Date Changes
|
||||
* * ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#include "ft_can.h"
|
||||
#include "ft_can_hw.h"
|
||||
#include "ft_assert.h"
|
||||
#include "ft_types.h"
|
||||
|
||||
ft_error_t FCan_SetHandler(FCan_t *Can_p, u32 HandlerType, FCan_irqHandler_t IrqCallBackFunc, void *IrqCallBackRef)
|
||||
{
|
||||
ft_error_t status = FCAN_SUCCESS;
|
||||
Ft_assertNonvoid(Can_p != NULL);
|
||||
Ft_assertNonvoid(Can_p->IsReady == FT_COMPONENT_IS_READLY);
|
||||
switch (HandlerType)
|
||||
{
|
||||
case FCAN_HANDLER_SEND:
|
||||
Can_p->SendHandler = IrqCallBackFunc;
|
||||
Can_p->SendRef = IrqCallBackRef;
|
||||
break;
|
||||
case FCAN_HANDLER_RECV:
|
||||
Can_p->RecvHandler = IrqCallBackFunc;
|
||||
Can_p->RecvRef = IrqCallBackRef;
|
||||
break;
|
||||
case FCAN_HANDLER_ERROR:
|
||||
Can_p->ErrorHandler = IrqCallBackFunc;
|
||||
Can_p->ErrorRef = IrqCallBackRef;
|
||||
break;
|
||||
default:
|
||||
status = FCAN_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void FCan_TxInterrupt(FCan_t *Can_p)
|
||||
{
|
||||
FCan_Config_t *Config_p = &Can_p->Config;
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, FCAN_INTR_TEIC_MASK | FCAN_INTR_REIC_MASK);
|
||||
|
||||
if (0 != Can_p->TxFifoCnt)
|
||||
{
|
||||
Can_p->TxFifoCnt--;
|
||||
FCan_ClearBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_TXREQ_MASK);
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Can_p->SendHandler)
|
||||
{
|
||||
Can_p->SendHandler(Can_p->SendRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FCan_ErrorInterrupt(FCan_t *Can_p)
|
||||
{
|
||||
if (Can_p->ErrorHandler)
|
||||
{
|
||||
Can_p->ErrorHandler(Can_p->ErrorRef);
|
||||
}
|
||||
}
|
||||
|
||||
static void FCan_RxInterrupt(FCan_t *Can_p)
|
||||
{
|
||||
if (Can_p->RecvHandler)
|
||||
{
|
||||
Can_p->RecvHandler(Can_p->RecvRef);
|
||||
}
|
||||
}
|
||||
|
||||
void FCan_IntrHandler(void *InstancePtr)
|
||||
{
|
||||
u32 Irq;
|
||||
FCan_t *Can_p = (FCan_t *)InstancePtr;
|
||||
FCan_Config_t *Config_p;
|
||||
Ft_assertVoid(Can_p != NULL);
|
||||
Ft_assertVoid(Can_p->IsReady == FT_COMPONENT_IS_READLY);
|
||||
Config_p = &Can_p->Config;
|
||||
Irq = FCan_ReadReg(Config_p->CanBaseAddress, FCAN_INTR_OFFSET);
|
||||
|
||||
if (0 == Irq)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for the type of error interrupt and Processing it */
|
||||
if (Irq & FCAN_INTR_TEIS_MASK)
|
||||
{
|
||||
Irq &= ~FCAN_INTR_REIS_MASK;
|
||||
FCan_TxInterrupt(Can_p);
|
||||
}
|
||||
|
||||
if (Irq & (FCAN_INTR_EIS_MASK | FCAN_INTR_RFIS_MASK |
|
||||
FCAN_INTR_BOIS_MASK | FCAN_INTR_PEIS_MASK | FCAN_INTR_PWIS_MASK))
|
||||
{
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, (FCAN_INTR_EIC_MASK | FCAN_INTR_RFIC_MASK | FCAN_INTR_BOIC_MASK | FCAN_INTR_PEIC_MASK | FCAN_INTR_PWIC_MASK));
|
||||
FCan_ErrorInterrupt(Can_p);
|
||||
}
|
||||
|
||||
if (Irq & FCAN_INTR_REIS_MASK)
|
||||
{
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, FCAN_INTR_REIE_MASK);
|
||||
FCan_RxInterrupt(Can_p);
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, FCAN_INTR_REIC_MASK);
|
||||
FCan_SetBit(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, FCAN_INTR_REIE_MASK);
|
||||
}
|
||||
}
|
||||
40
bsp/ft2004/libraries/bsp/ft_can/ft_can_sinit.c
Normal file
40
bsp/ft2004/libraries/bsp/ft_can/ft_can_sinit.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* @ : Copyright (c) 2021 Phytium Information Technology, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0.
|
||||
*
|
||||
* @Date: 2021-04-27 15:31:57
|
||||
* @LastEditTime: 2021-04-27 15:31:57
|
||||
* @Description: Description of file
|
||||
* @Modify History:
|
||||
* * * Ver Who Date Changes
|
||||
* * ----- ------ -------- --------------------------------------
|
||||
*/
|
||||
|
||||
#include "ft_can.h"
|
||||
#include "ft_parameters.h"
|
||||
|
||||
extern FCan_Config_t FCan_Config[FT_CAN_NUM];
|
||||
|
||||
/**
|
||||
* @name:
|
||||
* @msg:
|
||||
* @in param:
|
||||
* @return {*}
|
||||
* @param {u32} InstanceId
|
||||
*/
|
||||
FCan_Config_t *FCan_LookupConfig(u32 InstanceId)
|
||||
{
|
||||
FCan_Config_t *CfgPtr = NULL;
|
||||
u32 Index;
|
||||
|
||||
for (Index = 0; Index < (u32)FT_CAN_NUM; Index++)
|
||||
{
|
||||
if (FCan_Config[Index].InstanceId == InstanceId)
|
||||
{
|
||||
CfgPtr = &FCan_Config[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (FCan_Config_t *)CfgPtr;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user