本文主要记录飞腾平台SPI接口验证方法,主要对SPI接口进行简单介绍,同时提供一种系统下测试该接口的方法指导。
一、SPI接口简介
SPI是一种同步、全双工、主从式接口。来自主机或从机的数据在时钟上升沿或下降沿同步。主机和从机可以同时传输数据。本文重点介绍常用的4线SPI接口
数据传输
要开始SPI通信,主机必须发送时钟信号,并通过使能CS信号选择从机。片选通常是低电平有效信号。因此,主机必须在该信号上发送逻辑0以选择从机。SPI是全双工接口,主机和从机可以分别通过MOSI和MISO线路同时发送数据。在SPI通信期间,数据的发送(串行移出到MOSI/SDO总线上)和接收(采样或读入总线(MISO/SDI)上的数据)同时进行。串行时钟沿同步数据的移位和采样。SPI接口允许用户灵活选择时钟的上升沿或下降沿来采样和/或移位数据。欲确定使用SPI接口传输的数据位数,可以参考《飞腾芯片系类软件编程手册》
时钟极性和时钟相位
*在SPI中,主机可以选择时钟极性和时钟相位。在空闲状态期间,CPOL位设置时钟信号的极性。空闲状态是指传输开始时CS为高电平且在向低电平转变的期间,以及传输结束时CS为低电平且在向高电平转变的期间。CPHA位选择时钟相位。根据CPHA位的状态,使用时钟上升沿或下降沿来采样和/或移位数据。主机必须根据从机的要求选择时钟极性和时钟相位。根据CPOL和CPHA位的选择,有四种SPI模式可用。表1显示了这4种SPI模式。
Mode00
Mode01
Mode10
Mode11
熟悉以上几种工作模式后即可大致理解SPI协议的工作原理,下面开始介绍软件的相关情况。
二、软件介绍
在飞腾平台上,SPI接口初始化主要在操作系统层面完成,但是固件(uefi或uboot)需要完成SPI接口引脚的复用关系配置,具体参考《飞腾芯片系类软件编程手册》关于管脚复用配置寄存器,配置复用功能以及管脚上下拉情况。一般来说管脚驱动能力可以不用单独配置,使用默认情况即可。
固件还需要做一个工作就是给操作系统上报SPI总线接口,恰好在uefi的ACPI表中可以找到一个Spi.asl的接口描述表。在下文源码中添加了SPI0的接口描述,SPI1可以仿照自行添加。需要注意是情况是由于历史原因,麒麟系统使用的SPI的_HID 是PHTY000E, 但是飞腾官网描述的是PHYT000E,这一点看后期如何与操作系统协商统一。
在源码中,我修改了部分描述,为了支持更多的功能,其中添加了SPT0001,用于系统下创建一个spidev设备,便于软件测试,另外创建了一个TPM的设备描述,可用于TPM设备验证。这些描述都需要系统下提供相关的驱动支持才可实现接口应用。
Scope(_SB)
{
Device(SPI0) {
Name(_HID, "PHTY000E")
Name(_UID, 0)
Name(_CRS, ResourceTemplate() {
GpioIo(Exclusive, PullUp, 0, 0, IoRestrictionNone,"\\_SB.GPI1", 0, ResourceConsumer, , ) { 5 }
Memory32Fixed(ReadWrite, 0x2800c000, 0x1000)
Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) {50}
})
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"reg-io-width", 4},
Package() {"clocks", Package () {"\\_SB.CLK2"}},
Package() {"clocks-spi", 600000000},
Package() {"num-cs", 4},
Package() {"cs-gpios", Package () {
^SPI0, 0, 0, 0,
},
},
}
})
Device(FLAS) {
Name(_HID, "SPT0001")
Name(_UID, 0)
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"reg",0},
Package() {"spi-max-frequency", 48000000}
}
})
Name(_CRS, ResourceTemplate () {
// Index 0
SPISerialBus ( // SCKL - GPIO 11 - Pin 23
// MOSI - GPIO 10 - Pin 19
// MISO - GPIO 9 - Pin 21
// CE0 - GPIO 8 - Pin 24
0, // Device selection (CE0)
PolarityLow, // Device selection polarity
FourWireMode, // WireMode
8, // DataBit len
ControllerInitiated, // Slave mode
4000000, // Connection speed
ClockPolarityLow, // Clock polarity
ClockPhaseFirst, // Clock phase
"\\_SB.SPI0", // ResourceSource: SPI bus controller name
0, // ResourceSourceIndex
// Resource usage
// DescriptorName: creates name for offset of resource descriptor
) // Vendor Data
})
}
Device(TPM) {
Name(_ADR, 0)
Name (_CID, Package() {
"SMO0768",
})
Name(_UID, 0)
Name(_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
}
})
Method(_CRS, 0x0, NotSerialized) {
Name (RBUF, ResourceTemplate () {
SpiSerialBus (0, PolarityLow, , 8, ControllerInitiated, 1000000, ClockPolarityLow,ClockPhaseFirst, "\\_SB.SPI0", 0x00, ResourceConsumer, , )
})
Return(RBUF)
}
}
}
}
操作系统上需要内核配置SPI驱动,编译到内核中,其中X100-SPI可以不用勾选。
配置完成后,编译生成内核,并启动该内核,即可在系统下看到有/dev/spidev0.0,这个设备存在
接下来即可在系统下使用开源SPI测试软件进行验证与测试。
三、测试软件介绍
在系统下有多种方法可以测试SPI接口,若有真实设备,以及直接与设备通讯,查看设备状态是否正常。若无真实设备,既可以用系统提供的虚拟SPI设备进行验证,下文介绍该测试方法。
方式一:
sudo apt install spi-tools
方式二:
下载源码
wget https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/spi-tools/0.8.4-1/spi-tools_0.8.4.orig.tar.gz
解压与编译
tar -xf spi-tools_0.8.4.orig.tar.gz
cd spi-tools
cd spi-tools-0.8.4/
autoreconf -fim
./configure
make
安装
make install
验证
spi-config -d /dev/spidev0.0 -q
更多spi-config命令介绍:
-d, --device=DEVICE :使用指定的 spidev 字符设备
-q, --query :打印当前的配置
-m, --mode=[0-3] :设置 SPI 模式
-l, --lsb={0,1} :设置数据传输方式为 LSB first (1) 或者 MSB first (0)
-b, --bits=[7...] :设置每个字(word)的位数
-s, --speed=FREQUENCY :设置时钟频率(单位 Hz)
-r, --spirdy={0,1} :设置 SPI READY 模式标志
-s, --wait :阻塞,保持文件描述符打开
-h, --help :查看帮助并退出
-v, --version :查看版本信息并退出
发表评论