ArmSom---SPI开发指南

1. 简介

  • RK3588从入门到精通
  • 本⽂主要介绍在Rockchip平台配置spi接口并且使用的方法
  • 开发板:ArmSoM-W3
  • Kernel:5.10.160
  • OS:Debian11

2. SPI接口概述

SPI(Serial Peripheral Interface),即串行外围设备接口,是一种同步的,全双工的,多设备的,多主机的通信协议,用于连接外围设备,如ADC、DAC、数据存储器、定时器、接受器等。

2.1 spi接口的结构

在这里插入图片描述

  1. 主机:主机是SPI总线的控制者,它负责控制数据传输的方向和传输速度。
  2. 从机:从机是SPI总线的被控制者,它根据主机发出的指令,发出或接收数据。
  3. MOSI(Master Out Slave In):主机输出从机输入,用于传输从主机到从机的数据。
  4. MISO(Master In Slave Out):主机输入从机输出,用于传输从从机到主机的数据。
  5. CK(Serial Clock):时钟线,用于同步主机和从机之间的数据传输。
  6. CS(Chip Select):片选线,用于控制主机和从机之间的数据传输。

此外,SPI接口还有其他可选项,如中断线(INT)、复位线(RESET)等。

2.2 SPI接口的工作原理

在SPI接口通信过程中,主机发出一个片选信号,然后在时钟信号的控制下,主机发出一个字节的数据,从机接收到数据之后,也会发出一个字节的数据,主机接收到数据之后,发出一个片选信号,结束一次通信。

SPI接口有两种工作模式:主模式和从模式。主模式下,主机控制从机,从机接收主机发出的指令。从模式下,从机可以接收主机发出的指令,并向主机发送数据。

3.SPI硬件接口

RK3588旗舰芯片上可使用的spi接口有5组,ArmSoM SOM-3588-LGA核心板采用LGA 506引脚封装方式将spi资源全部引出,ArmSoM-W3开发板上40PIN引脚中有两组spi接口:

在这里插入图片描述

4.spi设备配置

spi驱动相关代码路径:

drivers/spi/spi.c spi驱动框架
drivers/spi/spi-rockchip.c rk spi各接口实现
drivers/spi/spidev.c 创建spi设备节点,用户态使用。
drivers/spi/spi-rockchip-test.c spi测试驱动,需要自己手动添加到Makefile编译
Documentation/spi/spidev_test.c 用户态spi测试工具

4.1 配置 DTS 节点

&spi1 {status = "okay";//assigned-clock-rates = <200000000>; //默认不用配置,SPI 设备工作时钟max-freq = <48000000>; /* spi internal clk, don't modify *///dma-names = "tx","rx"; //使能DMA模式//rx-sample-delay-ns = <10>; //默认不用配置,读采样延时spi_dev@0 {compatible = "rockchip,spidev";reg = <0>;spi-max-frequency = <12000000>;spi-lsb-first; //IO 先传输 lsb		};
};
  • status:如果要启用 SPI,则设为 okay,如不启用,设为 disable。

  • spi_dev@0:本例子使用 CS0,故此处设为 0,如果使用 CS1,则设为 1。

  • compatible:这里的属性必须与驱动中的结构体:of_device_id 中的成员 compatible 保持一致。

  • reg:此处与 spi_dev@0 保持一致,这里设为0。

  • spi-max-frequency:此处设置 spi 使用的最高频率,ITX-3588J 最高支持 50000000。

这里使用的驱动是drivers/spi/spidev.c,驱动设备加载注册成功后,会出现类似这个名字的设备:/dev/spidev1.0。

一些常见的SPI驱动API接口:

Linux SPI API:

  • spi_register_driver():注册SPI设备驱动程序。
  • spi_unregister_driver():注销SPI设备驱动程序。
  • spi_setup():设置SPI总线和设备的参数。
  • spi_sync():同步方式进行SPI数据传输。
  • spi_message_init():初始化SPI消息结构。
  • spi_message_add_tail():向SPI消息添加传输操作。
  • spi_sync():同步方式进行SPI数据传输。
  • spi_transfer():进行SPI数据传输。

