[bsp/bouffalo_lab]add spi driver (#7435)

This commit is contained in:
flyingcys 2023-05-04 11:49:38 +08:00 committed by GitHub
parent ca023c1b41
commit 6edd0586f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1412 additions and 88 deletions

View File

@ -2,7 +2,7 @@
## 1. 简介
bouffalo_lab bsp针对bouffalo_lab的系列AIoT芯片采用bouffalo_lab最新**LHAL** 驱动库,驱动库与[bl_mcu_sdk](https://github.com/bouffalolab/bl_mcu_sdk) 代码同步当前commitid:`47c662afae69309fd49d2721b5c9b93219a91af7`
bouffalo_lab bsp针对bouffalo_lab的系列AIoT芯片采用bouffalo_lab最新**LHAL** 驱动库,驱动库与[bouffalo_sdk](https://github.com/bouffalolab/bouffalo_sdk)(原bl_mcu_sdk)代码同步当前commitid:`e6e8da79a50aeb4fcb67ac380c3bd8885cd56faf`
目前支持以下芯片:
@ -50,9 +50,9 @@ bouffalo_lab bsp针对bouffalo_lab的系列AIoT芯片采用bouffalo_lab最新
## 2. 环境搭建及编译
bl60x/bl70x/bl61x可在对应芯片直接编译bl808是多核异构架构分为m0、lp、d0(适配中,敬请期待),每个核需要单独编译并烧录到对应的位置。
bl60x/bl70x/bl61x可在对应芯片直接编译bl808是多核异构架构分为m0、lp、d0每个核需要单独编译并烧录到对应的位置bl808三核使用详细参考[bl808三核使用指南](./bl808/README.md)
以下操作以bl61x为例其他芯片操作类同。
以下操作以单核bl61x为例其他芯片操作类同。
### 2.1. 下载
@ -106,17 +106,40 @@ Windows下推荐使用[env工具][1]在console下进入bsp/bouffalo_lab/bl61x
脚本会自动采用curl命令行方式下载`bflb_fw_post_proc`,如自动下载失败,可采用手工方式下载对应操作系统文件后保存至`libraries/bl_mcu_sdk/tools/bflb_tools/bflb_fw_post_proc`
[windows](https://raw.githubusercontent.com/bouffalolab/bl_mcu_sdk/master/tools/bflb_tools/bflb_fw_post_proc/bflb_fw_post_proc.exe)
| 下载地址1 | [windows](https://raw.githubusercontent.com/bouffalolab/bl_mcu_sdk/master/tools/bflb_tools/bflb_fw_post_proc/bflb_fw_post_proc.exe)/[Linux](https://raw.githubusercontent.com/bouffalolab/bl_mcu_sdk/master/tools/bflb_tools/bflb_fw_post_proc/bflb_fw_post_proc-ubuntu)/[macos](https://raw.githubusercontent.com/bouffalolab/bl_mcu_sdk/master/tools/bflb_tools/bflb_fw_post_proc/bflb_fw_post_proc-macos) |
| --------- | ------------------------------------------------------------ |
| 下载地址2 | [bflb_fw_post_proc-win.tar.gz](https://gitee.com/flyingcys/bflb_tools/releases/download/v1.0.4/bflb_fw_post_proc-win.tar.gz)/[bflb_fw_post_proc-linux.tar.gz](https://gitee.com/flyingcys/bflb_tools/releases/download/v1.0.4/bflb_fw_post_proc-linux.tar.gz)/[bflb_fw_post_proc-macos.tar.gz](https://gitee.com/flyingcys/bflb_tools/releases/download/v1.0.4/bflb_fw_post_proc-macos.tar.gz) |
| 下载地址3 | [bflb_fw_post_proc-win.tar.gz](https://github.com/flyingcys/bflb_tools/releases/download/v1.0.4/bflb_fw_post_proc-win.tar.gz)/[bflb_fw_post_proc-linux.tar.gz](https://github.com/flyingcys/bflb_tools/releases/download/v1.0.4/bflb_fw_post_proc-linux.tar.gz)/[bflb_fw_post_proc-macos.tar.gz](https://github.com/flyingcys/bflb_tools/releases/download/v1.0.4/bflb_fw_post_proc-macos.tar.gz) |
[Linux](https://raw.githubusercontent.com/bouffalolab/bl_mcu_sdk/master/tools/bflb_tools/bflb_fw_post_proc/bflb_fw_post_proc-ubuntu)
[macos](https://raw.githubusercontent.com/bouffalolab/bl_mcu_sdk/master/tools/bflb_tools/bflb_fw_post_proc/bflb_fw_post_proc-macos)
## 3. 下载烧录
### 3.1. GUI方式下载
### 3.1. 烧录工具下载
当前bsp必须使用[bouffalo_flash_cube-1.0.4](https://pan.baidu.com/s/1eG9pkxf3riAqQAu9aXiOjw?pwd=miv1)工具进行烧录,否则无法正常运行。
当前bsp必须使用`bouffalo_flash_cube-1.0.4`工具进行烧录,使用其他工作无法正常运行。
- 烧录工具下载地址1[百度网盘](https://pan.baidu.com/s/1eG9pkxf3riAqQAu9aXiOjw?pwd=miv1)
- 烧录工具下载地址2
[bouffalo_flash_cube-win.zip](https://gitee.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-win.zip)/[bouffalo_flash_cube-win.tar.gz](https://gitee.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-win.tar.gz)
[bouffalo_flash_cube-linux.zip](https://gitee.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-linux.zip)/[bouffalo_flash_cube-linux.tar.gz](https://gitee.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-linux.tar.gz)
[bouffalo_flash_cube-macos.zip](https://gitee.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-macos.zip)/[bouffalo_flash_cube-macos.tar.gz](https://gitee.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-macos.tar.gz)
- 烧录工具下载地址3
[bouffalo_flash_cube-win.zip](https://github.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-win.zip)/[bouffalo_flash_cube-win.tar.gz](https://github.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-win.tar.gz)
[bouffalo_flash_cube-linux.zip](https://github.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-linux.zip)/[bouffalo_flash_cube-linux.tar.gz](https://github.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-linux.tar.gz)
[bouffalo_flash_cube-macos.zip](https://github.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-macos.zip)/[bouffalo_flash_cube-macos.tar.gz](https://github.com/flyingcys/bflb_tools/releases/download/v1.0.4/bouffalo_flash_cube-macos.tar.gz)
### 3.2. GUI方式下载
1. 连接好串口并在工具上选择对应的串口号
@ -128,9 +151,13 @@ Windows下推荐使用[env工具][1]在console下进入bsp/bouffalo_lab/bl61x
![Flash Download](figures/bouffalo_flash_cube.jpg)
### 3.2. 命令行下载
或者可使用`bsp/bouffalo_lab`目录下的`bouffalo_flash_cube.sh`脚本通过命令行下载,输入`./`bouffalo_flash_cube.sh bl616 /dev/ttyUSB1`使用前先确定脚本中bouffalo_flash_cube工具路径需手工修改为工具所在目录。
命令行下载可使用`bsp/bouffalo_lab`目录下的`bouffalo_flash_cube.sh`脚本,输入`./bouffalo_flash_cube.sh bl616 /dev/ttyUSB1`脚本会自动采用curl命令行方式下载`bouffalo_flash_cube`。
如自动下载失败,可采用手工方式下载对应操作系统文件后保存至`libraries/bl_mcu_sdk/tools/bflb_tools/bouffalo_flash_cube`目录。
其中:
@ -153,7 +180,7 @@ Windows下推荐使用[env工具][1]在console下进入bsp/bouffalo_lab/bl61x
| ----- | ---------------------- |
| bl602 | BL602-IoT-3S/BL-HWC-G1 |
| bl702 | Maix Zero Sense |
| bl616 | M0S Dock |
| bl616/bl618 | M0S Dock/M0P Dock |
| bl808 | M1s Dock |
@ -164,8 +191,14 @@ Windows下推荐使用[env工具][1]在console下进入bsp/bouffalo_lab/bl61x
| :--- | :------- | :---------------- |
| UART | 支持 | 默认波特率2000000 |
| GPIO | 支持 | |
| I2C | 开发中 | |
| SPI | 开发中 | |
| I2C | 支持 | |
| SPI | 支持 | 支持DMA |
| PWM | 支持 | |
| ADC | 支持 | |
| RTC | 支持 | |
| WDT | 支持 | |
| HWTIMER | 支持 | |
| FLASH | 支持 | |
@ -182,12 +215,3 @@ Windows下推荐使用[env工具][1]在console下进入bsp/bouffalo_lab/bl61x
[1]: https://www.rt-thread.org/download.html#download-rt-thread-env-tool
[2]: https://github.com/bouffalolab/bl_docs
## 9. FAQ
| | M1s Dock |
| ---- | :----------------------------------------------------------- |
| 1 | 在 windows 环境下,通过 UART 接口将开发板连接至电脑时,仅能识别到两个 USB converter 设备,但是识别不到对应的串口设备。 <br>进入到设备管理器中,右击对应的 USB converter 设备,进入到属性中的高级设置,钩选 vcp 选项,刷新后即可看到对应的串口设备。<br> 也可通过安装以下驱动解决问题: https://dl.sipeed.com/shareURL/MAIX/tools/ftdi_vcp_driver |
| 2 | 使用 TypeC 数据线将电脑与板子的 UART 口连接起来,此时电脑上会出现两个串口 (如果出现鼠标不能动的现象请拔掉 USB 并且查看 [更新板载 bl702 固件](https://wiki.sipeed.com/hardware/zh/maix/m1s/other/start.html#给板载-bl702-进行烧录) 相关内容来修复问题)。 |

View File

@ -0,0 +1,156 @@
# 博流智能 BL808板级支持包说明
## 1. 简介
BL808 是高度集成的 AIoT 芯片组,具有 Wi-Fi/BT/BLE/Zigbee 等无线互联单元,包含多个 CPU 以及音频编码译码器、视频编码译码器和 AI 硬件加速器,适用于各种高性能和低功耗应用领域。
BL808 系列芯片主要包含无线和多媒体两个子系统。
无线子系统包含一颗 RISC-V 32-bit 高性能 CPUm0集成 Wi-Fi/BT/Zigbee 无线子系统,可以实现多种无线连接和数据传输,提供多样化的连接与传输体验。
多媒体子系统包含一颗 RISC-V 64-bit 超高性能 CPUd0集成 DVP/CSI/ H264/NPU 等视频处理模块,可以广泛应用于视频监控/智能音箱等多种 AI 领域
多媒体子系统组成部分如下:
- NPU HW NN 协处理器 (BLAI-100),适用于人工智能应用领域
- 摄像头接口
- 音频编码译码器
- 视频编码解码器
- 传感器
- 显示接口
电源管理单元控制低功耗模式。此外,还支持各种安全功能。
外围接口包括 USB2.0、 Ethernet、 SD/MMC、 SPI、 UART、 I2C、 I2S、 PWM、 GPDAC/GPADC、 ACOMP、 PIR、 Touch、
IR remote、 Display 和 GPIO。
支持灵活的 GPIO 配置, BL808 最多可达 40 个 GPIO。
芯片规格包括如下:
| 硬件 | 描述 |
| -- | -- |
|芯片型号| bl808 |
|CPU| 三核异构RISC-V CPUs <br />RV64GCV 480MHz<br/>RV32GCP 320MHz<br/>RV32EMC 160MHz |
|RAM| 768KB SRAM + 64MB UHS PSRAM |
| 外设 | 内嵌AES与SHA256算法加速器 |
| AI NN 通用硬件加速器 | BLAI-100 用于视频/音频检测/识别100GOPS 算力 |
| 摄像头接口 | DVP 和 MIPI-CSI |
| 显示接口 | SPI、DBI、DPI(RGB) |
| 无线 | 支持 Wi-Fi 802.11 b/g/n<br/>支持 Bluetooth 5.x Dual-mode(BT+BLE)<br/>支持 Wi-Fi / 蓝牙 共存 |
## 2. RT-Thread 版本
BL808是三核异构架构分别为m0、lp、d0当前bsp已实现三核同时启动三核分别采用了不同的RT-Thread版本
| 名称 | CPU核 | RT-Thread版本 |
| ---- | ----- | ---------------- |
| M0 | E907 | RT-Thread 标准版 |
| LP | E902 | RT-Thread Nano |
| D0 | C906 | RT-SMART |
## 3. 编译说明
BL808是三核异构架构分别为m0、lp、d0三核需要单独编译并烧录到对应的位置。
烧录地址:
| 名称 | CPU核 | 烧录地址 | 说明 |
| ---- | ----- | -------- | ------------------------------------------------------------ |
| M0 | E907 | 0x00000 | |
| LP | E902 | 0xC0000 | 调整lp烧录地址需修改<br>`bsp/bouffalo_lab/bl808/lp/board/linker_scripts/bl808_flash_lp.ld`中的xip_memory地址<br>`bsp/bouffalo_lab/bl808/m0/board/board.h`中`CONFIG_LP_FLASH_ADDR`地址 |
| D0 | C906 | 0x100000 | 在spl文件中设定调整d0烧录地址需重新编译spl文件及打包文件`bsp/bouffalo_lab/bl808/d0/merge_rtsmart.py` |
### 3.1. m0/lp
- #### 工具链下载
下载risc-v的工具链[下载地址1](https://occ.t-head.cn/community/download?id=4073475960903634944)或[下载地址2](https://dl.sipeed.com/shareURL/others/toolchain)
Windows下请使用使用[env工具][1],使用命令 `tar -xvf Xuantie-900-gcc-elf-newlib-mingw-V2.6.1-20220906.tar.gz` 解压交叉编译器使用Windows下解压工具直接解压可能出现Windows下编译错误。
在`rtconfig.py`中将risc-v工具链的本地路径加入 `EXEC_PATH` 或通过 `RTT_EXEC_PATH` 环境变量指定路径
Windows
```
set RTT_EXEC_PATH=C:\Users\xxxx\Downloads\Xuantie-900-gcc-elf-newlib-x86_64-V2.6.1\bin
```
Linux:
```
export RTT_EXEC_PATH=/opt/Xuantie-900-gcc-elf-newlib-x86_64-V2.6.1/bin
```
- ### 编译
Windows下推荐使用[env工具][1]在console下进入bsp/bl808目录中选择需要编译的核心m0或lp运行
cd bsp/bl808/m0
menuconfig
pkgs --update
如果在Linux平台下可以先执行
scons --menuconfig
它会自动下载env相关脚本到~/.env目录然后执行
source ~/.env/env.sh
cd bsp/bl808/m0
pkgs --update
更新完软件包后,执行 `scons -j10``scons -j10 --verbose` 来编译这个板级支持包。或者通过 `scons --exec-path="GCC工具链路径"` 命令,在指定工具链位置的同时直接编译。
如果编译正确无误会产生rtthread.elf、rtthread_m0.bin文件。其中rtthread_m0.bin需要烧写到设备中进行运行。
- #### 注意
由于BL808为三核异构lp核、d0核都是通过m0核启动的必须正确烧录m0核才可以实现三核正常运行
m0烧录配置文件`bsp/bouffalo_lab/bl808/m0/flash_prog_cfg.ini`
### 3.2. d0
bl808-d0运行在S态下支持RT-Smart采用的交叉编译器为`riscv64-unknown-linux-musl-gcc`,编译请参考[构建内核镜像](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/quickstart?id=%e6%9e%84%e5%bb%ba%e5%86%85%e6%a0%b8%e9%95%9c%e5%83%8f)
其中内核虚拟地址开始地址为`0x50000000`
![kernel_start](./figures/kernel_start.png)
bl808-d0编译完成后通过`merge_rtsmart.py`脚本,将`hw.dtb.5M`,`spl_bl808_d0.bin``opensbi_v0.6.bin`与`rtthread_d0.bin`,合成最终烧录文件`whole_img_d0.bin`,烧录地址为`0x100000`,否则无法启动。
预编译bin文件位于`bsp/bouffalo_lab/bl808/d0/pre_build_bin`文件夹下,如有修改需求可下载[Low-Starup-BL808](https://github.com/flyingcys/Low-Starup-BL808)后自行修改。
d0单独烧录文件为`bsp/bouffalo_lab/bl808/d0/flash_prog_cfg.ini`
![d0](./figures/d0.png)
### 3.3. 三核同时编译与烧录
- 可运行`bsp/bouffalo_lab/bl808/build_bl808_all.sh`依次编译m0、lp、d0核
- 可通过`bsp/bouffalo_lab/bl808/flash_prog_cfg.ini`烧录配置文件同时烧录m0、lp、d0核。
![bl808](./figures/bl808.png)
## 4. FAQ
- 在 windows 环境下,通过 UART 接口将开发板连接至电脑时,仅能识别到两个 USB converter 设备,但是识别不到对应的串口设备。
- 进入到设备管理器中,右击对应的 USB converter 设备,进入到属性中的高级设置,钩选 vcp 选项,刷新后即可看到对应的串口设备。
- 也可通过安装以下驱动解决问题: https://dl.sipeed.com/shareURL/MAIX/tools/ftdi_vcp_driver
- 使用 TypeC 数据线将电脑与板子的 UART 口连接起来,此时电脑上会出现两个串口 (如果出现鼠标不能动的现象请拔掉 USB 并且查看 [更新板载 bl702 固件](https://wiki.sipeed.com/hardware/zh/maix/m1s/other/start.html#给板载-bl702-进行烧录) 相关内容来修复问题)。

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -7,26 +7,20 @@
* Date Author Notes
* 2023-04-08 wcx1024979076 first version
*/
/*
* dfs 使
* mnt_init
* elm flash filesystem
* 使 https://blog.csdn.net/h451884098/article/details/118544347 和 https://blog.csdn.net/u013213069/article/details/117384971 开启以下配置:
* 1 menuconfig RT_USING_DFS elm-chan sector 4096
* 2 components/dfs/dfs_v1/include/dfs.h components/dfs/dfs_v2/include/dfs.h SECTOR_SIZE 4096
* 3 BSP_USING_ON_CHIP_FLASH
* 4 menuconfig RT_USING_FAL
*/
#include <rtthread.h>
#include <rtdevice.h>
#ifdef RT_USING_DFS
#ifdef RT_USING_FAL
#ifdef BSP_USING_ON_CHIP_FLASH
#define DBG_TAG "mnt"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#include "dfs_file.h"
#ifdef RT_USING_DFS
#include <dfs_fs.h>
#ifdef RT_USING_FAL
#include "fal.h"
#ifdef BSP_USING_ON_CHIP_FLASH
int mnt_init(void)
{
struct rt_device *rootfs = RT_NULL;
@ -34,33 +28,38 @@ int mnt_init(void)
/* 使用 filesystem 分区创建块设备,块设备名称为 filesystem */
rootfs = fal_blk_device_create("filesystem");
if(rootfs == RT_NULL)
{
LOG_E("Failed to create device.\n");
return -RT_ERROR;
}
/* 将 elm fat 文件系统挂载 filesystem 分区 */
if (dfs_mount("filesystem", "/", "elm", 0, 0) == 0)
{
rt_kprintf("file system initialization done!\n");
LOG_D("file system initialization done!\n");
}
else
{
LOG_I("file system initialization failed!\n");
if(dfs_mkfs("elm", "filesystem") == 0)
{
if (dfs_mount("filesystem", "/", "elm", 0, 0) == 0)
{
rt_kprintf("file system initialization done!\n");
LOG_D("file system initialization done!\n");
}
else
{
rt_kprintf("file system initialization failed!\n");
LOG_D("file system initialization failed!\n");
}
}
}
return RT_EOK;
}
INIT_ENV_EXPORT(mnt_init);
INIT_APP_EXPORT(mnt_init);
#endif /* BSP_USING_ON_CHIP_FLASH */
#endif /* RT_USING_FAL */
#endif /* RT_USING_DFS */
#endif /* RT_USING_FAL */
#endif /* BSP_USING_ON_CHIP_FLASH */

View File

@ -8,5 +8,5 @@ boot2_isp_mode = 0
[FW]
filedir = ./rtthread_m0.bin
# since D0 is boot by M0this address should consistent with m0's board_init in board.c
address = 0x000000
address = 0x000000

View File

@ -1,17 +1,6 @@
menu "General Drivers Configuration"
config BSP_USING_GPIO
bool "Enable GPIO"
select RT_USING_PIN
default y
config BSP_USING_ADC
bool "Enable ADC"
select RT_USING_ADC
default n
menu "General Purpose UARTs"
menuconfig BSP_USING_UART0
bool "Enable UART0"
default y
@ -126,7 +115,17 @@ menu "General Drivers Configuration"
endmenu
menuconfig BSP_USING_RTC
config BSP_USING_GPIO
bool "Enable GPIO"
select RT_USING_PIN
default n
config BSP_USING_ADC
bool "Enable ADC"
select RT_USING_ADC
default n
config BSP_USING_RTC
bool "Enable RTC"
select RT_USING_RTC
default n
@ -171,11 +170,7 @@ menu "General Drivers Configuration"
default n
endif
config BSP_USING_ON_CHIP_FLASH
bool "Enable on-chip FLASH"
default n
menu "General Purpose I2C"
menuconfig BSP_USING_I2C1
bool "Enable I2C1"
default n
@ -225,5 +220,314 @@ menu "General Drivers Configuration"
endif
endmenu
menuconfig BSP_USING_SPI
bool "Enable SPI"
select RT_USING_SPI
default n
if BSP_USING_SPI
choice
prompt "SPI SCK PIN"
default SPI_SCK_USING_GPIO3 if BSP_USING_BL60X
default SPI_SCK_USING_GPIO13 if BSP_USING_BL61X
default SPI_SCK_USING_GPIO15 if BSP_USING_BL70X
default SPI_SCK_USING_GPIO19 if BSP_USING_BL808
config SPI_SCK_USING_GPIO1
depends on BSP_USING_BL61X
bool "GPIO_1"
config SPI_SCK_USING_GPIO3
depends on BSP_USING_BL60X || BSP_USING_BL70X || BSP_USING_BL808
bool "GPIO_3"
config SPI_SCK_USING_GPIO5
depends on BSP_USING_BL61X
bool "GPIO_5"
config SPI_SCK_USING_GPIO7
depends on BSP_USING_BL60X || BSP_USING_BL70X || BSP_USING_BL808
bool "GPIO_7"
config SPI_SCK_USING_GPIO9
depends on BSP_USING_BL61X
bool "GPIO_9"
config SPI_SCK_USING_GPIO11
depends on BSP_USING_BL60X || BSP_USING_BL70X || BSP_USING_BL808
bool "GPIO_11"
config SPI_SCK_USING_GPIO13
depends on BSP_USING_BL61X
bool "GPIO_13"
config SPI_SCK_USING_GPIO15
depends on BSP_USING_BL60X || BSP_USING_BL70X || BSP_USING_BL808
bool "GPIO_15"
config SPI_SCK_USING_GPIO17
depends on BSP_USING_BL61X
bool "GPIO_17"
config SPI_SCK_USING_GPIO19
depends on BSP_USING_BL60X || BSP_USING_BL70X || BSP_USING_BL808
bool "GPIO_19"
config SPI_SCK_USING_GPIO21
depends on BSP_USING_BL61X
bool "GPIO_21"
config SPI_SCK_USING_GPIO23
depends on BSP_USING_BL70X || BSP_USING_BL808
bool "GPIO_23"
config SPI_SCK_USING_GPIO25
depends on BSP_USING_BL61X
bool "GPIO_25"
config SPI_SCK_USING_GPIO27
depends on BSP_USING_BL70X || BSP_USING_BL808
bool "GPIO_27"
config SPI_SCK_USING_GPIO29
depends on BSP_USING_BL61X
bool "GPIO_29"
config SPI_SCK_USING_GPIO31
depends on BSP_USING_BL808
bool "GPIO_31"
config SPI_SCK_USING_GPIO33
depends on BSP_USING_BL61X
bool "GPIO_33"
config SPI_SCK_USING_GPIO35
depends on BSP_USING_BL808
bool "GPIO_35"
config SPI_SCK_USING_GPIO39
depends on BSP_USING_BL808
bool "GPIO_39"
config SPI_SCK_USING_GPIO43
depends on BSP_USING_BL808
bool "GPIO_43"
endchoice
choice
prompt "SPI MISO PIN"
default SPI_MISO_USING_GPIO0 if BSP_USING_BL60X
default SPI_MISO_USING_GPIO10 if BSP_USING_BL61X
default SPI_MISO_USING_GPIO17 if BSP_USING_BL70X
default SPI_MISO_USING_GPIO22 if BSP_USING_BL808
config SPI_MISO_USING_GPIO0
depends on BSP_USING_BL60X
bool "GPIO_0"
config SPI_MISO_USING_GPIO1
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_1"
config SPI_MISO_USING_GPIO2
depends on BSP_USING_BL61X || BSP_USING_BL808
bool "GPIO_2"
config SPI_MISO_USING_GPIO4
depends on BSP_USING_BL60X
bool "GPIO_4"
config SPI_MISO_USING_GPIO5
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_5"
config SPI_MISO_USING_GPIO6
depends on BSP_USING_BL61X || BSP_USING_BL808
bool "GPIO_6"
config SPI_MISO_USING_GPIO8
depends on BSP_USING_BL60X
bool "GPIO_8"
config SPI_MISO_USING_GPIO9
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_9"
config SPI_MISO_USING_GPIO10
depends on BSP_USING_BL61X || BSP_USING_BL808
bool "GPIO_10"
config SPI_MISO_USING_GPIO12
depends on BSP_USING_BL60X
bool "GPIO_12"
config SPI_MISO_USING_GPIO13
depends on BSP_USING_BL60X || BSP_USING_BL60X
bool "GPIO_13"
config SPI_MISO_USING_GPIO14
depends on BSP_USING_BL61X || BSP_USING_BL808
bool "GPIO_14"
config SPI_MISO_USING_GPIO16
depends on BSP_USING_BL60X
bool "GPIO_16"
config SPI_MISO_USING_GPIO17
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_17"
config SPI_MISO_USING_GPIO18
depends on BSP_USING_BL61X || BSP_USING_BL808
bool "GPIO_18"
config SPI_MISO_USING_GPIO20
depends on BSP_USING_BL60X
bool "GPIO_20"
config SPI_MISO_USING_GPIO21
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_21"
config SPI_MISO_USING_GPIO22
depends on BSP_USING_BL61X || BSP_USING_BL808
bool "GPIO_22"
config SPI_MISO_USING_GPIO25
depends on BSP_USING_BL70X
bool "GPIO_25"
config SPI_MISO_USING_GPIO26
depends on BSP_USING_BL61X || BSP_USING_BL808
bool "GPIO_26"
config SPI_MISO_USING_GPIO29
depends on BSP_USING_BL70X
bool "GPIO_29"
config SPI_MISO_USING_GPIO30
depends on BSP_USING_BL61X || BSP_USING_BL808
bool "GPIO_30"
config SPI_MISO_USING_GPIO34
depends on BSP_USING_BL808
bool "GPIO_34"
config SPI_MISO_USING_GPIO38
depends on BSP_USING_BL808
bool "GPIO_38"
config SPI_MISO_USING_GPIO42
depends on BSP_USING_BL808
bool "GPIO_42"
endchoice
choice
prompt "SPI MOSI PIN"
default SPI_MOSI_USING_GPIO1 if BSP_USING_BL60X
default SPI_MOSI_USING_GPIO11 if BSP_USING_BL61X
default SPI_MOSI_USING_GPIO16 if BSP_USING_BL70X
default SPI_MOSI_USING_GPIO21 if BSP_USING_BL808
config SPI_MOSI_USING_GPIO0
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_0"
config SPI_MOSI_USING_GPIO1
depends on BSP_USING_BL60X || BSP_USING_BL808
bool "GPIO_1"
config SPI_MOSI_USING_GPIO3
depends on BSP_USING_BL61X
bool "GPIO_3"
config SPI_MOSI_USING_GPIO4
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_4"
config SPI_MOSI_USING_GPIO5
depends on BSP_USING_BL60X || BSP_USING_BL808
bool "GPIO_5"
config SPI_MOSI_USING_GPIO7
depends on BSP_USING_BL61X
bool "GPIO_7"
config SPI_MOSI_USING_GPIO8
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_8"
config SPI_MOSI_USING_GPIO9
depends on BSP_USING_BL60X || BSP_USING_BL808
bool "GPIO_9"
config SPI_MOSI_USING_GPIO11
depends on BSP_USING_BL61X
bool "GPIO_11"
config SPI_MOSI_USING_GPIO12
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_12"
config SPI_MOSI_USING_GPIO13
depends on BSP_USING_BL60X || BSP_USING_BL808
bool "GPIO_13"
config SPI_MOSI_USING_GPIO15
depends on BSP_USING_BL61X
bool "GPIO_15"
config SPI_MOSI_USING_GPIO16
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_16"
config SPI_MOSI_USING_GPIO17
depends on BSP_USING_BL60X || BSP_USING_BL808
bool "GPIO_17"
config SPI_MOSI_USING_GPIO19
depends on BSP_USING_BL61X
bool "GPIO_19"
config SPI_MOSI_USING_GPIO20
depends on BSP_USING_BL60X || BSP_USING_BL70X
bool "GPIO_20"
config SPI_MOSI_USING_GPIO21
depends on BSP_USING_BL60X || BSP_USING_BL808
bool "GPIO_21"
config SPI_MOSI_USING_GPIO23
depends on BSP_USING_BL61X
bool "GPIO_23"
config SPI_MOSI_USING_GPIO24
depends on BSP_USING_BL70X
bool "GPIO_24"
config SPI_MOSI_USING_GPIO25
depends on BSP_USING_BL808
bool "GPIO_25"
config SPI_MOSI_USING_GPIO27
depends on BSP_USING_BL61X
bool "GPIO_27"
config SPI_MOSI_USING_GPIO28
depends on BSP_USING_BL70X
bool "GPIO_28"
config SPI_MOSI_USING_GPIO29
depends on BSP_USING_BL808
bool "GPIO_29"
config SPI_MOSI_USING_GPIO31
depends on BSP_USING_BL61X
bool "GPIO_31"
config SPI_MOSI_USING_GPIO33
depends on BSP_USING_BL808
bool "GPIO_33"
config SPI_MOSI_USING_GPIO37
depends on BSP_USING_BL808
bool "GPIO_37"
config SPI_MOSI_USING_GPIO41
depends on BSP_USING_BL808
bool "GPIO_41"
config SPI_MOSI_USING_GPIO45
depends on BSP_USING_BL808
bool "GPIO_45"
endchoice
config BSP_SPI_TX_USING_DMA
bool "Enable SPI TX DMA"
default n
if BSP_SPI_TX_USING_DMA
config BSP_SPI_TX_DMA_CHANNEL
string "SPI TX DMA Channel Name"
default "dma0_ch0"
config BSP_SPI_TX_DMA_TIMEOUT
int "SPI TX DMA Timeout(ms)"
default 10
range 5 100
config BSP_SPI_TX_DMA_NOCACHE_BUFSIZE
depends on BSP_USING_BL61X || BSP_USING_BL808
int "SPI TX DMA Nocache Buffer Size"
default 512
range 0 4095
endif
config BSP_SPI_RX_USING_DMA
bool "Enable SPI RX DMA"
default n
if BSP_SPI_RX_USING_DMA
config BSP_SPI_RX_DMA_CHANNEL
string "SPI RX DMA Channel Name"
default "dma0_ch1"
config BSP_SPI_RX_DMA_TIMEOUT
int "SPI RX DMA Timeout(ms)"
default 10
range 5 100
config BSP_SPI_RX_DMA_NOCACHE_BUFSIZE
depends on BSP_USING_BL61X || BSP_USING_BL808
int "SPI RX DMA Nocache Buffer Size"
default 512
range 0 4095
endif
endif
config BSP_USING_ON_CHIP_FLASH
bool "Enable On-Chip FLASH"
default n
menuconfig BSP_USING_FS
bool "Enable File System"
select RT_USING_DFS
select RT_USING_DFS_ELMFAT
select RT_USING_FAL
select FAL_DEBUG_CONFIG
select FAL_PART_HAS_TABLE_CFG
default n
if BSP_USING_FS
config BSP_USING_ON_CHIP_FLASH_FATFS
bool "Enable On-Chip Flash File System"
select BSP_USING_ON_CHIP_FLASH
default n
endif
endmenu

View File

@ -9,7 +9,7 @@ CPPPATH = [cwd]
if GetDepend('BSP_USING_GPIO'):
src += ['drv_gpio.c']
if GetDepend('RT_USING_I2C'):
if GetDepend('BSP_USING_I2C'):
src += ['drv_soft_i2c.c']
if GetDepend('BSP_USING_ADC'):
@ -18,14 +18,21 @@ if GetDepend('BSP_USING_ADC'):
if GetDepend('BSP_USING_RTC'):
src += ['drv_rtc.c']
if GetDepend('RT_USING_PWM'):
if GetDepend('BSP_USING_PWM'):
src += ['drv_pwm.c']
src += ['src/pwm_led_sample.c']
if GetDepend('RT_USING_WDT'):
if GetDepend('BSP_USING_WDT'):
src += ['drv_wdt.c']
src += ['sample/wdt_sample.c']
if GetDepend('BSP_USING_HWTIMER'):
src += ['drv_hwtimer.c']
src += ['sample/hwtimer_sample.c']
if GetDepend('BSP_USING_SPI'):
src += ['drv_spi.c']
src += ['sample/spi_sample.c']
if GetDepend('BSP_USING_ON_CHIP_FLASH'):
src += ['drv_flash.c']

View File

@ -8,24 +8,20 @@
* 2023-04-08 wcx1024979076 first version
*/
#include "drv_flash.h"
#include <rtthread.h>
#include <rtdevice.h>
#ifdef BSP_USING_ON_CHIP_FLASH
#include "drv_flash.h"
#ifdef RT_USING_FAL
#include "fal.h"
#endif /* RT_USING_FAL */
#define DBG_LEVEL DBG_LOG
#define LOG_TAG "DRV.FLASH"
#include <rtdbg.h>
#define BFLB_FLASH_START_ADRESS 0x58000000
#define BFLB_FLASH_START_ADRESS 0x0000000
#define BFLB_FLASH_END_ADDRESS 0x1000000
#define BFLB_FLASH_SIZE 16 * 1024 * 1024
#define BFLB_FLASH_PAGE_SIZE 4 * 1024
#define BFLB_FLASH_END_ADDRESS 0x59000000
int _flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
{
@ -107,6 +103,8 @@ int _flash_erase(rt_uint32_t addr, size_t size)
#ifdef RT_USING_FAL
#include "fal.h"
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size);
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size);
static int fal_flash_erase(long offset, size_t size);
@ -140,6 +138,12 @@ static int fal_flash_erase(long offset, size_t size)
return _flash_erase(_onchip_flash.addr + offset, size);
}
INIT_DEVICE_EXPORT(fal_init);
static int rt_hw_on_chip_flash_init(void)
{
fal_init();
return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_on_chip_flash_init);
#endif /* RT_USING_FAL */
#endif /* BSP_USING_ON_CHIP_FLASH */

View File

@ -12,11 +12,12 @@
#include "drv_gpio.h"
#include <stdbool.h>
#ifdef BSP_USING_PIN
#define DBG_TAG "drv.gpio"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef RT_USING_PIN
static struct bflb_device_s *gpio;
static struct rt_pin_irq_hdr pin_irq_hdr_tab[GPIO_MAX];
@ -226,4 +227,4 @@ int rt_hw_pin_init(void)
}
INIT_BOARD_EXPORT(rt_hw_pin_init);
#endif /*RT_USING_PIN */
#endif /*BSP_USING_PIN */

View File

@ -8,16 +8,16 @@
* 2023-04-01 wcx1024979076 first version
*/
#include "drv_hwtimer.h"
#include <rtthread.h>
#include <rtdevice.h>
#ifdef BSP_USING_HWTIMER
#define DBG_LEVEL DBG_LOG
#include <rtdbg.h>
#define LOG_TAG "DRV.HWTIMER"
#ifdef RT_USING_HWTIMER
#include "drv_hwtimer.h"
typedef struct _gptimer
{
@ -196,4 +196,4 @@ int rt_hw_hwtimer_init(void)
}
INIT_DEVICE_EXPORT(rt_hw_hwtimer_init);
#endif /* RT_USING_HWTIMER */
#endif /* BSP_USING_HWTIMER */

View File

@ -12,12 +12,12 @@
#include <rtdevice.h>
#include "drv_pwm.h"
#ifdef BSP_USING_PWM
#define DBG_LEVEL DBG_LOG
#include <rtdbg.h>
#define LOG_TAG "DRV.PWM"
#ifdef BSP_USING_PWM
static rt_err_t _pwm_set(rt_uint8_t channel, struct rt_pwm_configuration *configuration)
{
struct bflb_device_s* pwm = bflb_device_get_by_name("pwm_v2_0");

View File

@ -12,12 +12,12 @@
#include "board.h"
#include "drv_rtc.h"
#ifdef BSP_USING_RTC
#define DBG_TAG "DRV.RTC"
#define DBG_LVL DBG_WARNING
#include <rtdbg.h>
#ifdef RT_USING_RTC
static struct rt_device rtc;
static rt_uint32_t rtc_time;
@ -87,4 +87,4 @@ int rt_hw_rtc_init(void)
}
INIT_DEVICE_EXPORT(rt_hw_rtc_init);
#endif /* RT_USING_RTC */
#endif /* BSP_USING_RTC */

View File

@ -12,7 +12,8 @@
#include "bflb_gpio.h"
#include "bflb_common.h"
#ifdef RT_USING_I2C
#ifdef BSP_USING_I2C
#define DBG_LEVEL DBG_LOG
#include <rtdbg.h>
#define LOG_TAG "DRV.I2C"
@ -208,4 +209,4 @@ int rt_hw_i2c_init(void)
}
INIT_BOARD_EXPORT(rt_hw_i2c_init);
#endif /* RT_USING_I2C */
#endif /* BSP_USING_I2C */

View File

@ -0,0 +1,568 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-05-01 flyingcys first version
*/
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include "board.h"
#include "drv_spi.h"
#ifdef BSP_USING_SPI
#define DBG_LEVEL DBG_LOG
#include <rtdbg.h>
#define LOG_TAG "drv.spi"
#define DMA_MAX_BUFSIZE 4095
#if defined(BSP_USING_BL808)
#define NOCACHE_BUFSTART 0x22026000
#define NOCACHE_BUFSIZE (40 * 1024)
#elif defined (BSP_USING_BL61X)
#define NOCACHE_BUFSTART 0x22FC6000
#define NOCACHE_BUFSIZE (104 * 1024)
#endif
struct bl_device_spi
{
struct rt_spi_bus spi_bus;
struct bflb_device_s *spi;
#if defined(BSP_SPI_TX_USING_DMA)
struct bflb_device_s *dma_tx;
rt_uint32_t dma_dst_req;
rt_sem_t sem_tx;
#endif
#if defined(BSP_SPI_RX_USING_DMA)
struct bflb_device_s *dma_rx;
rt_uint32_t dma_src_req;
rt_sem_t sem_rx;
#endif
};
#if defined(BSP_SPI_TX_USING_DMA) && defined(BSP_SPI_TX_DMA_NOCACHE_BUFSIZE)
static ATTR_NOCACHE_NOINIT_RAM_SECTION rt_uint8_t dma_tx_buf[BSP_SPI_TX_DMA_NOCACHE_BUFSIZE];
#endif
#if defined(BSP_SPI_RX_USING_DMA) && defined(BSP_SPI_RX_DMA_NOCACHE_BUFSIZE)
static ATTR_NOCACHE_NOINIT_RAM_SECTION rt_uint8_t dma_rx_buf[BSP_SPI_RX_DMA_NOCACHE_BUFSIZE];
#endif
#if defined(BSP_SPI_TX_USING_DMA)
static void spi_bl_spi_dma_tx_isr(void *arg)
{
struct bl_device_spi *bl_spi = (struct bl_device_spi *)arg;
LOG_D("spi dma tx done ");
rt_sem_release(bl_spi->sem_tx);
}
#endif
#if defined(BSP_SPI_RX_USING_DMA)
void spi_dma_rx_isr(void *arg)
{
struct bl_device_spi *bl_spi = (struct bl_device_spi *)arg;
LOG_D("spi dma rx done");
rt_sem_release(bl_spi->sem_rx);
}
#endif
static rt_err_t spi_configure(struct rt_spi_device *device,
struct rt_spi_configuration *cfg)
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
struct bflb_spi_config_s spi_cfg = {
.freq = 1 * 1000 * 1000,
.role = SPI_ROLE_MASTER,
.mode = SPI_MODE3,
.data_width = SPI_DATA_WIDTH_8BIT,
.bit_order = SPI_BIT_MSB,
.byte_order = SPI_BYTE_LSB,
.tx_fifo_threshold = 0,
.rx_fifo_threshold = 0,
};
switch (cfg->mode & RT_SPI_MODE_3)
{
case RT_SPI_MODE_0: /* RT_SPI_CPOL:0 , RT_SPI_CPHA:0 */
spi_cfg.mode = SPI_MODE0;
break;
case RT_SPI_MODE_1: /* RT_SPI_CPOL:0 , RT_SPI_CPHA:1 */
spi_cfg.mode = SPI_MODE1;
break;
case RT_SPI_MODE_2: /* RT_SPI_CPOL:1 , RT_SPI_CPHA:0 */
spi_cfg.mode = SPI_MODE2;
break;
case RT_SPI_MODE_3: /* RT_SPI_CPOL:1 , RT_SPI_CPHA:1 */
spi_cfg.mode = SPI_MODE3;
break;
default:
LOG_E("spi_configure mode error %x\n", cfg->mode);
return -RT_EINVAL;
}
switch (cfg->data_width)
{
case 8:
spi_cfg.data_width = SPI_DATA_WIDTH_8BIT;
break;
case 16:
spi_cfg.data_width = SPI_DATA_WIDTH_16BIT;
break;
case 24:
spi_cfg.data_width = SPI_DATA_WIDTH_24BIT;
break;
case 32:
spi_cfg.data_width = SPI_DATA_WIDTH_32BIT;
break;
default:
LOG_E("spi_configure data_width error %x\n", cfg->data_width);
return RT_ERROR;
}
spi_cfg.freq = cfg->max_hz;
if (cfg->mode & RT_SPI_MSB)
spi_cfg.bit_order = SPI_BIT_MSB;
else
spi_cfg.bit_order = SPI_BIT_LSB;
if (cfg->mode & RT_SPI_SLAVE)
spi_cfg.role = SPI_ROLE_SLAVE;
else
spi_cfg.role = SPI_ROLE_MASTER;
struct bl_device_spi *bl_spi;
bl_spi = (struct bl_device_spi *)device->bus->parent.user_data;
bflb_spi_init(bl_spi->spi, &spi_cfg);
#if defined(BSP_SPI_TX_USING_DMA)
bl_spi->sem_tx = rt_sem_create("dam_tx", 0, RT_IPC_FLAG_PRIO);
if (bl_spi->sem_tx == RT_NULL)
{
LOG_E("rt_sem_create dma_tx error");
return -RT_ENOMEM;
}
rt_uint8_t tx_data_width = DMA_DATA_WIDTH_8BIT;
if (spi_cfg.data_width == SPI_DATA_WIDTH_8BIT)
tx_data_width = DMA_DATA_WIDTH_8BIT;
else if (spi_cfg.data_width == SPI_DATA_WIDTH_16BIT)
tx_data_width = DMA_DATA_WIDTH_16BIT;
else if (spi_cfg.data_width == SPI_DATA_WIDTH_32BIT)
tx_data_width = DMA_DATA_WIDTH_32BIT;
else
{
LOG_E("spi dma not support 24bit...");
return -RT_EINVAL;
}
struct bflb_dma_channel_config_s tx_config = {
.direction = DMA_MEMORY_TO_PERIPH,
.src_req = DMA_REQUEST_NONE,
.dst_req = bl_spi->dma_dst_req,
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
.src_burst_count = DMA_BURST_INCR1,
.dst_burst_count = DMA_BURST_INCR1,
.src_width = tx_data_width,
.dst_width = tx_data_width,
};
bflb_spi_link_txdma(bl_spi->spi, true);
bflb_dma_channel_init(bl_spi->dma_tx, &tx_config);
bflb_dma_channel_irq_attach(bl_spi->dma_tx, spi_bl_spi_dma_tx_isr, (void *)bl_spi);
#endif
#if defined(BSP_SPI_RX_USING_DMA)
bl_spi->sem_rx = rt_sem_create("dam_rx", 0, RT_IPC_FLAG_PRIO);
if (bl_spi->sem_rx == RT_NULL)
{
LOG_E("rt_sem_create dma_rx error");
return -RT_ENOMEM;
}
rt_uint8_t rx_data_width = DMA_DATA_WIDTH_8BIT;
if (spi_cfg.data_width == SPI_DATA_WIDTH_8BIT)
rx_data_width = DMA_DATA_WIDTH_8BIT;
else if (spi_cfg.data_width == SPI_DATA_WIDTH_16BIT)
rx_data_width = DMA_DATA_WIDTH_16BIT;
else if (spi_cfg.data_width == SPI_DATA_WIDTH_32BIT)
rx_data_width = DMA_DATA_WIDTH_32BIT;
else
{
LOG_E("spi dma not support 24bit...");
return -RT_EINVAL;
}
struct bflb_dma_channel_config_s rx_config = {
.direction = DMA_PERIPH_TO_MEMORY,
.src_req = bl_spi->dma_src_req,
.dst_req = DMA_REQUEST_NONE,
.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
.src_burst_count = DMA_BURST_INCR1,
.dst_burst_count = DMA_BURST_INCR1,
.src_width = rx_data_width,
.dst_width = rx_data_width,
};
bflb_spi_link_rxdma(bl_spi->spi, true);
bflb_dma_channel_init(bl_spi->dma_rx, &rx_config);
bflb_dma_channel_irq_attach(bl_spi->dma_rx, spi_dma_rx_isr, (void *)bl_spi);
#endif
return RT_EOK;
}
#if defined(BSP_SPI_TX_USING_DMA)
static rt_err_t _bl_spi_dma_tx(struct bl_device_spi *bl_spi, rt_uint8_t *src, rt_size_t length)
{
rt_err_t result;
struct bflb_dma_channel_lli_pool_s tx_llipool[1];
struct bflb_dma_channel_lli_transfer_s tx_transfers[1];
tx_transfers[0].src_addr = (rt_uint32_t)src;
tx_transfers[0].dst_addr = (rt_uint32_t)DMA_ADDR_SPI0_TDR;
tx_transfers[0].nbytes = length;
LOG_D("dma tx start...");
rt_kprintf("tx length:%d\n", length);
bflb_dma_channel_lli_reload(bl_spi->dma_tx, tx_llipool, 1, tx_transfers, 1);
bflb_dma_channel_start(bl_spi->dma_tx);
result = rt_sem_take(bl_spi->sem_tx, BSP_SPI_TX_DMA_TIMEOUT);
if (result != RT_EOK)
LOG_E("sem take dma tx error:%d", result);
return result;
}
static rt_err_t _spi_dma_xfer_tx(struct rt_spi_device *device, struct rt_spi_message *message)
{
rt_err_t result = RT_EOK;
rt_uint8_t *src = (rt_uint8_t *)message->send_buf;
rt_size_t length = message->length;
struct bl_device_spi *bl_spi = (struct bl_device_spi *)device->bus->parent.user_data;
#if defined(NOCACHE_BUFSTART) && defined(NOCACHE_BUFSIZE)
if ((message->send_buf < NOCACHE_BUFSTART) || (message->send_buf > (NOCACHE_BUFSTART + NOCACHE_BUFSIZE)))
{
if (length <= BSP_SPI_TX_DMA_NOCACHE_BUFSIZE)
{
memcpy(dma_tx_buf, src, length);
result = _bl_spi_dma_tx(bl_spi, dma_tx_buf, length);
}
else
{
while(length > 0)
{
if (length >= BSP_SPI_TX_DMA_NOCACHE_BUFSIZE)
{
memcpy(dma_tx_buf, src, BSP_SPI_TX_DMA_NOCACHE_BUFSIZE);
result = _bl_spi_dma_tx(bl_spi, dma_tx_buf, BSP_SPI_TX_DMA_NOCACHE_BUFSIZE);
if (result != RT_EOK)
break;
length -= BSP_SPI_TX_DMA_NOCACHE_BUFSIZE;
src += BSP_SPI_TX_DMA_NOCACHE_BUFSIZE;
}
else
{
memcpy(dma_tx_buf, src, length);
result = _bl_spi_dma_tx(bl_spi, dma_tx_buf, length);
length = 0;
}
}
}
}
else
#endif
{
if (length <= DMA_MAX_BUFSIZE)
{
result = _bl_spi_dma_tx(bl_spi, src, length);
}
else
{
while(length > 0)
{
if (length >= DMA_MAX_BUFSIZE)
{
result = _bl_spi_dma_tx(bl_spi, src, DMA_MAX_BUFSIZE);
if (result != RT_EOK)
break;
length -= DMA_MAX_BUFSIZE;
src += DMA_MAX_BUFSIZE;
}
else
{
result = _bl_spi_dma_tx(bl_spi, src, length);
length = 0;
}
}
}
}
LOG_D("dma tx finish...");
return result;
}
#endif
#if defined(BSP_SPI_RX_USING_DMA)
static rt_err_t _bl_spi_dma_rx(struct bl_device_spi *bl_spi, rt_uint8_t *dst, rt_size_t length)
{
rt_err_t result;
struct bflb_dma_channel_lli_pool_s rx_llipool[1];
struct bflb_dma_channel_lli_transfer_s rx_transfers[1];
rx_transfers[0].src_addr = (rt_uint32_t)DMA_ADDR_SPI0_RDR;
rx_transfers[0].dst_addr = (rt_uint32_t)dst;
rx_transfers[0].nbytes = length;
bflb_dma_channel_lli_reload(bl_spi->dma_rx, rx_llipool, 1, rx_transfers, 1);
bflb_dma_channel_start(bl_spi->dma_rx);
result = rt_sem_take(bl_spi->sem_rx, BSP_SPI_RX_DMA_TIMEOUT);
if (result != RT_EOK)
LOG_E("sem take dma rx error:%d", result);
return result;
}
static rt_err_t _spi_dma_xfer_rx(struct rt_spi_device *device, struct rt_spi_message *message)
{
rt_err_t result = RT_EOK;
rt_uint8_t *dst = (rt_uint8_t *)message->recv_buf;
rt_size_t length = message->length;
struct bl_device_spi *bl_spi = (struct bl_device_spi *)device->bus->parent.user_data;
#if defined(NOCACHE_BUFSTART) && defined(NOCACHE_BUFSIZE)
if ((message->recv_buf < NOCACHE_BUFSTART) || (message->recv_buf > (NOCACHE_BUFSTART + NOCACHE_BUFSIZE)))
{
if (length <= BSP_SPI_RX_DMA_NOCACHE_BUFSIZE)
{
result = _bl_spi_dma_rx(bl_spi, dst, length);
if (result == RT_EOK)
memcpy(dst, dma_rx_buf, length);
}
else
{
while(length > 0)
{
if (length >= BSP_SPI_RX_DMA_NOCACHE_BUFSIZE)
{
result = _bl_spi_dma_rx(bl_spi, dma_tx_buf, BSP_SPI_RX_DMA_NOCACHE_BUFSIZE);
if (result != RT_EOK)
break;
memcpy(dst, dma_rx_buf, BSP_SPI_RX_DMA_NOCACHE_BUFSIZE);
length -= BSP_SPI_RX_DMA_NOCACHE_BUFSIZE;
dst += BSP_SPI_RX_DMA_NOCACHE_BUFSIZE;
}
else
{
result = _bl_spi_dma_rx(bl_spi, dma_rx_buf, length);
if (result != RT_EOK)
break;
memcpy(dst, dma_rx_buf, length);
length = 0;
}
}
}
}
else
#endif
{
if (length <= DMA_MAX_BUFSIZE)
{
result = _bl_spi_dma_rx(bl_spi, dst, length);
if (result == RT_EOK)
memcpy(dst, dma_rx_buf, length);
}
else
{
while(length > 0)
{
if (length >= DMA_MAX_BUFSIZE)
{
result = _bl_spi_dma_rx(bl_spi, dst, DMA_MAX_BUFSIZE);
if (result != RT_EOK)
break;
memcpy(dst, dma_rx_buf, DMA_MAX_BUFSIZE);
length -= DMA_MAX_BUFSIZE;
dst += DMA_MAX_BUFSIZE;
}
else
{
result = _bl_spi_dma_rx(bl_spi, dst, length);
if (result != RT_EOK)
break;
memcpy(dst, dma_rx_buf, length);
length = 0;
}
}
}
}
LOG_D("dma rx finish...");
return result;
}
#endif
static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
rt_err_t result;
rt_uint32_t cs_pin = (rt_uint32_t)device->parent.user_data;
struct bflb_device_s* gpio = bflb_device_get_by_name("gpio");
struct bl_device_spi *bl_spi;
bl_spi = (struct bl_device_spi *)device->bus->parent.user_data;
if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS))
{
if (device->config.mode & RT_SPI_CS_HIGH)
bflb_gpio_set(gpio, cs_pin);
else
bflb_gpio_reset(gpio, cs_pin);
}
if (message->send_buf && message->recv_buf)
{
rt_memset(message->recv_buf, 0x0, message->length);
bflb_spi_poll_exchange(bl_spi->spi, (void *)message->send_buf, (void *)message->recv_buf, message->length);
message->length += strlen(message->recv_buf);
}
else if (message->send_buf)
{
#if defined(BSP_SPI_TX_USING_DMA)
result = _spi_dma_xfer_tx(device, message);
if(result != RT_EOK)
message->length = -1;
#else
bflb_spi_poll_exchange(bl_spi->spi, (void *)message->send_buf, NULL, message->length);
#endif
}
else if (message->recv_buf)
{
rt_memset(message->recv_buf, 0x0, message->length);
#if defined(BSP_SPI_RX_USING_DMA)
result = _spi_dma_xfer_rx(device, message);
if(result != RT_EOK)
message->length = -1;
#else
bflb_spi_poll_exchange(bl_spi->spi, NULL, (void *)message->recv_buf, message->length);
#endif
}
else
{
LOG_E("both send_buf and recv_buf is null!");
message->length = -1;
}
if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS))
{
if (device->config.mode & RT_SPI_CS_HIGH)
bflb_gpio_reset(gpio, cs_pin);
else
bflb_gpio_set(gpio, cs_pin);
}
return message->length;
}
/* spi bus callback function */
static const struct rt_spi_ops bl_spi_ops =
{
.configure = spi_configure,
.xfer = spixfer,
};
/**
* 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, rt_uint32_t cs_pin)
{
RT_ASSERT(bus_name != RT_NULL);
RT_ASSERT(device_name != RT_NULL);
rt_err_t ret;
struct rt_spi_device *spi_device;
/* attach the device to spi bus*/
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
RT_ASSERT(spi_device != RT_NULL);
/* initialize the cs pin */
ret = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
if (ret != RT_EOK)
{
LOG_E("%s attach to %s faild, %d", device_name, bus_name, ret);
ret = RT_ERROR;
}
RT_ASSERT(ret == RT_EOK);
return ret;
}
int rt_hw_spi_init(void)
{
rt_err_t ret = RT_ERROR;
static struct bl_device_spi dev_spi;
struct bflb_device_s *gpio;
gpio = bflb_device_get_by_name("gpio");
#ifndef BL808_CORE_D0
bflb_gpio_init(gpio, SPI_SCK_PIN, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(gpio, SPI_MISO_PIN, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(gpio, SPI_MOSI_PIN, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
dev_spi.spi = bflb_device_get_by_name("spi0");
#ifdef BSP_SPI_TX_USING_DMA
dev_spi.dma_dst_req = DMA_REQUEST_SPI0_TX;
dev_spi.dma_tx = bflb_device_get_by_name(BSP_SPI_TX_DMA_CHANNEL);
#endif
#ifdef BSP_SPI_RX_USING_DMA
dev_spi.dma_src_req = DMA_REQUEST_SPI0_RX;
dev_spi.dma_rx = bflb_device_get_by_name(BSP_SPI_RX_DMA_CHANNEL);
#endif
#endif /* BL808_CORE_D0 */
dev_spi.spi_bus.parent.user_data = (void *)&dev_spi;
ret = rt_spi_bus_register(&dev_spi.spi_bus, "spi0", &bl_spi_ops);
RT_ASSERT(ret == RT_EOK);
return ret;
}
INIT_BOARD_EXPORT(rt_hw_spi_init);
#endif /* BSP_USING_SPI */

View File

@ -0,0 +1,175 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-05-01 flyingcys first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <rthw.h>
#include "bflb_spi.h"
#include "bflb_dma.h"
#ifndef __DRV_SPI_H_
#define __DRV_SPI_H_
#ifdef SPI_SCK_USING_GPIO1
#define SPI_SCK_PIN GPIO_PIN_1
#elif defined(SPI_SCK_USING_GPIO3)
#define SPI_SCK_PIN GPIO_PIN_3
#elif defined(SPI_SCK_USING_GPIO5)
#define SPI_SCK_PIN GPIO_PIN_5
#elif defined(SPI_SCK_USING_GPIO7)
#define SPI_SCK_PIN GPIO_PIN_7
#elif defined(SPI_SCK_USING_GPIO9)
#define SPI_SCK_PIN GPIO_PIN_9
#elif defined(SPI_SCK_USING_GPIO11)
#define SPI_SCK_PIN GPIO_PIN_11
#elif defined(SPI_SCK_USING_GPIO13)
#define SPI_SCK_PIN GPIO_PIN_13
#elif defined(SPI_SCK_USING_GPIO15)
#define SPI_SCK_PIN GPIO_PIN_15
#elif defined(SPI_SCK_USING_GPIO17)
#define SPI_SCK_PIN GPIO_PIN_17
#elif defined(SPI_SCK_USING_GPIO19)
#define SPI_SCK_PIN GPIO_PIN_19
#elif defined(SPI_SCK_USING_GPIO21)
#define SPI_SCK_PIN GPIO_PIN_21
#elif defined(SPI_SCK_USING_GPIO23)
#define SPI_SCK_PIN GPIO_PIN_23
#elif defined(SPI_SCK_USING_GPIO25)
#define SPI_SCK_PIN GPIO_PIN_25
#elif defined(SPI_SCK_USING_GPIO27)
#define SPI_SCK_PIN GPIO_PIN_27
#elif defined(SPI_SCK_USING_GPIO29)
#define SPI_SCK_PIN GPIO_PIN_29
#elif defined(SPI_SCK_USING_GPIO31)
#define SPI_SCK_PIN GPIO_PIN_31
#elif defined(SPI_SCK_USING_GPIO33)
#define SPI_SCK_PIN GPIO_PIN_33
#elif defined(SPI_SCK_USING_GPIO35)
#define SPI_SCK_PIN GPIO_PIN_35
#elif defined(SPI_SCK_USING_GPIO39)
#define SPI_SCK_PIN GPIO_PIN_39
#elif defined(SPI_SCK_USING_GPIO43)
#define SPI_SCK_PIN GPIO_PIN_43
#endif
#ifdef SPI_MISO_USING_GPIO0
#define SPI_MISO_PIN GPIO_PIN_0
#elif defined(SPI_MISO_USING_GPIO1)
#define SPI_MISO_PIN GPIO_PIN_1
#elif defined(SPI_MISO_USING_GPIO2)
#define SPI_MISO_PIN GPIO_PIN_2
#elif defined(SPI_MISO_USING_GPIO4)
#define SPI_MISO_PIN GPIO_PIN_4
#elif defined(SPI_MISO_USING_GPIO5)
#define SPI_MISO_PIN GPIO_PIN_5
#elif defined(SPI_MISO_USING_GPIO6)
#define SPI_MISO_PIN GPIO_PIN_6
#elif defined(SPI_MISO_USING_GPIO8)
#define SPI_MISO_PIN GPIO_PIN_8
#elif defined(SPI_MISO_USING_GPIO9)
#define SPI_MISO_PIN GPIO_PIN_9
#elif defined(SPI_MISO_USING_GPIO10)
#define SPI_MISO_PIN GPIO_PIN_10
#elif defined(SPI_MISO_USING_GPIO12)
#define SPI_MISO_PIN GPIO_PIN_12
#elif defined(SPI_MISO_USING_GPIO13)
#define SPI_MISO_PIN GPIO_PIN_13
#elif defined(SPI_MISO_USING_GPIO14)
#define SPI_MISO_PIN GPIO_PIN_14
#elif defined(SPI_MISO_USING_GPIO16)
#define SPI_MISO_PIN GPIO_PIN_16
#elif defined(SPI_MISO_USING_GPIO17)
#define SPI_MISO_PIN GPIO_PIN_17
#elif defined(SPI_MISO_USING_GPIO18)
#define SPI_MISO_PIN GPIO_PIN_18
#elif defined(SPI_MISO_USING_GPIO20)
#define SPI_MISO_PIN GPIO_PIN_20
#elif defined(SPI_MISO_USING_GPIO21)
#define SPI_MISO_PIN GPIO_PIN_21
#elif defined(SPI_MISO_USING_GPIO22)
#define SPI_MISO_PIN GPIO_PIN_22
#elif defined(SPI_MISO_USING_GPIO25)
#define SPI_MISO_PIN GPIO_PIN_25
#elif defined(SPI_MISO_USING_GPIO26)
#define SPI_MISO_PIN GPIO_PIN_26
#elif defined(SPI_MISO_USING_GPIO29)
#define SPI_MISO_PIN GPIO_PIN_29
#elif defined(SPI_MISO_USING_GPIO30)
#define SPI_MISO_PIN GPIO_PIN_30
#elif defined(SPI_MISO_USING_GPIO34)
#define SPI_MISO_PIN GPIO_PIN_34
#elif defined(SPI_MISO_USING_GPIO38)
#define SPI_MISO_PIN GPIO_PIN_38
#elif defined(SPI_MISO_USING_GPIO42)
#define SPI_MISO_PIN GPIO_PIN_42
#endif
#ifdef SPI_MOSI_USING_GPIO0
#define SPI_MOSI_PIN GPIO_PIN_0
#elif defined(SPI_MOSI_USING_GPIO1)
#define SPI_MOSI_PIN GPIO_PIN_1
#elif defined(SPI_MOSI_USING_GPIO3)
#define SPI_MOSI_PIN GPIO_PIN_3
#elif defined(SPI_MOSI_USING_GPIO4)
#define SPI_MOSI_PIN GPIO_PIN_4
#elif defined(SPI_MOSI_USING_GPIO5)
#define SPI_MOSI_PIN GPIO_PIN_5
#elif defined(SPI_MOSI_USING_GPIO7)
#define SPI_MOSI_PIN GPIO_PIN_7
#elif defined(SPI_MOSI_USING_GPIO8)
#define SPI_MOSI_PIN GPIO_PIN_8
#elif defined(SPI_MOSI_USING_GPIO9)
#define SPI_MOSI_PIN GPIO_PIN_9
#elif defined(SPI_MOSI_USING_GPIO11)
#define SPI_MOSI_PIN GPIO_PIN_11
#elif defined(SPI_MOSI_USING_GPIO12)
#define SPI_MOSI_PIN GPIO_PIN_12
#elif defined(SPI_MOSI_USING_GPIO13)
#define SPI_MOSI_PIN GPIO_PIN_13
#elif defined(SPI_MOSI_USING_GPIO15)
#define SPI_MOSI_PIN GPIO_PIN_15
#elif defined(SPI_MOSI_USING_GPIO16)
#define SPI_MOSI_PIN GPIO_PIN_16
#elif defined(SPI_MOSI_USING_GPIO17)
#define SPI_MOSI_PIN GPIO_PIN_17
#elif defined(SPI_MOSI_USING_GPIO19)
#define SPI_MOSI_PIN GPIO_PIN_19
#elif defined(SPI_MOSI_USING_GPIO20)
#define SPI_MOSI_PIN GPIO_PIN_20
#elif defined(SPI_MOSI_USING_GPIO21)
#define SPI_MOSI_PIN GPIO_PIN_21
#elif defined(SPI_MOSI_USING_GPIO23)
#define SPI_MOSI_PIN GPIO_PIN_23
#elif defined(SPI_MOSI_USING_GPIO24)
#define SPI_MOSI_PIN GPIO_PIN_24
#elif defined(SPI_MOSI_USING_GPIO25)
#define SPI_MOSI_PIN GPIO_PIN_25
#elif defined(SPI_MOSI_USING_GPIO27)
#define SPI_MOSI_PIN GPIO_PIN_27
#elif defined(SPI_MOSI_USING_GPIO28)
#define SPI_MOSI_PIN GPIO_PIN_28
#elif defined(SPI_MOSI_USING_GPIO29)
#define SPI_MOSI_PIN GPIO_PIN_29
#elif defined(SPI_MOSI_USING_GPIO31)
#define SPI_MOSI_PIN GPIO_PIN_31
#elif defined(SPI_MOSI_USING_GPIO33)
#define SPI_MOSI_PIN GPIO_PIN_33
#elif defined(SPI_MOSI_USING_GPIO37)
#define SPI_MOSI_PIN GPIO_PIN_37
#elif defined(SPI_MOSI_USING_GPIO41)
#define SPI_MOSI_PIN GPIO_PIN_41
#elif defined(SPI_MOSI_USING_GPIO45)
#define SPI_MOSI_PIN GPIO_PIN_45
#endif
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t cs_pin);
int rt_hw_spi_init(void);
#endif /*__DRV_SPI_H_*/

View File

@ -10,7 +10,6 @@
#include "drv_wdt.h"
#ifdef RT_USING_WDT
#ifdef BSP_USING_WDT
#define DBG_LEVEL DBG_LOG
#include <rtdbg.h>
@ -94,4 +93,3 @@ int rt_hw_wdt_init(void)
INIT_BOARD_EXPORT(rt_hw_wdt_init);
#endif /* BSP_USING_WDT */
#endif /* RT_USING_WDT */

View File

@ -16,7 +16,8 @@
#include <rtthread.h>
#include <rtdevice.h>
#ifdef RT_USING_HWTIMER
#ifdef BSP_USING_HWTIMER
#define HWTIMER_DEV_NAME "timer0" /* 定时器名称 */

View File

@ -16,7 +16,7 @@
#include <rtthread.h>
#include <rtdevice.h>
#ifdef RT_USING_PWM
#ifdef BSP_USING_PWM
#define LED_PIN_NUM 8 /* LED PIN脚编号查看驱动文件drv_gpio.c确定 */
#define PWM_DEV_NAME "pwm" /* PWM设备名称 */

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-05-01 flyingcys first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#ifdef BSP_USING_SPI
#define BUS_NAME "spi0"
#define SPI_NAME "spi00"
static struct rt_spi_device *spi_dev = RT_NULL;
/* attach spi5 device */
static int rt_spi_device_init(void)
{
struct rt_spi_configuration cfg;
rt_hw_spi_device_attach(BUS_NAME, SPI_NAME, RT_NULL);
cfg.data_width = 8;
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB | RT_SPI_NO_CS;
cfg.max_hz = 10 *1000 *1000;
spi_dev = (struct rt_spi_device *)rt_device_find(SPI_NAME);
if (RT_NULL == spi_dev)
{
rt_kprintf("spi sample run failed! can't find %s device!\n", SPI_NAME);
return -RT_ERROR;
}
rt_spi_configure(spi_dev, &cfg);
return RT_EOK;
}
INIT_APP_EXPORT(rt_spi_device_init);
/* spi loopback mode test case */
static int spi_sample(int argc, char **argv)
{
rt_uint8_t t_buf[8], r_buf[8];
int i = 0;
static struct rt_spi_message msg1;
if (argc != 9)
{
rt_kprintf("Please Usage:\n");
rt_kprintf("spi_sample 1 2 3 4 5 6 7 8\n");
return -RT_ERROR;
}
for (i = 0; i < 8; i++)
{
t_buf[i] = atoi(argv[i+1]);
}
msg1.send_buf = &t_buf;
msg1.recv_buf = &r_buf;
msg1.length = sizeof(t_buf);
msg1.cs_take = 1;
msg1.cs_release = 0;
msg1.next = RT_NULL;
rt_spi_transfer_message(spi_dev, &msg1);
rt_kprintf("spi rbuf : ");
for (i = 0; i < sizeof(t_buf); i++)
{
rt_kprintf("%x ", r_buf[i]);
}
rt_kprintf("\nspi loopback mode test over!\n");
return RT_EOK;
}
MSH_CMD_EXPORT(spi_sample, spi loopback test);
#endif /* BSP_USING_SPI */

View File

@ -19,7 +19,7 @@
#include <rtthread.h>
#include <rtdevice.h>
#ifdef RT_USING_WDT
#ifdef BSP_USING_WDT
#define WDT_DEVICE_NAME "wdt" /* 看门狗设备名称 */