3. spi总线抽象实现
此部分实现源码为:spi_hw.c spi_hw.h
3.1 spi总线抽象API实现
第一步:“spi_send_then_recv”,实现代码如下:
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)
{
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,&message);
message.length = recv_size;
message.send_buf = 0;
message.recv_buf = recv_buff;
message.cs_take = 0;
message.cs_release = 1;
spi_dev->spi_bus->spi_bus_xfer(spi_dev,&message);
return 0;
}
实现的功能是,spi发送完一帧后再接收一帧数据。
1)spi_dev即是传入的设备指针;
2)收发参数主要传递给“spi_dev_message”;
3)对于第一帧“spi_dev_message”,不接收返回值,所以recv_buf设置空(0);此时片选拉低(cs_take=1),发送完还不能拉高片选(cs_release=0),待后面接收帧接收完再拉高片选(cs_release=1),从外设时序图也可以看出;
4)对于第二帧,此时发送数据为空,所以send_buf设置为0,此时的发送动作并非真的发送,只是用来产生接收数据的时钟信号。
第二步:spi_send_then_send,与spi_send_then_recv类似,只是后面的“接收”动作变为“发送”动作,故不作重复分析,源码看附件。
第三步:spi_send_recv,实现代码如下:
int spi_send_recv(struct spi_dev_device *spi_dev,const void *send_buff,void *recv_buff,unsigned short data_size)
{
message.length = data_size;
message.send_buf = send_buff;
message.recv_buf = recv_buff;
message.cs_take = 1;
message.cs_release = 1;
spi_dev->spi_bus->spi_bus_xfer(spi_dev,&message);
return 0;
}
实现功能是发送完同时接收完,或者只接收。
1)spi_dev即是传入的设备指针;
2)收发数据及长度由用户通过形参传入,只接收时,发送数据缓存可设置为空(0);
3)操作前拉低片选(cs_take=1),操作完成片选拉高(cs_release=1);
第四步:spi_send,实现代码如下:
int spi_send(struct spi_dev_device *spi_dev,const void *send_buff,unsigned short send_size)
{
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 = 1;
spi_dev->spi_bus->spi_bus_xfer(spi_dev,&message);
return 0;
}
该函数与spi_send_recv非常类似,但只有“发送”动作,无“接收”动作,故recv_buf设置为空(0)。 |