SPI驱动中常用的ioctl请求值,这些请求值用于设置和读取SPI设备的各种参数,包括通信模式、字长、数据模式和通信速率等。这些请求值通常用于Linux的SPI驱动编程。以下是一些常用的SPI ioctl请求值:

  • SPI_IOC_RD_MODE: 读取SPI设备的通信模式。
  • SPI_IOC_WR_MODE: 设置SPI设备的通信模式。
  • SPI_IOC_RD_MODE32: 读取SPI设备的32位通信模式。
  • SPI_IOC_WR_MODE32: 设置SPI设备的32位通信模式。
  • SPI_IOC_RD_LSB_FIRST: 读取SPI设备的LSB(Least Significant Bit)优先模式。
  • SPI_IOC_WR_LSB_FIRST: 设置SPI设备的LSB优先模式。
  • SPI_IOC_RD_BITS_PER_WORD: 读取SPI设备的字长。
  • SPI_IOC_WR_BITS_PER_WORD: 设置SPI设备的字长。
  • SPI_IOC_RD_MAX_SPEED_HZ: 读取SPI设备的最大通信速率。
  • SPI_IOC_WR_MAX_SPEED_HZ: 设置SPI设备的最大通信速率。
  • SPI_IOC_MESSAGE(N): 一次进行N次双向或多次读写操作。

4.2 SPI测试实验

将上述设备树以及驱动修改之后更新板卡的内核,通过SPI设备文件来判断spi驱动是否加载成功

这里测试使用的是spi1这一组spi相关接口,检查spi设备:

root@linaro-alip:~# ls /dev/spi*
/dev/spidev1.0	
root@linaro-alip:~# 

测试SPI接口,使用/dev/spidev1.0设备节点,实现短接MOSI和MISO线路以自发自收数据,同时在未短接时报告错误

4.2.1 硬件连接

将SPI1的 MIOS与MOSI引脚(板卡上的7和8)短接即可,如下图所示
在这里插入图片描述

4.2.2 测试程序

用户应用层使用spidev驱动的步骤如下:

  1. 打开SPI设备文件:用户可以通过打开/dev/spidevX.Y文件来访问SPI设备,其中X是SPI控制器的编号,Y是SPI设备的编号。

  2. 配置SPI参数:用户可以使用ioctl命令SPI_IOC_WR_MODE、SPI_IOC_WR_BITS_PER_WORD和SPI_IOC_WR_MAX_SPEED_HZ来设置SPI模式、数据位数和时钟速度等参数。

  3. 发送和接收数据:用户可以使用read和write系统调用来发送和接收SPI数据。写入的数据将被传输到SPI设备,而从设备读取的数据将被存储在用户提供的缓冲区中。

  4. 关闭SPI设备文件:当不再需要与SPI设备通信时,用户应该关闭SPI设备文件。

总结起来,spidev驱动提供了一种简单而灵活的方式来与SPI设备进行通信,使得用户可以轻松地在Linux系统上开发和控制SPI设备。

