linux+spi通讯同步,和菜鸟一起学linux总线驱动之初识spi驱动数据传输流程

本文深入探讨了Linux系统中SPI(Serial Peripheral Interface)的通信同步,并详细解析了SPI的write、read及8位读写函数的工作流程。通过分析 spi_write、spi_read 和 spi_w8r8 等函数,展示了数据如何在工作队列中传输。同时,文章介绍了如何使用GPIO模拟SPI总线,并详细解释了从设备驱动到GPIO控制器的数据流,包括 spi_bitbang_start 和 spi_bitbang_transfer 的作用。文章特别指出,在16位和32位数据传输中可能存在的大小端问题及其影响。
摘要由CSDN通过智能技术生成

对于SPI的一些结构体都有所了解之后呢,那么再去瞧瞧SPI的那些长见的操作的函数了。

首先看一下本人画的比较挫的数据流了,仅供参考,如有不对,不吝赐教

uid-13059007-id-5766895.html

接下来看看各个函数吧还是:

SPI write

/**

* spi_write - SPI synchronous write

* @spi: device to which data will be written

* @buf: data buffer

* @len: data buffer size

* Context: can sleep

*

* This writes the buffer and returns zero or a negative error code.

* Callable only from contexts that can sleep.

*/

static inline int

spi_write(struct spi_device *spi, const void *buf, size_t len)

{

struct spi_transfer   t= {

.tx_buf=buf,

.len=len,

};

struct spi_message  m;

spi_message_init(&m);

spi_message_add_tail(&t, &m);

return spi_sync(spi, &m);

}

SPI发送函数,数据放在buf中,然后把要发送的数据放在工作队列中

SPI  read

/**

* spi_read - SPI synchronous read

* @spi: device from which data will be read

* @buf: data buffer

* @len: data buffer size

* Context: can sleep

*

* This reads the buffer and returns zero or a negative error code.

* Callable only from contexts that can sleep.

*/

static inline int

spi_read(struct spi_device *spi, void *buf, size_t len)

{

struct spi_transfer   t= {

.rx_buf=buf,

.len=len,

};

struct spi_message  m;

spi_message_init(&m);

spi_message_add_tail(&t, &m);

return spi_sync(spi, &m);

}

SPI接收函数,数据放在buf中,然后把要发送的数据放在工作队列中,发送出去

SPI write 8 bits read 8 bits

/* this copies txbuf and rxbuf data; for small transfers only! */

extern int spi_write_then_read(struct spi_device *spi,

const void *txbuf, unsigned n_tx,

void *rxbuf, unsigned n_rx);

/**

* spi_w8r8 - SPI synchronous 8 bit write followed by 8 bit read

* @spi: device with which data will be exchanged

* @cmd: command to be written before data is read back

* Context: can sleep

*

* This returns the (unsigned) eight bit number returned by the

* device, or else a negative error code.  Callable only from

* contexts that can sleep.

*/

static inline ssize_t spi_w8r8(struct spi_device *spi, u8 cmd)

{

ssize_t                   status;

u8                  result;

status=spi_write_then_read(spi, &cmd, 1, &result, 1);

/* return negative errno or unsigned value */

return (status <0) ? status : result;

}

SPI write 8 bit read 16 bits

/**

* spi_w8r16 - SPI synchronous 8 bit write followed by 16 bit read

* @spi: device with which data will be exchanged

* @cmd: command to be written before data is read back

* Context: can sleep

*

* This returns the (unsigned) sixteen bit number returned by the

* device, or else a negative error code.  Callable only from

* contexts that can sleep.

*

* The number is returned in wire-order, which is at least sometimes

* big-endian.

*/

static inline ssize_t spi_w8r16(struct spi_device *spi, u8 cmd)

{

ssize_t                   status;

u16                result;

status=spi_write_then_read(spi, &cmd, 1, (u8 *) &result, 2);

/* return negative errno or unsigned value */

return (status <0) ? status : result;

}

int spi_write_then_read(struct spi_device *spi,

const void *txbuf, unsigned n_tx,

void *rxbuf, unsigned n_rx)

{

static DEFINE_MUTEX(lock);

int                 status;

struct spi_message  message;

struct spi_transfer   x[2];

u8                  *local_buf;

/* Use preallocated DMA-safe buffer.  We can't avoid copying here,

* (as a pure convenience thing), but we can keep heap costs

* out of the hot path ...

*/

if ((n_tx + n_rx) >SPI_BUFSIZ)

return -EINVAL;

spi_message_init(&message);

memset(x, 0, sizeof x);

if (n_tx) {

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值