本文转载自:https://bbs.aw-ol.com/topic/3031 作者 @ whycan矿工-小叶
验证D1H芯片SPI主从机通信.
主机SPI | 从机SPI | ||
---|---|---|---|
19 | SPI1_MOSI | SPI1_MOSI | 19 |
21 | SPI1_MISO | SPI1_MISO | 21 |
23 | SPI1_SCK | SPI1_SCK | 23 |
24 | SPI1_CE | SPI1_CE | 24 |
SPI接口是一种高速的, 全双工, 同步的通信总线. 适配D1H芯片的Tina Linux的BSP-SDK(以下简称SDK)中已包含相关驱动文件: spi-sunxi.c. 它提供的了仅内核态下主从机的简易通信验证实验, 这或许是考虑到SPI通信速率比较高的特性. 验证操作
在SDK执行完环境变量加载后, 执行:
/mnt/tina-d1-h$ make kernel_menuconfig
●开启Device Drivers->SPI support ●进入SPI support, 按图示开启:
修改: ./device/config/chips/d1-h/configs/nezha/board.dts
需要根据手册和原理图确认好针脚功能:
(同SPI主机配置一致)
仅spi_slave_mode设为0, 其余项同SPI主机配置一致. spi_slave_mode = <0>;
按上述配置, 重新编译SDK, 打包, 烧录, 启动设备会出现:
root@TinaLinux# ls -l /dev/spidev1.0
crw------- 1 root root 153, 0 Jan 1 08:00 /dev/spidev1.0
然后将可执行的SPI测试程序(./lichee/linux-5.4/tools/spi/spidev_test)挪到设备上(adb push等)并赋予可执行权限:
# 主机以10MHz发送(即MOSI)发送16进制数据: 0x01 0x02 0x03 0x04
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "\x01\x02\x03\x04"
# 主机以10MHz发送(即MOSI)发送ASCII字符串数据: "allwinner"
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "allwinner"
spi mode: 0x0
bits per word: 8
max speed: 10000000 Hz (10000 KHz)
TX | 61 6C 6C 77 69 6E 6E 65 72 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |allwinner|
注意SPI是同步通信接口, 所以在发送的同时也会接收同样长度字节的数据. 下文将用到SPI主从通信的一种常见做法: 主机先发指令头, 然后再发指令体以获取从机应答.
spi-sunxi.c中对SPI从机模(SLAVE_MODE)采取了简单的收发验证处理, 具体是创建一个内核线程执行int sunxi_spi_slave_task(void *data), 该函数又被设备中断所控制(当收到SPI数据时).
从机安排一块32byte的内存缓存空间(简称"缓存空间")供主机通过指令进行读操作和写操作, 且从机能在用户层对该内存空间访问.
改动详情请查看: d1h_spi_driver.diff
写操作: 操作:0x01(写) 地址:0x00 0x00 0x00 指令体长度:0x09
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "\x01\x00\x00\x00\x09" && \
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "allwinner"
读操作: 操作:0x03(读) 地址:0x00 0x00 0x00 指令体长度:0x09
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "\x03\x00\x00\x00\x09" && \
./spidev_test -v -D /dev/spidev1.0 -s 10000000 -p "\x00\x00\x00\x00\x00\x00\x00\x00\x00"
从机读取缓存空间:
cat /sys/class/spi_slave/spi_buf
从机写入缓存空间:
echo "Hello world" > /sys/class/spi_slave/spi_buf