armsom团队 的测试程序spi_test.c如下:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>#define SPI_DEV_PATH "/dev/spidev1.0"int fd;
static unsigned mode = SPI_MODE_0;
static uint8_t bits = 8;
static uint32_t speed = 1000000; // 设置SPI速度为1MHz
static uint16_t delay;void transfer(int fd, uint8_t const *tx, uint8_t *rx, size_t len)
{int ret;struct spi_ioc_transfer tr = {.tx_buf = (unsigned long)tx,.rx_buf = (unsigned long)rx,.len = len,.delay_usecs = delay,.speed_hz = speed,.bits_per_word = bits,.cs_change = 0, // 设置为1以在每次传输前切换片选,这里不切换片选};ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);if (ret < 1) {perror("SPI transfer failed");}
}void spi_init(void)
{int ret;// 打开 SPI 设备fd = open(SPI_DEV_PATH, O_RDWR);if (fd < 0) {perror("Can't open SPI device");exit(1);}// 设置 SPI 工作模式ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);if (ret == -1) {perror("Can't set SPI mode");exit(1);}// 设置位数ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);if (ret == -1) {perror("Can't set bits per word");exit(1);}// 设置SPI速度ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);if (ret == -1) {perror("Can't set max speed");exit(1);}// 打印设置printf("SPI mode: 0x%x\n", mode);printf("Bits per word: %d\n", bits);printf("Max speed: %d Hz\n", speed);
}int main(int argc, char *argv[])
{if (argc != 2) {printf("Usage: %s <string_to_send>\n", argv[0]);return 1;}char *tx_buffer = argv[1]; // 获取要发送的字符串作为命令行参数// 初始化SPI接口spi_init();// 设置要接收数据的缓冲区unsigned char rx_buffer[strlen(tx_buffer) + 1];// 执行SPI数据传输transfer(fd, tx_buffer, rx_buffer, strlen(tx_buffer));// 打印发送和接收的数据printf("Sent: %s\n", tx_buffer);printf("Received: %s\n", rx_buffer);// 关闭SPI设备close(fd);return 0;
}

4.2.3 编译&运行

开发板上下载gcc编译器:

apt upgrade
apt update
apt install gcc

编译:

gcc spi_test.c -o spi

短接与不短接的运行情况如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/128895.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ElementuiPlus的table组件实现行拖动与列拖动

借助了插件sortablejs。这种方法只适合做非树状table。如果想实现树状table&#xff0c;并且可拖动。可以试一下aggridVue3这个插件 <template><div class"draggable" style"padding: 20px"><el-table row-key"id" :data"t…

RabbitMQ 消息对象 序列化/反序列化 天坑!异常处理方案

目录 1. 报错的背景 2. 问题分析 3. 最佳解决办法 1. 报错的背景 a&#xff09;使用 RabbitMQ 发送消息时&#xff0c;发送消息的类型为 Map<String, Object>&#xff0c;map 里面我 put 了一个 <String, Long> 类型&#xff0c;如下图&#xff1a; b&#xff…

【考研数据结构代码题2】删除单链表倒数第n个结点

题目&#xff1a;删除单链表倒数第n个结点 难度&#xff1a;★ 算法思路&#xff1a; 首先题目没有指明链表的长度&#xff0c;多以首先需要编写一个函数getLength()来求表长&#xff0c;其次删除倒数第n个结点&#xff0c;即删除正数第length-n1个结点&#xff0c;这是二者之间…

更快更准 | YOLOv3算法超详细解析(包括诞生背景+论文解析+技术原理等)

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。YOLOv3是一种基于深度学习的目标检测算法&#xff0c;它可以快速而准确地在图像中检测出多个目标。它是由Joseph Redmon和Ali Farhadi在2018年提出的&#xff0c;是YOLO&#xff08;You Only Look Once&#xff09;系列算法…

Linux权限+Shell和Linux的关系

文章目录 1.Shell存在的意义及作用1.1对于Shell的认知过程1.2Shell/图形化界面外壳程序的意义 2.对Linux权限的理解2.1对Linux权限的认知过程2.2对于Linux下ll指令显示的文件属性的认识 1.Shell存在的意义及作用 1.1对于Shell的认知过程 Linux是什么? Linux是一套免费使用和自…

msvcr110.dll丢失的解决方法都有哪些,有效解决msvcr110.dll丢失

今天在使用电脑的时候提示一个和“msvcr110.dll丢失”有关的报错&#xff0c;出现这样的问题小编也是一脸懵&#xff0c;一下也不是知道该怎么处理了&#xff0c;于是小编去了解了一下msvcr110.dll丢失是什么情况&#xff0c;为什么会有这样的问题发生&#xff0c;同时msvcr110…

多模态论文阅读之VLMo

VLMo泛读 TitleMotivationContributionModelExpertimentsSummary Title VLMo:Unified Vision_Langugae Pre-Training with Mixture-of-Modality-Experts Motivation CLIP和ALIGN都采用dual-encoder的方式分别编码图像和文本&#xff0c;模态之间的交互采用cosine similarity…

《C++ Primer》第6章 函数(一)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 6.1 函数基础&#xff08;P182&#xff09; 典型的函数定义包括&#xff1a;返回类型&#xff08; return type &#xff09;、函数名字、0 个或多个形参&#xff08; parameter &#xff09;组成的列表、函…

Redis常见的全局命令

Redis中最核心的两个命令set和get 两个最核心的命令就是get和set. redis是按照键值对的方式来存储数据的,所以set就表示把key-value存储进去,get表示根据key来查询对应的value. 需要注意的是,必须进入redis客户端才能输入redis命令. 此处的key和value都是字符串类型.对于上述…

致远OA wpsAssistServlet任意文件上传漏洞复现 [附POC]

文章目录 致远OA wpsAssistServlet任意文件上传漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 致远OA wpsAssistServlet任意文件上传漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用…

【行云流水线实践】基于“OneBuild”方法对镜像进行快速装箱 | 京东云技术团队

在云原生领域&#xff0c;无论使用哪种编排调度平台&#xff0c;Kubernetes&#xff0c;DockerSwarm&#xff0c;OpenShift等&#xff0c;业务都需要基于镜像进行交付&#xff0c;我们在内部实践“Source-to-image”和链式构建&#xff0c;总而总结出“OneBuild”模式。 其核心…

VS2022安装时碰到VsWebProtocolSelector.Msi包安装错误,2330code解决方法

未能安装包“Microsoft.VisualStudio.VsWebProtocolSelector.Msi,version17.8.34129.139”。 搜索 URL https://aka.ms/VSSetupErrorReports?qPackageIdMicrosoft.VisualStudio.VsWebProtocolSelector.Msi;PackageActionInstall;ReturnCode2330 详细信息 …

C++——定义一个 Book(图书)类

完整代码&#xff1a; /*定义一个 Book(图书)类&#xff0c;在该类定义中包括数据成员和成员函数 数据成员&#xff1a;book_name &#xff08;书名&#xff09;、price(价格)和 number(存书数量)&#xff1b; 成员函数&#xff1a;display()显示图书的 情况&#xff1b;borro…

Spring面试题:(二)基于xml方式的Spring配置

xml配置Bean的常见属性 id属性 name属性 scope属性 lazy-init属性 init-method属性和destroy属性 initializingBean方法 Bean实例化方式 ApplicationContext底层调用BeanFactory创建Bean&#xff0c;BeanFactory可以利用反射机制调用构造方法实例化Bean&#xff0c;也可采用工…

Apollo云实验:使用Sim control仿真自动驾驶

使用Sim control仿真自动驾驶 概述Sim control仿真自动驾驶启动DreamView仿真系统 实验目的福利活动 主页传送门&#xff1a;&#x1f4c0; 传送 概述 自动驾驶汽车在实现落地应用前&#xff0c;需要经历大量的道路测试来验证算法的可行性和系统的稳定性&#xff0c;但道路测试…

关于Linux下排查C++进程Segment fault问题的步骤

C 中出现Segment问题的常见原因有: 如果要定位Segment fault问题&#xff0c;需要进行如下几步&#xff1a; gdb your_program(gdb) break main(gdb) run(gdb) backtrace同时要在CMakeLists.txt文件中配置编译时启用符号调试信息&#xff0c; 在C或者C中的设置分别如下&#x…

Pytest UI自动化测试实战实例

环境准备 序号库/插件/工具安装命令1确保您已经安装了python3.x2配置python3pycharmselenium2开发环境3安装pytest库pip install pytest4安装pytest -html 报告插件pip install pytest-html5安装pypiwin32库(用来模拟按键)pip install pypiwin326安装openpyxl解析excel文件库p…

R语言使用surveyCV包对NHANES数据(复杂调查加权数据)进行10折交叉验证

美国国家健康与营养调查&#xff08; NHANES, National Health and Nutrition Examination Survey&#xff09;是一项基于人群的横断面调查&#xff0c;旨在收集有关美国家庭人口健康和营养的信息。 地址为&#xff1a;https://wwwn.cdc.gov/nchs/nhanes/Default.aspx 既往咱们…

Linux 服务器 Oracle19C安装

原文:【精选】Oracle | CentOS7安装Oracle19c数据库(RPM包)_oracle-database-preinstall-19c-1.0-1.el7.x86_64.rp_Thorolds Deer的博客-CSDN博客 下载 第一个软件包:Oracle Database 19c Download for Linux x86-64 第二个包:Oracle Linux 7 (x86_64) Latest | Oracle,…

免费(daoban)gpt,同时去除广告

一. 内容简介 免费(daoban)gpt&#xff0c;同时去除广告&#xff0c;https://chat18.aichatos.xyz/&#xff0c;也可当gpt用&#xff0c;就是有点广告&#xff0c;大家也可以支持一下 二. 软件环境 2.1 Tampermonkey 三.主要流程 3.1 创建javascript脚本 点击添加新脚本 …