使用spi-gpio-custom模块配置SPI总线

news/2025/3/15 21:02:18/文章来源:https://www.cnblogs.com/lsgxeva/p/18504347

使用spi-gpio-custom模块配置SPI总线

 

来源 https://www.xuzhe.tj.cn/index.php/2023/10/26/spi-gpio-customspi/

参考专栏 https://www.zhihu.com/column/c_1698084667767709696

 

1. 引言

SPI(Serial Peripheral Interface)是一种常见的串行通信协议,广泛应用于微控制器与外部设备的连接。

Linux内核中的spi-gpio与spi-bitbang模块可使用GPIO引脚进行SPI的位操作,spidev模块可将SPI暴露给用户空间。但是,这些模块并不能“直接”使用:它们被其他内核驱动程序使用。没有办法动态地说“我想在这些引脚上使用一个SPI”。相反,我们需要重新配置、编译内核。

spi-gpio-custom模块允许动态配置SPI总线及其节点,无需重新编译内核。对于测试、概念验证非常方便。此外,spi-gpio-custom模块的速度也相当不错,测试显示它可以达到1 MHz以上。

2. 安装spi-gpio-custom

以openwrt系统为例,安装模块包是最方便的。如果还要修改其它的openwrt构建设置,可在make menuconfig中选上此模块,然后重新编译openwrt。

2.1 离线安装模块包

在线安装最便捷,会自动安装依赖包,但需要网络条件。离线安装需要先下载好所需要的包,之后手动安装。

可使用LuCI网页界面安装,操作简单。简单直观,本文不再介绍。

下面介绍命令行安装方法,可在没有配置LuCI功能,或LuCI页面出错打不开时使用。

下载包:kernel、kmod-spi-bitbang、kmod-spi-dev、kmod-spi-gpio、kmod-spi-gpio-custom。其中只kmod-spi-gpio-custom是需要的spi-gpio-custom包,其它均为依赖包。

包要与操作系统及硬件主控对上。比如包名:

kmod-spi-gpio-custom_3.18.29-1-8876e460a901ba0991338a5b1846e893_ramips_24kec.ipk 

其中,各部分的含义为:

  • kmod-: 内核模块(Kernel Module)。
  • spi-gpio-custom: 内核模块的具体名称。
  • 3.18.29: 这是该内核模块所依赖的 Linux 内核版本。
  • -1: 这是该软件包版本的修订号,通常用于追踪小的更新或修补。
  • 8876e460a901ba0991338a5b1846e893: 这是一个校验和或唯一标识符,用于确保软件包的完整性和唯一性。
  • ramips: 这表示该模块是为基于 Ralink/MediaTek MIPS 架构(ramips)的设备编译的。
  • 24kec: 这是该 MIPS 架构下的一个特定型号或子架构。
  • .ipk: 这是软件包的文件扩展名,表明它是一个用于 OpenWRT 的安装包。

模块包的安装命令opkg install。如安装kmod-spi-gpio-custom包:

opkg install kmod-spi-gpio-custom*.ipk

在命令中,可用*号用替代后续字符。

按照这个顺序依次安装:kernel、kmod-spi-bitbang、kmod-spi-dev、kmod-spi-gpio、kmod-spi-gpio-custom。

检验是否安装成功:

opkg list-installed | grep spi-gpio

看到kmod-spi-gpio-custom,说明已安装好。

安装时,如还遇到缺少依赖包问题,需根据提示,依次安装。

2.2 编译安装

在系统源代码根目录,输入配置指令:

make menuconfig

在kernel model -> spi support,选中”kmod-spi-gpio-custom”,系统会自动选中三个依赖包:“kmod-spi-bitbang”、“kmod-spi-dev”、“kmod-spi-gpio”。

保存退出后,重新编译openwrt:

make j=2 //双线程编译

3 使用spi-gpio-custom模块配置SPI总线

spi-gpio-custom 的便利就在于可动态配置SPI总线,不需“修改dts文件、编译系统”的繁琐操作。也就是说,通过spi-gpio-custom使用spi时,dts文件中可以没有任何spi功能的定义。

