基于硬件 SPI 的数据抽象实例(附代码)
扫描二维码
随时随地手机看文章
1.写在前面
spi(Serial Peripheral Interface)即串行外设接口。与i2c一样,spi也常用外设设备通信的总线,从事嵌入式开发必不可少的掌握。
2.spi总线抽象
此部分实现源码为:spi_core.c spi_core.h
2.1 spi总线模型对外接口(API)
/*extern function*/extern int spi_send_then_recv(struct spi_dev_device *spi_dev,const void *send_buff,
unsigned short send_size,void *recv_buff,unsigned short recv_size);
extern int spi_send_then_send(struct spi_dev_device *spi_dev,const void *send_buff1,
unsigned short send_size1,const void *send_buff2,unsigned short send_size2);
extern int spi_send_recv(struct spi_dev_device *spi_dev,const void *send_buff,void *recv_buff,unsigned short data_size);
extern int spi_send(struct spi_dev_device *spi_dev,const void *send_buff,unsigned short send_size);
1)spi_send_then_recv,标准spi,常规操作,发送完一帧再接收,如读取某芯片寄存器的值;
2.2 spi总线抽象API实现
以“spi_send_then_recv”函数为例:
2.3 struct spi_de_device
该结构体为关键,调用API驱动一个外设时,需要先初始化(类似Linux的注册设备驱动)。一个完整的spi外设,包括片选和总线量部分,一个总线可和多个片选组成,驱动多个外设,因此struct spi_dev_device设计原型为:
{
void (*spi_cs)(unsigned char state);
struct spi_bus_device *spi_bus;
};
1)第一个参数为函数指针,主要功能的实现spi外设片选的选择(拉低/拉高)功能;
2.4 struct spi_bus_device *spi_bus
该结构体为底层硬件相关的spi总线实现,具体由实际需求实现,如用硬件spi还是用模拟spi。struct spi_bus_device*spi_bus原型为:
{
int (*spi_bus_xfer)(struct spi_dev_device *spi_bus,struct spi_dev_message *msg);
void *spi_phy;
unsigned char data_width;
};
1)第一个参数是函数指针,为spi总线收发函数,这部分就是我们平常写裸机代码时候写到的,只是这里把它放在一个结构体里面,以函数指针的方式实现;这样的好处是,上层接口不变,更好其他MCU或者使用模拟spi时,只需修改此部分的函数实体,上层代码不需变动。
2.5 spi_bus_xfer
该函数指针入口参数为spi设备指针(struct spi_dev_device )、spi设备信息帧指针(struct spi_dev_message)。struct spi_dev_device与前面提及的为同一类参数,struct spi_dev_message为收发数据信息帧,其原型如下:
{
const void *send_buf;
void *recv_buf;
int length;
unsigned char cs_take : 1;
unsigned char cs_release : 1;
};
1)send_buf:待发送数据(缓存);
3. spi总线抽象实现
此部分实现源码为:spi_hw.c spi_hw.h
3.1 spi总线抽象API实现
第一步:“spi_send_then_recv”,实现代码如下:
{
struct spi_dev_message message;
message.length = send_size;
message.send_buf = send_buff;
message.recv_buf = 0;
message.cs_take = 1;
message.cs_release = 0;
spi_dev->spi_bus->spi_bus_xfer(spi_dev,