首页 > 其他分享 >使用spi-gpio-custom模块配置SPI总线

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

时间:2024-10-26 18:42:04浏览次数:1  
标签:kmod SPI 00000000 custom spi gpio

使用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

 

标签:kmod,SPI,00000000,custom,spi,gpio
From: https://www.cnblogs.com/lsgxeva/p/18504347

相关文章

  • 总结SPI、I2C、UART三者的区别
    1、三者的区别:通信协议硬件连接 总线速度传输方式功能SPI  4线(SCLK\MOSI\MISO\SS) MHz 同步双向、全双工/半双工I2C  2线(SDA\SCL)KHz 同步 多设备总线UART2线(TX\RX) 115200bps异步单向或双向串行    1.硬件连接:SPI使用4线或3线(带主从模式)连接,其中包括......
  • 【Java知识】Java进阶-服务发现机制SPI
    文章目录SPI概述SPI工作原理ServiceLoader代码展示简化的`ServiceLoader`类关键点解释使用示例1.定义服务接口2.实现服务提供者3.配置文件4.加载服务提供者总结SPI使用场景1.数据库驱动2.日志框架3.图像处理4.加密算法5.插件系统6.缓存机制示例代码1.定......
  • Java SPI 机制详解
    原文:JavaSPI机制详解在面向对象的设计原则中,一般推荐模块之间基于接口编程,通常情况下调用方模块是不会感知到被调用方模块的内部具体实现。一旦代码里面涉及具体实现类,就违反了开闭原则。如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候不用在程序里面动态指......
  • 为什么汽车行业用ASPICE的V型开发模型
    随着汽车逐渐转型为移动计算平台,软件的重要性日益突出。ASPICE的V型开发模型为汽车行业提供了一个结构化、可追踪和重复的开发过程,从而确保质量和安全性。关键原因包括:1.明确的需求管理;2.增强的验证与确认;3.有利于协同工作;4.确保质量和可靠性;5.符合行业标准和法规要求。1.明确......
  • SPI的学习
    工作原理SPI的工作原理基于主从架构。主设备通过四条主要信号线与一个或多个从设备进行通信:MOSI(主输出,从输入)DI(MasterOutputSlaveInput):主设备发送数据到从设备。MISO(主输入,从输出)DO(MasterInputSlaveOutput):从设备发送数据到主设备。SCLK(时钟信号):由主设备生成的时钟信号,......
  • 深入解析 Aerospike高性能分布式数据库的利器
    1.Aerospike简介在当今大数据和高并发的时代,传统关系型数据库往往难以满足实时性和扩展性的需求。Aerospike作为一款高性能、低延迟的分布式NoSQL数据库,以其独特的架构和强大的功能,受到了业界的广泛关注。本文将深入探讨Aerospike的核心原理、关键特性、应用场景,以......
  • ssts-hospital-web-master项目实战记录五:环境配置
    记录时间:2024-10-24《.env.development》VITE_APP_ENV=development#VITE_APP_BASE_URL=/apiVITE_APP_BASE_URL=http://127.0.0.1:9000/VITE_APP_ADAPTERSERVICE_URL=http://127.0.0.1:9080/VITE_APP_TERMINALSERVICE_URL=http://localhost:8881/VITE_APP_EZWAREWEBSOCKET......
  • sentinel-SPI初始化时机
    时机一引入alibaba-starter-sentinel如果使用了alibaba-starter-sentinel则不需要手动调用因为com.alibaba.cloud.sentinel.custom.SentinelAutoConfiguration#init在这里面执行了自动调用@PostConstructprivatevoidinit(){if(StringUtils.isEmpty(System.ge......
  • ssts-hospital-web-master项目实战记录四:主要配置
    记录时间:2024-10-231.配置浏览器自动打开配置文件:package.json "scripts":{  "dev":"vite--open" } 2.配置src别名(1)安装@types/node输入npm命令npm i@types/node--save-dev(2)配置文件:vite.config.tsimport{defineConfig}from'vi......
  • ssts-hospital-web-master项目实战记录三:项目开发规范
    记录时间:2024-10-23参考书籍《Vue.js3+TypeScript完全指南》17.3 项目开发规范 在企业项目开发中,通常由多人一起协作完成开发任务,每个人编写的代码风格可能不统一。为了避免出现问题,一般会制定一些规范来约束整个项目的编码风格,包括编辑器规范、代码格式规范、编写代码......