Skip to main content

SPI

一 相关配置

SPI驱动配置有两种方式,一种直接配置驱动,另外一种可以使用gpio模拟SPI

1.1 spi驱动配置

1

1.2 GPIO口模拟SPI驱动

2

1.3 SPI相关demo

3

1.4 驱动相关配置

4

5

1.5 kernel相关配置

取消勾选红框框中的配置

6

二 SPI调试

相关源码见libhardware2/src/cmds/spi_main.c

2.1 shell命令

cmd_spi info <dev_path>
功能:获取spi设备的传输配置信息
参数:dev_path //spi设备节点的路径
example:
cmd_spi info /dev/spidev0.0
cmd_spi set <dev_path> <arg>[arg...]
功能:设置spi设备传输的配置信息
参数:dev_path //spi设备节点的路径
arg /*配置参数(至少配置一项)
mode=(传输模式)
speed=(传输速度)
lsb=(数据低位发送顺序,0表示低位在后,1表示低位在前)
bits=(数据每次传输的位数)*/
example:
cmd_spi set /dev/spidev0.0 mode=0x01 speed=5000000 lsb=0 bits=8
cmd_spi transfer <dev_path> <data0>[data...]
功能:SPI传输(收发)
参数:dev_path //spi设备节点路径
<data0>[data...] //数据(单位:16进制)
example:
cmd_spi transfer /dev/spidev0.0 0x01 0x02 0x03 0x05 0x05
cmd_spi write <dev_path> <data0>[data...]
功能:SPI传输(只发不收)
参数:dev_path //spi设备节点路径
<data0>[data...] //数据(单位:16进制)
example:
cmd_spi write /dev/spidev0.0 0x01 0x02 0x03 0x05 0x05
cmd_spi read <dev_path> <len>
功能:SPI传输(只收不发)
参数:dev_path //spi设备节点路径
len //要接收的长度
example:
cmd_spi read /dev/spidev0.0 10
cmd_spi add_dev <busnum> <cs_gpio>
功能:添加一个spi设备到spi总线上,生成/dev/spidev节点
参数:busnum //要挂载的spi总线号
cs_gpio //该设备的片选引脚
example:
cmd_spi add_dev 0 pc26
cmd_spi del_dev <dev_path>
功能:删除已有的spi设备
参数:dev_path //spi设备节点路径
example:
cmd_spi del_dev /dev/spidev0.0

2.2 示例

测试为SPI的自发自收传输实验,在进行测试前确保SSI0_DT(发送)和SSI0_DR(接收)引脚已经用杜邦线进行连接

*#使用cmd_spi add_dev命令进行spi设备的添加*
1.cmd_spi add_dev 0 pb00 *#0:spi总线号 pb00:片选引脚*
/dev/spidev0.0

*#使用cmd_spi transfer进行5个字节的数据传输实验*
2.cmd_spi transfer /dev/spidev0.0 0x00 0x01 0x02 0x03 0x04
receive[0]: 00
receive[1]: 01
receive[2]: 02
receive[3]: 03
receive[4]: 04
*#数据接收缓冲区能正确接收到发送的数据,说明spi数据传输成功*

*#使用cmd_spi set对spi设备属性设置,并且用cmd_spi info查看是否设置成功*
3.cmd_spi set /dev/spidev0.0 mode=0x03 speed=500000 bits=8 lsb=0

4.cmd_spi info /dev/spidev0.0
mode speed bits lsb
03 500000 8 0

*#使用cmd_spi del_dev删除指定spi设备*
5.cmd_spi del_dev /dev/spidev0.0

三 SPI应用接口分析

相关源码见libhardware2/src/lib/spi/spi.c

3.1 API详细介绍

