Linux驱动开发20-SPI子系统分析
Posted hntea-hong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux驱动开发20-SPI子系统分析相关的知识,希望对你有一定的参考价值。
SPI总线
基础概念:
SPI(Serial Peripheral Interface,串行外围设备接口)总线,串行 主-从接口;很多集成与微控制器内部。
四线制,全双共模式,速度达到几兆,四线分别为:
SCLK(Serial Clock):串行时钟
CS(Chip Select):片选,有些写着SS
MISO(Master In Slave out):主设备输入,从设备输出
MOSI(Master Out Slave in):主设备输出,从设备输入
架构图解:
数据传输过程:
主节点通过 MOSI 线输出数据,从节点在 SIMO 处从主节点读取数据。同时,也在通过 SOMI 输出 MSB(最高位),主节点会在 MISO处读取从节点的数据,整个过程将一直持续,直至交换完所有数据;也就是所主从实现数据交换既为一次传输过程
总线时序:
CPOL极性:决定时钟空闲时为高电平还是低电平
CPOL=0:CLK空闲时是低电平,CLK有效时是高电平
CPOL=1: CLK空闲时是高电平,CLK有效时是低电平
决定何时进行数据采样(读取)
CPHA=0:第一个时钟的上升沿采样
CPHA=1:第一个时钟的下降沿采样
根据CPOL和CPHA的不同组合,SPI被分为4种模式
SPI0传输时序
TQ210 SPI控制器编程步骤:芯片手册900页
Linux SPI总线子系统
架构
1. SPI核心
SPI控制器驱动和设备驱动之间的纽带,它提供了SPI控制器驱动和设备驱动的注册、 注销方法等。
2.SPI控制器驱动
对 SPI控制器的驱动实现。
3. SPI设备驱动
对 SPI从设备的驱动实现。
典型客户驱动程序:
1、向SPI核心注册设备驱动:如在prob 函数中:
#include<linux/spi/spi.h>
static struct spi_driver my_spidriver =
.driver =
.name = “myspi”,
.bus = &spi_bus_type,
.owner = THIS_MODULE,
.prob = myspidevice_prob,
.remove = _devexit_p(myspidevice_remove),
;
spi_register_driver(my_spidriver ); /*向SPI核心注册,在SPI总线挂载驱动*/
SPI核心创建对应于此设备的spi_device 结构,当调用注册的驱动方法时,将此结构作为调用参数。
2、数据传输结构
* I/O INTERFACE between SPI controller and protocol drivers
* Protocol drivers use a queue of spi_messages, each transferring data
* between the controller and memory buffers.
struct spi_transfer
* struct spi_message - one multi-segment SPI transaction
struct spi_message
关系图解:
3、SPI消息构造
a、spi_message_init(struct spi_message *m) /*分配一条消息空间,并初始化 链表头*/
b、spi_message_add_tail(struct spi_transfer *t, struct spi_message *m) /*将数据加入链表*/
4、数据通讯
spi_sync():等待操作完成
spi_async():当数据传输完成时,异步触发对注册的回调程序的调用,如SPI中断处理函数、sysf方法或者定时器处理程序
5、SPI数据传输例子
#include<linux/spi/spi.h>
struct spi_device *spi;
struct spi_transfer *t;
struct spi_message sm;
unsigned char *command_buff; /*数据传输空间*/
int len; /*数据长度*/
/*1、初始化SPI消息链表*/
spi_message_init(&sm);
/*2、填充传输数据*/
t.tx_buf = command_buff;
t.len = len;
/*3、把传输数据加入SPI消息队列*/
spi_message_add_tail(t, &sm);
/*4、阻塞请求传输,将数据提交给SPI控制器*/
spi_sync(spi,&sm);
SPI控制器驱动:spi_s3c64xx.c,移植和I2C类似,不过这次比较简单,将内核配置,选择64XX的SPI驱动就行了
平台型驱动,控制器初始化在捕获函数中进行,数据传输在中断中进行,桥接控制器和设备的数据结构,平台资源初始化对应在:dev-spi.c文件中,和6410使用同一个驱动
struct s3c24xx_spi
/* bitbang has to be first */
struct spi_bitbang bitbang;
struct completion done;
void __iomem *regs;
int irq;
int len;
int count;
struct fiq_handler fiq_handler;
enum spi_fiq_mode fiq_mode;
unsigned char fiq_inuse;
unsigned char fiq_claimed;
void (*set_cs)(struct s3c2410_spi_info *spi,
int cs, int pol);
/* data buffers */
const unsigned char *tx;
unsigned char *rx;
struct clk *clk;
struct resource *ioarea;
struct spi_master *master;
struct spi_device *curdev;
struct device *dev;
struct s3c2410_spi_info *pdata;
;
SPI控制器和SPI设备驱动的函数联系
(国嵌入图)
以上是关于Linux驱动开发20-SPI子系统分析的主要内容,如果未能解决你的问题,请参考以下文章