spi读写分析

本文详细分析了SPI设备的读写过程,包括`spi_write_then_read`函数的内部逻辑,如何设置传输参数,以及如何通过`spi_message`和`spi_transfer`结构进行数据传输。同时,文章还探讨了`spi_sync`函数的工作原理,以及在中断服务程序中如何处理数据的发送和接收。此外,文章还介绍了`spidev`的写操作,如何通过`spidev_sync_write`函数将数据发送到SPI设备。整个过程涉及到的任务转换、数据缓冲和中断处理机制是理解SPI通信的关键。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.spi_write_then_read

static int s3c24xx_spi_setupxfer(struct spi_device *spi,  

                 struct spi_transfer *t)  

{  

    /*设置了每字长的位数,发送速度*/  

    bpw = t ? t->bits_per_word : spi->bits_per_word;  

    hz  = t ? t->speed_hz : spi->max_speed_hz;  

  

    /*分频值*/  

    div = clk_get_rate(hw->clk) / hz;  

}  


int spi_write_then_read(struct spi_device *spi,

                const u8 *txbuf, unsigned n_tx,

                u8 *rxbuf, unsigned n_rx)

{

        static DECLARE_MUTEX(lock);

        int                     status;

        struct spi_message      message;

        struct spi_transfer     x[2];

        u8                      *local_buf;

     /* 这里初始化message结构里面用于存放struct spi_transfer指针的链表头 */

        spi_message_init(&message);//INIT_LIST_HEAD(&message->transfers);

        memset(x, 0, sizeof x);

     /* 留意到没有:tx和rx个占一个工作添加到message的struct spi_transfer链表里,稍后被bitbang_work从链表里提出来处理*/

        if (n_tx) {

                x[0].len = n_tx;

                spi_message_add_tail(&x[0], &message);//list_add_tail(&t->transfer_list, &m->transfers);

        }

        if (n_rx) {

                x[1].len = n_rx;

                spi_message_add_tail(&x[1], &message);

        }

        /* ... unless someone else is using the pre-allocated buffer */

                local_buf = buf;//采用预分配的缓存吧

        /* local_buf的前部分用来存放要发送的数据,后部分用来存放接收到的数据 */

        memcpy(local_buf, txbuf, n_tx);

        x[0].tx_buf = local_buf;

        x[1].rx_buf = local_buf + n_tx;

        /* do the i/o */

        status = spi_sync(spi, &message);//同步io,等待spi传输完成,然后返回用户所接收的数据和状态

}

int spi_sync(struct spi_device *spi, struct spi_message *message)

{

        DECLARE_COMPLETION_ONSTACK(done);//声明一个完成变量

        int status;

        message->complete = spi_complete;//spi传输完成后的回调函数

        message->context = &done;

        status = spi_async(spi, message);

        if (status == 0)

                wait_for_completion(&done);//等待spi传输,调用spi_complete后返回

}

static inline int

spi_async(struct spi_device *spi, struct spi_message *message)

{

        message->spi = spi;

        return spi->master->transfer(spi, message);//调用spi_bitbang_transfer传输数据

}


int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m)

{

        struct spi_bitbang      *bitbang;

        unsigned long           flags;

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值