int spi_open(char *spi_dev_path)
功能:获取spi设备句柄
参数:spi_dev_path //spi设备路径,如/dev/spidev0.0
返回值:成功:spi设备句柄
失败:-1
void spi_close(int spi_fd)
功能:关闭spi设备
参数:spi_fd //spi设备句柄,通过spi_open获得
返回值:无
int spi_transfer(int spi_fd, struct spi_ioc_transfer *spi_tr, int num)
功能:spi设备数据传输(同时发送和接收)
参数:spi_fd //spi设备句柄,通过spi_open获得
spi_tr //spi设备传输需要配置的结构体,详见中间参数详解
num //传输结构体的个数
返回值:成功:0
失败:-1
int spi_write(int spi_fd, char *tx_buf, int len)
功能:spi设备数据传输(只发送不接收)
参数:spi_fd //spi设备句柄,通过spi_open获得
tx_buf //要发送数据的缓冲区
len //发送数据的长度(单位:字节)
返回值:成功:0
失败:-1
int spi_read(int spi_fd, char *rx_buf, int len)
功能:spi设备数据传输(只接收不发送)
参数:spi_fd //spi设备句柄,通过spi_open获得
rx_buf //接收数据的缓冲区
len //接收的长度(单位:字节)
返回值:成功:0
失败:-1
int spi_set_mode(int spi_fd, int mode)
功能:设置spi传输时的模式
参数:spi_fd //spi设备句柄,通过spi_open获得
mode //传输时的模式
返回值:成功:0
失败:-1
int spi_set_speed(int spi_fd, int speed)
功能:设置spi传输时的模式
参数:spi_fd //spi设备句柄,通过spi_open获得
speed //传输时的速度
返回值:成功:0
失败:-1
int spi_set_bits(int spi_fd, int bits_per_word)
功能:设置spi传输时的位数
参数:spi_fd //spi设备句柄,通过spi_open获得
bits_per_word //传输时的位数
返回值:成功:0
失败:-1
int spi_set_lsb(int spi_fd, int lsb_first)
功能:设置spi传输时数据的高低位发送顺序
参数:spi_fd //spi设备句柄,通过spi_open获得
lsb_first //1表示低位在前,0表示高位在前
返回值:成功:0
失败:-1
void spi_get_info(int spi_fd, struct spi_info *spi)
功能:获取spi传输的配置信息
参数:spi_fd //spi设备句柄,通过spi_open获得
spi //存放信息的结构体,详见中间参数详解
返回值:成功:0
失败:-1
int spi_add_device(struct spidev_register_data *data)
功能:添加一个spi设备
参数:data //注册添加一个spi设备需要准备的结构体,详见中间参数详解
返回值:成功:0
失败:-1
int spi_del_device(char *spidev_path)
功能:删除一个spi设备
参数:spidev_path //设备节点的路径,如:/dev/spidev0.0
返回值:成功:0
失败:-1

中间参数详解:

/*linux kernel定义的spi传输结构体*/
struct spi_ioc_transfer {
__u64 tx_buf; //unsigned long型,写数据缓冲区
__u64 rx_buf; //unsigned long型,读数据缓冲区
__u32 len; //unsigned int 型,读写长度
__u32 speed_hz; //unsigned int 型,通信时的时钟频率

__u16 delay_usecs; //unsigned short型,发生在一个spi_ioc_transfer之后的修正延时
__u8 bits_per_word; //char型,字长(比特数)
__u8 cs_change; /*char型,该transfer传输完毕后是否要非使能cs引脚。
通常在该设备的最后一个transfer置位*/
__u8 tx_nbits; //定义几线发送(1、2、4线可选)。0默认单线传输
__u8 rx_nbits; //定义几线接收(1、2、 4线可选)。0默认单线传输
__u16 pad;
};
/*用来存放spi信息结构体*/
struct spi_info {
unsigned char spi_mode; //spi传输模式
unsigned int spi_speed; //spi传输速度
unsigned char spi_bits; //spi传输位数
unsigned char spi_lsb; //spi传输时数据的高低位发送顺序
};

/*spi_mode在linux kernel内每一位的定义如下:*/
#define SPI_CPHA 0x01 /* 第0位,采样的相位,0为第一个边沿,1为第二个边沿 */
#define SPI_CPOL 0x02 /* 第1位,spi空闲时时钟的相位,0为低电平,1为高电平 */
#define SPI_CS_HIGH 0x04 /* 第2位,置1片选的有效信号是高电平*/
#define SPI_LSB_FIRST 0x08 /*第3位,置1发送时低比特在前*/
#define SPI_3WIRE 0x10 /* 第4位,输入输出信号使用同一根信号线 */
#define SPI_LOOP 0x20 /* 第5位,回环模式 */
#define SPI_NO_CS 0x40 /* 第6位,单个设备占用一个spi总线,无片选,spi传输可只用3根线 */
#define SPI_READY 0x80 /* 第7位,spi传输多一根控制线,从机拉低停止传输 */
/*注册添加一个spi设备准备的结构体*/
struct spidev_register_data {
int busnum; //要挂载的spi总线号
char *cs_gpio; //spi设备使用的片选引脚
char spidev_path[20]; //不需要用户配置,用来存放注册成功后,spi设备节点的路径
};