常规的一个屏幕接口引脚定义

接口功能
MISO SPI输出
MOSI SPI输入
CLK SPI时钟输入
DC 数据/命令 切换控制,低电平表示输入命令,高电平表示输入数据
RES 复位屏幕
BLK 背光控制
VCC 电源
GND 接地

配置举例

配置一个ID为1的总线,使用GPIO3作为CLK,GPIO4作为MOSI,GPIO5作为MISO,在SPI模式0下工作、最大频率为20KHz、GPIO2作为CS的设备。

命令参数  功能描述
<id> ID to used as device_id for the corresponding bus (required)
<sck> GPIO pin ID to be used for bus SCK (required)
<mosi> GPIO pin ID to be used for bus MOSI (required*)
<miso> GPIO pin ID to be used for bus MISO (required*)
<modeX> Mode configuration for slave X in the bus (required) * (see /include/linux/spi/spi.h)
<maxfreqX> Maximum clock frequency in Hz for slave X in the bus (required)
<csX> GPIO pin ID to be used for slave X CS (required**)

运行命令:

insmod spi-gpio-custom bus0=1,3,4,5,0,20000,2

请注意GPIOx中的x,不是引脚编号(pin),而是引脚名称。

如需修改spi总线的配置,需先卸载后再加载:

rmmod spi-gpio-custom 
insmod spi-gpio-custom <new parameters>

更复杂的配置,参考 原始文档: SPI over GPIO in OpenWrt

 

=========

MT7628dan 增加SPI接口

来源  https://blog.csdn.net/likang517/article/details/80864918

 

SPI是可以全双工通信的一种串行总线,两个设备之间双向通信的话一般使用3根线:SCLK,MISO,MOSI,多个设备之间双向通信的话,每个设备还需要再加上一根地址线CSn。相比之下I2C只能半双工,而且一般需要上拉电阻,但无论几个设备,都只需要2根线。更多基础知识请谷歌百度。

MT7628DAN芯片只有一个主控制器,但是有两个片选信号,可以接2个设备,其中一个已经被SPI FLASH占用,所以需要启用另外一个设备。

1、修改内核配置文件

make menuconfig

配置完成后退出保存。

1、修改文件mt7628an.dtsi

spi0: spi@b00 {
compatible = "ralink,mt7621-spi";
reg = <0xb00 0x100>;
resets = <&rstctrl 18>;
reset-names = "spi";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&spi_pins>,<&spi_cs1_pins>;
status = "disabled";

};

spi@b00代表一个spi控制器,是一个platform device,compatible = "ralink,mt7621-spi";和 platform driver 中的of_match_table 对应(如果要支持片选1,还得修改num_cs=2,前提是mt7628的spi控制器本来就支持两个片选).相同就会进入到probe函数中,再调用spi_register_master()注册一个spi主控制器.<&spi_cs1_pins>是新增片选引脚,文件mt7628an.dtsi中有定义:

spi_pins: spi {
spi {
ralink,group = "spi";
ralink,function = "spi";
};
};


spi_cs1_pins: spi_cs1 {
spi_cs1 {
ralink,group = "spi cs1";
ralink,function = "spi cs1";
};
};

3、修改MT7628.dts 文件

/dts-v1/;

#include "mt7628an.dtsi"


/ {
compatible = "mediatek,mt7628an-eval-board", "mediatek,mt7628an-soc";
model = "Mediatek MT7628AN evaluation board";


memory@0 {
device_type = "memory";
reg = <0x0 0x2000000>;
};
};


&pinctrl {
state_default: pinctrl0 {
gpio {
ralink,group = "i2c";
ralink,function = "gpio";
};
};
};


&wmac {
status = "okay";
};


