2024年6月12日发(作者:)
SPI协议是一种同步的串行数据连接标准,由摩托罗拉公司命名,可工作于全双工模式。相
关通讯设备可工作于m/s模式。主设备发起数据帧,允许多个从设备的存在。每个从设备
有独立的片选信号,SPI一般来说是四线串行总线结构。
接口:
SCLK——Serial Clock(output from master)时钟(主设备发出)
MOSI/SIMO——Master Output, Slave Input(output from master)数据信号线mosi(主设备
发出)
MISO/SOMI——Master Input,Slave Outpu(output from slave)数据信号线(从设备)
SS——Slave Select(active low;output from master)片选信号
下面来看一下Linux中的SPI驱动。在Linux设备驱动框架的设计中,有一个重要的主机,
外设驱动框架分离的思想,如下图。
外设a,b,c的驱动与主机控制器A,B,C的驱动不相关,主机控制器驱动不关心外设,而外设
驱动也不关心主机,外设只是访问核心层的通用的API进行数据的传输,主机和外设之间
可以进行任意的组合。如果我们不进行如图的主机和外设分离,外设a,b,c和主机A,B,C进
行组合的时候,需要9种不同的驱动。设想一共有个主机控制器,n个外设,分离的结构是
需要m+n个驱动,不分离则需要m*n个驱动。
下面介绍spi子系统的数据结构:
在Linux中,使用spi_master结构来描述一个SPI主机控制器的驱动。
view plain
1.
2.
3.
4.
5.
6.
struct spi_master {
struct device dev;/*总线编号,从0开始*/
s16 bus_num;/*支持的片选的数量,从设备的片选号不能大于这个数量*/
u16 num_chipselect;
u16 dma_alignment;/*改变spi_device的特性如:传输模式,字长,时钟频率*/
int (*setup)(struct spi_device *spi);/*添加消息到队列的方法,这个函数不可睡眠,他的任务是安排发生的传送
并且调用注册的回调函数complete()*/
7. int (*transfer)(struct spi_device *spi,struct spi_message *mesg);
8.
9.
void (*cleanup)(struct spi_device *spi);
};
分配,注册和注销的SPI主机的API由SPI核心提供:
view plain
1.
2.
3.
struct spi_master *spi_alloc_master(struct device *host, unsigned size);
int spi_register_master(struct spi_master *master);
void spi_unregister_master(struct spi_master *master);
在Linux中用spi_driver来描述一个SPI外设驱动。
view plain
1.
2.
3.
4.
5.
6.
7.
8.
struct spi_driver {
int (*probe)(struct spi_device *spi);
int (*remove)(struct spi_device *spi);
void (*shutdown)(struct spi_device *spi);
int (*suspend)(struct spi_device *spi, pm_message_t mesg);
int (*resume)(struct spi_device *spi);
struct device_driver driver;
};
可以看出,spi_driver结构体和platform_driver结构体有极大的相似性,都有
probe(),remove(),suspend(),resume()这样的接口。
Linux用spi_device来描述一个SPI外设设备。
view plain
1.
2.
3.
4.
5.
6.
7.
8.
9.
struct spi_device {
struct device dev;
struct spi_master *master; //对应的控制器指针u32
max_speed_hz; //spi通信的时钟u8
chip_select; //片选,用于区分同一总线上的不同设备
u8 mode;
#define SPI_CPHA 0x01 /* clock phase */
#define SPI_CPOL 0x02 /* clock polarity */
#define SPI_MODE_0 (0|0) /* (original MicroWire) */#define SPI_MODE_1 (0|SPI_CPHA)
10. #define SPI_MODE_2 (SPI_CPOL|0)
11. #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)#define SPI_CS_HIGH 0x04 /* chipselect active h
igh? */
12. #define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */
13. #define SPI_3WIRE 0x10 /* SI/SO signals shared */
14. #define SPI_LOOP 0x20 /* loopback mode */
15. u8 bits_per_word; //每个字长的比特数
16. int irq; //使用的中断


发布评论