首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SPI驱动程序

SPI驱动程序
EN

Stack Overflow用户
提问于 2017-01-29 16:40:32
回答 1查看 2.1K关注 1票数 3

我正在努力学习如何编写一个基本的SPI驱动程序,下面是我编写的探测函数。

我在这里要做的是为fram(数据表)安装spi设备,并使用spi_sync_transfer()api描述从芯片中获取制造商的id。

当我执行这段代码时,我可以使用逻辑分析器在SPI总线上看到数据,但是我无法使用rx缓冲区读取它。我是不是漏掉了什么?有人能帮我吗?

代码语言:javascript
复制
static int fram_probe(struct spi_device *spi)
{
    int err;
    unsigned char ch16[] = {0x9F,0x00,0x00,0x00};// 0x9F => 10011111
    unsigned char rx16[] = {0x00,0x00,0x00,0x00};

    printk("[FRAM DRIVER] fram_probe called \n");

    spi->max_speed_hz = 1000000;
    spi->bits_per_word = 8;
    spi->mode = (3);

    err = spi_setup(spi);
        if (err < 0) {
            printk("[FRAM DRIVER::fram_probe spi_setup failed!\n");
            return err;
        }
    printk("[FRAM DRIVER] spi_setup ok, cs: %d\n", spi->chip_select);
    spi_element[0].tx_buf = ch16;
    spi_element[1].rx_buf = rx16;

    err = spi_sync_transfer(spi, spi_element, ARRAY_SIZE(spi_element)/2);
    printk("rx16=%x %x %x %x\n",rx16[0],rx16[1],rx16[2],rx16[3]);

    if (err < 0) {
        printk("[FRAM DRIVER]::fram_probe spi_sync_transfer failed!\n");
        return err;
    }

    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-29 19:18:58

本例中没有声明spi_element。您应该展示这一点,以及如何填充数组中的所有元素。但从代码中我看到了一些错误。

您需要设置len参数的spi_transfer。您已经将TX或RX缓冲区分配给了ch16rx16,但在这两种情况下都没有设置缓冲区的长度。

您应该将spi_transfer中未使用的所有字段归零。

如果将长度设置为4,则不会根据数据表发送正确的命令。RDID期望有一个字节的命令,然后是四个字节的输出数据。您正在第一次传输中编写一个四字节的命令,然后读取四个字节的数据。第一次传输中的tx_buf应该是一个字节。

最后,指定为spi_sync_transfer()的最后一个参数的传输数是不正确的。在本例中应该是2,因为您已经定义了两个,spi_element[0]spi_element[1]。如果为此消息的目的声明了ARRAY_SIZE(),并且希望发送数组中的所有传输,则可以使用spi_element。

将此视为更好地填写spi_transfers的一种方法。它将负责对未使用的字段进行零化,以一种易于看到的方式定义传输,并在剩余代码中自动计算缓冲区大小或传输数量。

代码语言:javascript
复制
const char ch16[] = { 0x8f };
char rx16[4];
struct spi_transfer rdid[] = {
    { .tx_buf = ch16, .len = sizeof(ch16) },
    { .rx_buf = rx16, .len = sizeof(rx16) },
};
spi_transfer(spi, rdid, ARRAY_SIZE(rdid));

由于您有一个范围,请确保此操作发生在单个芯片选择脉冲下。我发现不止一个Linux驱动程序有一个错误,当它不应该的时候,脉冲芯片会选择它。在某些情况下,从TX切换到RX (如上面所做的)将触发CS脉冲。在其他情况下,为数据的每一个字(此处8位)产生CS脉冲。

您应该更改的另一件事是使用dev_info(&spi->dev, "device version %d", id)'dev_err()打印消息。这将以标准方式插入设备名称,而不是硬编码、非标准和不一致的“框架驱动程序:”文本。并酌情设置消息的级别。

此外,考虑在驱动程序中支持设备树来读取设备属性。然后,您可以为该设备更改SPI总线频率,而无需重新构建内核驱动程序。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41923285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档