&spi0 {
status = "okay";


m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <10000000>;
m25p,chunked-io = <32>;


partition@0 {
label = "u-boot";
reg = <0x0 0x30000>;
read-only;
};


partition@30000 {
label = "u-boot-env";
reg = <0x30000 0x10000>;
read-only;
};


factory: partition@40000 {
label = "factory";
reg = <0x40000 0x10000>;
read-only;
};


partition@50000 {
label = "firmware";
reg = <0x50000 0x7b0000>;
};
};
spidev@1 {
compatible = "rohm,dh2228fv";
reg = <1 0>;
spi-max-frequency = <1000000>;
};
};


&wmac {
status = "okay";

};

 

spi_register_master注册spi主控制器时就会扫描这些设备,并注册这些设备。 status = “okay”表示选中,否则不能编译进内核. m25p80@0表示在spi片选0下挂了一个m25p80的设备,reg=<0,0>表示片选0,compatible = "jedec,spi-nor"; 与驱动文件匹配.如果要在spi控制器的片选1上挂一个设备,就要修改dts文件,修改如下:

spidev@1 {
compatible = "rohm,dh2228fv";
reg = <1 0>;
spi-max-frequency = <1000000>;

};

compatible = "rohm,dh2228fv";与 spidev.c文件中compatible 一致。

 

4、保存修改文件,执行make 生产升级固件

lede-snapshot-r7346-7b74b40-ramips-mt76x8-mt7628-squashfs-sysupgrade.bin

5、烧写固件查看设备文件:

6、好不好用还没有测试。

7、编译spi-test进行spi测试

8、执行

root@OpenWrt:/# spidev_test -D /dev/spidev0.1

出现如下一连串错误


spi mode: 0x0[ 196.130000] ------------[ cut here ]------------

bits per word:[ 196.130000] WARNING: CPU: 0 PID: 161 at drivers/spi/spi-mt7621.c:137 mt7621_spi_transfer_one_message+0x158/0x360()

8

max speed: 5[ 196.140000] Modules linked in:00000 Hz (500 KH qcserialz)

pppoe ppp_async option iptable_nat usb_wwan sierra pppox ppp_generic nf_nat_ipv4 nf_conntrack_ipv6 nf_conntrack_ipv4 ipt_REJECT ipt_MASQUERADE xt_time xt_tcpudp xt_state xt_nat xt_multiport xt_mark xt_mac xt_limit xt_id xt_conntrack xt_comment xt_TCPMSS xt_REDIRECT xt_LOG xt_CT usbserial spidev slhc nf_reject_ipv4 nf_nat_masquerade_ipv4 nf_nat_ftp nf_nat nf_log_ipv4 nf_defrag_ipv6 nf_defrag_ipv4 nf_conntrack_rtcache nf_conntrack_ftp nf_conntrack iptable_raw iptable_mangle iptable_filter ip_tables crc_ccitt i2c_gpio i2c_algo_bit i2c_dev i2c_core mt76x8 ralink_eeprom_api ledtrig_usbdev ip6t_REJECT nf_reject_ipv6 nf_log_ipv6 nf_log_common ip6table_raw ip6table_mangle ip6table_filter ip6_tables x_tables ipv6 mmc_block mmc_core leds_gpio ohci_platform ohci_hcd ehci_platform ehci_hcd gpio_button_hotplug usbcore nls_base usb_common

[ 196.220000] CPU: 0 PID: 161 Comm: spi32766 Tainted: G W 3.18.20 #8
[ 196.230000] Stack : 00000000 00000000 00000000 00000000 803441f2 00000042 00000000 801ae398

00000001 8f8c7b88 802a53d0 802fc9c3 000000a1 8034341c 8f900bf8 8f8c7b88
00010000 80309578 00000000 80047400 00000003 80024170 00000089 8f8c7b88
802a88d4 8f979d74 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
...

