加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

int spi_write_then_read (struct spi_device * spi,  const void * txbuf,  unsigned n_tx,  void * r

(2013-10-28 20:24:00)
标签:

杂谈

//发送n_tx个字节的命令到spi从机,并从spi从机中读取n_rx字节的数据到缓冲区

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;

       
        if ((n_tx + n_rx) > SPI_BUFSIZ)//SPI_BUFSIZ == 32
                return -EINVAL;

     
        spi_message_init(&message);//INIT_LIST_HEAD(&message->transfers);
        memset(x, 0, sizeof x);
     
        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);
        }

       
       
        if (down_trylock(&lock)) {
                local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
                if (!local_buf)
                        return -ENOMEM;
        } else
                local_buf = buf;//否则就采用预分配的缓存吧

       
        memcpy(local_buf, txbuf, n_tx);
        x[0].tx_buf = local_buf;
        x[1].rx_buf = local_buf + n_tx;

       
        status = spi_sync(spi, &message);//同步io,等待spi传输完成,然后返回用户所接收的数据和状态
        if (status == 0) {
                memcpy(rxbuf, x[1].rx_buf, n_rx);
                status = message.status;
        }

        if (x[0].tx_buf == buf)//如果使用的是预分配的缓存,释放锁好让其它人使用
                up(&lock);
        else
                kfree(local_buf);//如果使用的是临时申请的缓存,释放之

        return status;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有