[哪吒开发板]Tina Linux SPI主从通信验证实录
-
背景
- 主控: D1H
- 板卡: 两块哪吒开发板(以下简称为主机, 从机)
- 操作系统: Tina Linux 2.0
问题
验证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概述
SPI接口是一种高速的, 全双工, 同步的通信总线.
适配D1H芯片的Tina Linux的BSP-SDK(以下简称SDK)中已包含相关驱动文件: spi-sunxi.c.
它提供的了仅内核态下主从机的简易通信验证实验, 这或许是考虑到SPI通信速率比较高的特性.
验证操作SPI主机配置
menuconfig
在SDK执行完环境变量加载后, 执行:
/mnt/tina-d1-h$ make kernel_menuconfig
●开启Device Drivers->SPI support
●进入SPI support, 按图示开启:设备树
修改: ./device/config/chips/d1-h/configs/nezha/board.dts
需要根据手册和原理图确认好针脚功能:
SPI从机配置
menuconfig
(同SPI主机配置一致)
设备树
仅spi_slave_mode设为0, 其余项同SPI主机配置一致. spi_slave_mode = <0>;
SPI主机收发信息
按上述配置, 重新编译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从机收发信息
spi-sunxi.c中对SPI从机模(SLAVE_MODE)采取了简单的收发验证处理, 具体是创建一个内核线程执行int sunxi_spi_slave_task(void *data), 该函数又被设备中断所控制(当收到SPI数据时).
-
SPI从机接收到数据的主要流程:
sunxi_spi_slave_task() -> sunxi_spi_slave_handle_head(), 然后:
若指令头是写操作(0x01), 则执行:sunxi_spi_slave_cpu_rx_config(), 该函数仅是输出写入内容.
若指令投是读操作(0x03), 则执行:sunxi_spi_slave_cpu_tx_config(), 该函数仅是将收到的指令体的值+0x80, 然后发送(MISO)给主机. -
对于从机, spi-sunxi.c能验证SPI通信, 但没有可供用户层直接使用的方法.
用户层可验证的SPI从机收发方案
功能设计
从机安排一块32byte的内存缓存空间(简称"缓存空间")供主机通过指令进行读操作和写操作, 且从机能在用户层对该内存空间访问.
主要改动
- spi.c:
- 增加static struct class_attribute ye_spi_buf_attrs[], 以创建/sys/class/spi_slave目录下的spi_buf文件, 并提供实现了读/写缓存空间的方法.
- spi-sunxi.c:
- 使用ye_spi_slave_set_txdata()方法替换sunxi_spi_slave_set_txdata(), 以实现读操作.
- 修改sunxi_spi_slave_cpu_rx_config()方法, 以实现写操作.
改动详情请查看: 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
-
-
@aldfaaa 请问spi通信速率10M太高了,和其他开发板通信速率不一致,导致只能发数据过去,接收到的数据老是出问题,这个spi时钟是否能修改
-
@sfgy125110 能, 但芯片分频器支持的分频数有限. 你可以试出哪个有效
-
@aldfaaa 在设备树哪里修改
修改这个spi-max-frequency抓波形后时钟频率没有改变,还是10M,我看其他人说,这个时钟频率是主sck的分频,这个分频在哪里设置
-
@aldfaaa
修改了dtsi里面的配置,但是量波形还是10M,这就是无效吗,还是要在驱动里面改什么东西 -
@aldfaaa
内核代码直接设置10M,我修改为了1.2M,但是最后输出的时钟频率还是10M,修改这里还需要修改其他地方吗?
路径为/lichee/linux-5.4/drivers/spi/spi-sunxi.c,2310行 -
@sfgy125110 说明不支持该频率. SPI很少用这么速率的通信的, 毕竟用上了4个io
-
@aldfaaa 可以给几个可能有效的频率吗,我试试看,能不能修改成功
-
@sfgy125110 你用spidev_test就可以试,10M,5M,25M,50M
-
请问设备树配置的时候为什么要把spi_dbi_enable这个注释掉,打开的时候就不能产生spidev1.0,这个是什么原因造成的?
-
@jaunenahy spi_dbi_enable 是使用dbi接口接屏幕,驱动挂载到dbi上了不兼容spidev
-
@whycanservice 好的,多谢解答。我现在在尝试使用spi分频更小的时钟,在设备树中修改后如图
但是最终去查看0x02001944这个寄存器里面的值,发现时钟并没有被更换,这个是什么原因造成的,可以帮我解答一下吗,谢谢。 -
@jaunenahy 可以直接这样替换吗?我看了下好像没有这个时钟通路。如果需要低时钟可以打linux rt实时补丁然后软件模拟spi
-
@whycanservice 好的,多谢解答。我看了一下那个设备树文件里面有其他的地方用到了我替换的5分频时钟,而且用户手册中分出来给spi的时钟也有5分频的这个,为什么说没有这个时钟通路啊,还有就是打linux rt补丁去得到低时钟我先去了解一下,有不懂的地方再来请教你。
-
@whycanservice 我刚刚把时钟换成低时钟了,但是现在就是会碰到修改时钟频率然后运行官方的spidev_test会出现卡死的情况,修改的时钟频率都是通过计算得到的,在该时钟分频的范围内的。
-
@aldfaaa
从机模式接收的时候要设置这个寄存器的作用是什么,为什么请求头设置是5,发送大小,接收到的数据要设置成一半,我改成数据大小也没有什么变化,这个寄存器配置有什么作用呢?能不能解答一下
sunxi_spi_slave_cpu_rx_config()函数
sunxi_spi_slave_task()函数
-
@sfgy125110 我记得驱动默认是启用了DMA的, 所以你修改CPU接收过程的参数并不会生效. 手册有对两种SPI通信逻辑介绍
-
@aldfaaa 这个从机模式没有关于dma的代码,是要我自己参照用户手册里面的流程重新写一个代码使用dma吗?
现在主从通信有时候就会漏掉数据,按照你的流程就是主机发送完数据,发0x03 0x00 0x00 0x00 0x05的时候这个数据从机没处理到,直接把第4条数据当成第3条处理,主机就读不到数据
还有就是从机没写数据,但是主机一直会接收到无用数据(.898),结果图就在下面
-
-
@sfgy125110 你的从机要烧录从机镜像才行, 或者根据代码差异去修改从机的SPI驱动.
-
有朋友自行编译slave机发现结构体缺失成员, 发现diff遗漏了头文件的变更:
补上即可.
需要购买D1H官方哪吒开发板, 可以到我店铺看看 :
小叶芯片开发板店 -
-
spi_slave_mode配置的主从模式是不是反了
-
@aldfaaa 在 [哪吒开发板]Tina Linux SPI主从通信验证实录 中说:
有朋友自行编译slave机发现结构体缺失成员, 发现diff遗漏了头文件的变更:
补上即可.
需要购买D1H官方哪吒开发板, 可以到我店铺看看 :
小叶芯片开发板店原来如此,学习了。
-
此回复已被删除!
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号