Browse Source

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

flyingcys 2 years ago
parent
commit
6edd0586f2

+ 45 - 21
bsp/bouffalo_lab/README.md

@@ -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-进行烧录) 相关内容来修复问题)。 |
-

+ 156 - 0
bsp/bouffalo_lab/bl808/README.md

@@ -0,0 +1,156 @@
+# 博流智能 BL808板级支持包说明
+
+## 1. 简介
+
+BL808 是高度集成的 AIoT 芯片组,具有 Wi-Fi/BT/BLE/Zigbee 等无线互联单元,包含多个 CPU 以及音频编码译码器、视频编码译码器和 AI 硬件加速器,适用于各种高性能和低功耗应用领域。
+
+BL808 系列芯片主要包含无线和多媒体两个子系统。
+
+无线子系统包含一颗 RISC-V 32-bit 高性能 CPU(m0),集成 Wi-Fi/BT/Zigbee 无线子系统,可以实现多种无线连接和数据传输,提供多样化的连接与传输体验。
+多媒体子系统包含一颗 RISC-V 64-bit 超高性能 CPU(d0),集成 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-进行烧录) 相关内容来修复问题)。

BIN
bsp/bouffalo_lab/bl808/figures/bl808.png


BIN
bsp/bouffalo_lab/bl808/figures/d0.png


BIN
bsp/bouffalo_lab/bl808/figures/kernel_start.png


+ 18 - 19
bsp/bouffalo_lab/bl808/m0/applications/dfs_mnt_sample.c → bsp/bouffalo_lab/bl808/m0/applications/mnt.c

@@ -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>
 
+#define DBG_TAG    "mnt"
+#define DBG_LVL    DBG_INFO
+#include <rtdbg.h>
+
 #ifdef RT_USING_DFS
-#ifdef RT_USING_FAL
-#ifdef BSP_USING_ON_CHIP_FLASH
+#include <dfs_fs.h>
 
-#include "dfs_file.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_DFS */
 #endif /* RT_USING_FAL */
-#endif /* BSP_USING_ON_CHIP_FLASH */
+
+#endif /* RT_USING_DFS */

+ 2 - 2
bsp/bouffalo_lab/bl808/m0/flash_prog_cfg.ini

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

+ 320 - 16
bsp/bouffalo_lab/libraries/rt_drivers/Kconfig

@@ -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
 

+ 10 - 3
bsp/bouffalo_lab/libraries/rt_drivers/SConscript

@@ -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']

+ 12 - 8
bsp/bouffalo_lab/libraries/rt_drivers/drv_flash.c

@@ -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 */

+ 3 - 2
bsp/bouffalo_lab/libraries/rt_drivers/drv_gpio.c

@@ -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 */

+ 4 - 4
bsp/bouffalo_lab/libraries/rt_drivers/drv_hwtimer.c

@@ -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 */

+ 2 - 2
bsp/bouffalo_lab/libraries/rt_drivers/drv_pwm.c

@@ -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");

+ 3 - 3
bsp/bouffalo_lab/libraries/rt_drivers/drv_rtc.c

@@ -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 */

+ 3 - 2
bsp/bouffalo_lab/libraries/rt_drivers/drv_soft_i2c.c

@@ -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 */

+ 568 - 0
bsp/bouffalo_lab/libraries/rt_drivers/drv_spi.c

@@ -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 */

+ 175 - 0
bsp/bouffalo_lab/libraries/rt_drivers/drv_spi.h

@@ -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_*/

+ 0 - 2
bsp/bouffalo_lab/libraries/rt_drivers/drv_wdt.c

@@ -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 */

+ 2 - 1
bsp/bouffalo_lab/bl808/m0/applications/hwtimer_sample.c → bsp/bouffalo_lab/libraries/rt_drivers/sample/hwtimer_sample.c

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

+ 1 - 1
bsp/bouffalo_lab/bl808/m0/applications/pwm_led_sample.c → bsp/bouffalo_lab/libraries/rt_drivers/sample/pwm_led_sample.c

@@ -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设备名称 */

+ 86 - 0
bsp/bouffalo_lab/libraries/rt_drivers/sample/spi_sample.c

@@ -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 */

+ 1 - 1
bsp/bouffalo_lab/bl808/m0/applications/wdt_sample.c → bsp/bouffalo_lab/libraries/rt_drivers/sample/wdt_sample.c

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