SPI 学习总结
来源:互联网 发布:设计图纸软件下载 编辑:程序博客网 时间:2024/06/02 00:58
1. SPI 简介
SPI (Serial Peripheral interface)串行外围设备接口,是Motorola首先在其MC68HCXX系列处理器上定义的。
SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。
SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便。
SPI的四根线为SDI(数据输入),SDO(数据输出),SCLK(时钟),CS(片选)。
可以参考 drivers/spi 目录。
spi_device的板信息用spi_board_info结构体来描述:
struct spi_board_info {
char modalias[SPI_NAME_SIZE];
const void *platform_data;
void *controller_data;
int irq;
u32 max_speed_hz;
u16 bus_num;
u16 chip_select;
u8 mode;
};
记录了SPI外设使用的主机控制器序号、片选信号、数据比特率、SPI传输方式等
static struct mcp251x_platform_data mcp251x_info = {
.oscillator_frequency = 20*1000*1000, /*外部晶振,结合手册及具体硬件设置*/
.board_specific_setup = NULL,
.power_enable = NULL,
.transceiver_enable = NULL,
};
CS用gpio替换
static struct pxa2xx_spi_chip qrk_ffrd_spi_cs_mcp251x = {
.gpio_cs = 9,/*GPIO号*/
};
{
.modalias = "mcp2515",
.platform_data = &mcp251x_info,
.mode = SPI_MODE_0,
.irq = 58,
.max_speed_hz = 2*1000*1000, /* max sample rate at 3V */
.bus_num = 0,
.chip_select = 1,
.controller_data = &qrk_ffrd_spi_cs_mcp251x,
}
spi_register_board_info(spi_devs, ARRAY_SIZE(spi_devs));
MOSI(SDO):主器件数据输出,从器件数据输入。
MISO(SDI):主器件数据输入,从器件数据输出。
SCLK :时钟信号,由主器件产生。
CS:从器件使能信号,由主器件控制(可以使用GPIO来替换)。
SPI是串行通讯协议,也就是说数据是一位一位从MSB或者LSB开始传输的,这就是SCK时钟线存在的原因,由SCK提供时钟脉冲,MISO、MOSI则基于此脉冲完成数据传输。 SPI支持4-32bits的串行数据传输,支持MSB和LSB,每次数据传输时当从设备的大小端发生变化时需要重新设置SPI Master的大小端。
2 SPI 驱动架构
SPI的驱动架构分为三个层次:SPI 核心、SPI控制器驱动和SPI设备驱动。
SPI核心:
主要提供了核心数据结构的定义、SPI控制器驱动和设备驱动的注册、注销管理等的API接口。
SPI控制器驱动:
每种平台都有自己的控制器,可参考处理器手册移植。其功能是为每条SPI总线实现读写方法,向下连接SPI从设备。
在include/liunx/spi/spi.h文件中,在数据结构struct spi_master定义如下:
struct spi_master {
struct device dev;
s16 bus_num;
u16 num_chipselect;
int (*setup)(struct spi_device *spi);
int (*transfer)(struct spi_device *spi, struct spi_message *mesg);
void (*cleanup)(struct spi_device *spi);
};
bus_num 对应的SPI总线号。
num_chipselect 能支持的spi设备个数
setup 设置SPI总线的模式,时钟等的初始化函数,在spi_add_device函数中调用。
transfer 函数是实现SPI总线读写方法的函数。实现数据的双向传输.
cleanup 注销时候调用
SPI设备驱动:
为应用层提供通过SPI总线访问设备的接口。
使用到两个模块来实现。
1. struct spi_driver 注册扫描SPI总线上的设备,通过probe来匹配对应的设备并进行初始化设备。
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的slave驱动。
2. struct spi_device 的构建与注册
struct spi_device {
struct device dev;
struct spi_master *master;
u32 max_speed_hz;
u8 chip_select;
u8 mode;
u8 bits_per_word;
int irq;
void *controller_state;
void *controller_data;
char modalias[32];
};
spi_device 对应于特定的从设备,并且spi_device 封装了一个spi_master结构体。
spi_device 的赋值在platform文件中完成。
以设备mcp2515,spi转CAN为例:
mcp2515从设备平台信息
static struct spi_board_info spi_devs[]={
};
在platform的init函数中调用.
注册把spi_board_info注册到board_list.在spi_master注册中调用scan_boardinfo扫描board_list并匹配设备,然后创建并注册spi_deivce.
参考:
http://www.cnblogs.com/liugf05/archive/2012/12/03/2800457.html
- SPI学习总结
- SPI 学习总结
- SPI通信协议学习总结
- I2C和SPI学习总结
- STM32 SPI 自我学习总结 不断更新中
- TMS320F28335学习SPI模块总结笔记
- IIC与SPI学习总结 未完待续
- UART、I2C以及SPI协议学习总结
- [FatFs 学习] SD卡总结-SPI模式
- SPI总结
- SPI 总结
- 【总结】SPI
- SPI学习
- SPI学习
- @SPI 学习
- SPI学习之:SPI编程
- mini2440 spi驱动总结
- SPI的一些总结
- 用来获取指定类的所有祖先类的名称及其所在的单元名称。
- java连接字符串
- 重新学习C语言的getchar()函数以及某些体会
- Oracle数据库安装图解
- 使用命令行打包apk的过程
- SPI 学习总结
- Dollars+uva+简单dp
- USACO 之 Section 1.2 Complete Search
- ios 单例的写法
- Android数据库高手秘籍——使用LitePal升级表
- LAMP攻略之重新编译PHP安装扩展和GD库安装与配置
- 单片机项目-智能家居与无线组网通信
- vim 经典插件大全
- 创建新的Cocos2d-JS工程