[ 196.270000] Call Trace:
[ 196.270000] [<800140b4>] show_stack+0x48/0x70
[ 196.270000] [<800242ec>] warn_slowpath_common+0x84/0xb4
[ 196.280000] [<800243a4>] warn_slowpath_null+0x18/0x24
[ 196.290000] [<801ae398>] mt7621_spi_transfer_one_message+0x158/0x360
[ 196.290000] [<801ad4e8>] spi_pump_messages+0x3cc/0x438
[ 196.300000] [<80039b9c>] kthread_worker_fn+0xa8/0xf4
[ 196.300000] [<80039cc0>] kthread+0xd8/0xe4
[ 196.310000] [<80004878>] ret_from_kernel_thread+0x14/0x1c
[ 196.310000]
[ 196.310000] ---[ end trace 828b306131dd7246 ]---
can't send spi message: Input/output error
Aborted

查了好几天问题,没明白找到了一个帖子

http://dev.archive.openwrt.org/ticket/20521?action=new&attachfilebutton=Attach+file#no1

原因是

The spidev_test is transmitting a 38 bytes array, that is too large. The spi-mt7621.c will reject when Tx length > 16 (full duplex).

然后修改mt7621.c文件,把全双工注释掉可正常运行spi-test。

 

============

QCA9531修改寄存器值控制GPIO

来源  https://blog.csdn.net/cocos_yang/article/details/109249418

由高通9531芯片规格书可知,芯片对应的GPIO有18个GPIO0-17,下图是规格书定义。下面以SKYLAB的SKW99模块为例进行说明。

SKYLAB的SKW99模块使用源码为QSDK,GPIO0-3默认为JTAG功能,GPIO9和10为uart串口,剩下的GPIO11-16为默认为灯的功能,GPIO17为WPS按键功能。

GPIO11-17对应功能源码地址为:

qsdk/target/linux/ar71xx/files/arch/mips/ath79/mach-ap147.c
下面以在固件中控制GPIO0进行讲述说明,固件中需要有io工具:

1、将GPIO1转为GPIO功能:

下面是芯片规格书中关于GPIO0-3功能的定义:对应寄存器的地址为0x1804006C

读取寄存器0x1804006C寄存器的值:

root@OpenWrt:~# io -4 0x1804006C
1804006c: 00000020
root@OpenWrt:~#
高通规格书,没有详细介绍bit1值对应的功能,根据实践:

默认0,对应jtag(默认),1对应的是GPIO功能。

将bit1设置为1,则对应寄存器的值应设置为0x00000022

root@OpenWrt:/# io -4 0x1804006c 0x00000022 //写寄存器值
root@OpenWrt:/#
root@OpenWrt:/# io -4 0x1804006c //读寄存器值
1804006c: 00000022
root@OpenWrt:/#
2、对GPIO1进行操作

步骤如下:

(1)先注册GPIO1

root@OpenWrt:/# echo 1 > /sys/class/gpio/export
root@OpenWrt:/#
root@OpenWrt:/# echo out > /sys/class/gpio/gpio1/direction
root@OpenWrt:/#
(2)查看系统GPIO的状态

root@OpenWrt:/# cat /sys/kernel/debug/gpio
GPIOs 0-17, ath79:
gpio-0 (sysfs ) out lo
gpio-1 (sysfs ) out lo
gpio-13 (sysfs ) out hi
gpio-17 (WPS button ) in hi
root@OpenWrt:/#
(3)对GPIO1进行拉高操作

(4)对GPIO1进行拉低操作

同理Link1灯GPIO16的操作控制如下:寄存器为0x1804003C,bit0-bit7对应GPIO16.

 

============== End

 

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

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

相关文章

开源化验单智能识别:思通数科AI平台引领医疗数据处理新变革

智能化验单识别系统在医疗数据管理中的应用意义体现在多个方面,包括提高数据录入效率、减少人为错误、优化患者体验,以及为医疗研究提供高质量数据支持。以下是智能化验单识别系统在医疗数据高效管理中的主要应用意义:提升数据录入效率,减轻医护人员负担传统的化验单录入多…

关于栈

关于栈栈的图一.什么是堆栈平衡(比较抽象)含义就是 当函数在一步步执行的时候 一直到ret执行之前,堆栈栈顶的地址 一定要是call指令的下一个地址。 也就是说函数执行前一直到函数执行结束,函数里面的堆栈是要保持不变的。 如果堆栈变化了,那么,要在ret执行前将堆栈恢复成原…

简单谈谈Google TPUv6

简单谈谈Google TPUv6 根据Google TPU第六代的数据做了一些性能数据的对比,需要注意的是TPUv6当前应该是一个用于训推一体的单Die的版本,用于训练的V6p双Die版本应该会后期再发布. 需要注意的是在国内外都开始卷大模型推理价格的时候, TPU这样的东西对于提高ROI非常有帮助。快…

GNU编译器(GCC)原理简介

GNU编译器(GCC)原理简介GNU编译器(GCC, GNU Compiler Collection)是GNU工具链的关键组件,与GNU、Linux相关项目的标准编译器。它设计之初仅用来处理C语言的(也被称为GNU C编译器),紧接着扩展到C++、Objective-C/C++、Fortran、Java、Go等编程语言。 目前,GCC已经被以知…

22207130-叶盛东-Java大作业总结

Java大作业总结 目录Java大作业总结一.前言第一次作业1.设计与分析第一小题第二小题第三小题第四小题第五小题2.踩坑心得3.改进建议第二次作业1.设计与分析第一小题第二小题第三小题第四小题2.踩坑心得3.改进建议第三次作业1.设计与分析第一小题第二小题第三小题2.踩坑心得3.改…

基于ESP32的桌面小屏幕实战[1]:需求分析与方案选型

项目来源:B站小智学长 1. 需求分析看时间:可联网同步时间;有屏幕 看天气:可联网同步天气;有屏幕 记单词:可联网同步单词;有屏幕 番茄工作时钟:可以手机设置工作、休息时间;有屏幕 获取B站粉丝数: 看室内温湿度:有温湿度传感器;有屏幕 可放入口袋:1-2寸屏幕;带电池…

利用samtools flagstat 对bam文件统计比对率的时候看的是哪个mapping rate

001、 在samtools flagstat 对bam的统计结果中,一共有三个比对率的结果: 002、比对率结果应该以哪个为准? 答案是:以3为准003、以山羊、绵羊的fastq数据,绵羊的参考基因组进行比对测试 a、如果以primary mapped对比,基本看不出两者的差异(其中S是sheep,G是goat) b、…

CPU 计算时延分析

CPU 计算时延 CPU(中央处理器)是计算机的核心组件,其性能对计算机系统的整体性能有着重要影响。CPU 计算时延是指从指令发出到完成整个指令操作所需的时间。理解 CPU 的计算时延对于优化计算性能和设计高效的计算系统至关重要。 1. CPU 计算时延的组成 CPU 计算时延主要由以…

Windows 记录一次磁盘相关的PC卡顿问题

我的电脑最近经常抽疯,时不时卡顿一次 检查系统事件日志,会有这俩个:发出了对设备 \Device\RaidPort0 的重置。 已在磁盘 0 (PDO 名称: \Device\0000003a)的逻辑块地址 0x7206a8 处重试 IO 操作。DiskGenis检查磁盘0,是正常的:这个FASPEED硬盘是国产士必得牌子的。京东商城…

RF/射频器件: CMD246C4 CMD235C4 CMD236C4 CMD254C3 CMD299K4 CMD262 一款5 W GaN MMIC功率放大器芯片

CMD254C3是一款高IP3双平衡混频器,采用无引脚表贴封装,可用于11 GHz至20 GHz的上变频和下变频应用。CMD246C4是一款宽带GaAs MMIC低相位噪声放大器,采用无引脚表贴封装,非常适合军事、航天和通信系统。16 GHz时,该器件提供17 dB的增益,饱和输出功率为+18 dBm,噪声系数为…

记录下使用docker-compose搭建开发环境

目录结构 docker-compose.ymlversion: "3" services:nginx:image: nginx:latestports:- "80:80"volumes:- ./code:/var/www/html- ./nginx/default.conf:/etc/nginx/conf.d/default.confdepends_on:- phpphp:#image: php:8.0-fpm########################…