免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7302 | 回复: 1
打印 上一主题 下一主题

求指点!修改使用spidev源码时发现spi_read/spi_write接口没用?! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-28 15:18 |只看该作者 |倒序浏览
本帖最后由 acrazyworld 于 2012-03-28 15:19 编辑

在下使用的是tq2440开发板,linux2.6.30。正在使用spi0驱动一个RF模块,本人没有用iomap的方法直接配置spi寄存器,而是想利用linux自己的spi驱动体系来编写设备驱动。
(1)已经在加上了spi0总线,在/sys/device/platform/下有了s3c2410-spi0目录。
(2)将spidev.h,spidev.c抠出来加以修改,编译.ko驱动模块,insmod模块。然后连接MISO-MOSI,在测试的应用程序中使用 ioctl (fd, SPI_IOC_MESSAGE (1), &tr)进行IO同步的方法可以读写数据。应用层的测试代码:
static void
transfer (int fd)
{
  int ret;
  uint8_t tx[] = {
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
    0xF0, 0x0D,
  };
  uint8_t rx[ARRAY_SIZE (tx)] = { 0, };
  struct spi_ioc_transfer tr = {
    .tx_buf = (unsigned long) tx,
    .rx_buf = (unsigned long) rx,
    .len = ARRAY_SIZE (tx),
    .delay_usecs = delay,
    .speed_hz = speed,
    .bits_per_word = bits,
  };

  ret = ioctl (fd, SPI_IOC_MESSAGE (1), &tr);
  if (ret == 1)
    pabort ("can't send spi message");

  for (ret = 0; ret < ARRAY_SIZE (tx); ret++)
    {
      if (!(ret % 6))
        puts ("");
      printf ("%.2X ", rx[ret]);
    }
  puts ("");
}


(3)问题来了!为了在内核使用spi_read,spi_write等接口,我在spidev_probe中加入其测试代码后发现spi_read,spi_write根本没有读写成功!spidev.c添加的测试代码如下:
static int spidev_probe(struct spi_device *spi)
{
。。。省略。。。               
                /*test code*/
                printk("test 3 start!\n");
                if(spi_write(spidev->spi,tx_buf,8)< 0){
                        printk("spi_write write error!\n");
                }
                if(spi_read (spidev->spi,rx_buf,8)){
                        printk("spi_write read error!\n");
                }
                for(i = 0; i < 8; i++){
                        printk("{%2x}\n",rx_buf);
                }
                printk("test 4 start!\n");
                for(i = 0; i < 8; i++){
                        printk("{%2x}\n",spi_w8r8(spidev->spi,i));
                }
                printk("test end!\n");

。。。省略。。。
        return status;
}

小弟就不明白了,由于(2)测试成功,说明spi总线加上了,硬件层的配置也没问题了,而使用probe中传入的spi_device设备在内核进行spi_read,spi_write操作却没有成功?难道是那个地方没有设置的原因?

论坛徽章:
0
2 [报告]
发表于 2012-03-28 15:43 |只看该作者
引用文档spidev
Normal open() and close() operations on /dev/spidevB.D files work as you
would expect.

Standard read() and write() operations are obviously only half-duplex, and
the chipselect is deactivated between those operations.  Full-duplex access,
and composite operation without chipselect de-activation, is available using
the SPI_IOC_MESSAGE(N) request.

传统的read write使用的是半双工模式,需要cs片选;而 SPI_IOC_MESSAGE(N) 方式使用全双工,无须片选。

Several ioctl() requests let your driver read or override the device's current
settings for data transfer parameters:

    SPI_IOC_RD_MODE, SPI_IOC_WR_MODE ... pass a pointer to a byte which will
        return (RD) or assign (WR) the SPI transfer mode.  Use the constants
        SPI_MODE_0..SPI_MODE_3; or if you prefer you can combine SPI_CPOL
        (clock polarity, idle high iff this is set) or SPI_CPHA (clock phase,
        sample on trailing edge iff this is set) flags.

    SPI_IOC_RD_LSB_FIRST, SPI_IOC_WR_LSB_FIRST ... pass a pointer to a byte
        which will return (RD) or assign (WR) the bit justification used to
        transfer SPI words.  Zero indicates MSB-first; other values indicate
        the less common LSB-first encoding.  In both cases the specified value
        is right-justified in each word, so that unused (TX) or undefined (RX)
        bits are in the MSBs.

    SPI_IOC_RD_BITS_PER_WORD, SPI_IOC_WR_BITS_PER_WORD ... pass a pointer to
        a byte which will return (RD) or assign (WR) the number of bits in
        each SPI transfer word.  The value zero signifies eight bits.

    SPI_IOC_RD_MAX_SPEED_HZ, SPI_IOC_WR_MAX_SPEED_HZ ... pass a pointer to a
        u32 which will return (RD) or assign (WR) the maximum SPI transfer
        speed, in Hz.  The controller can't necessarily assign that specific
        clock speed.

NOTES:

   - At this time there is no async I/O support; everything is purely
      synchronous.都是同步的?

    - There's currently no way to report the actual bit rate used to
      shift data to/from a given device.

    - From userspace, you can't currently change the chip select polarity;
      that could corrupt transfers to other devices sharing the SPI bus.
      Each SPI device is deselected when it's not in active use, allowing
      other drivers to talk to other devices.

    - There's a limit on the number of bytes each I/O request can transfer
      to the SPI device.  It defaults to one page, but that can be changed
      using a module parameter.

    - Because SPI has no low-level transfer acknowledgement, you usually
      won't see any I/O errors when talking to a non-existent device.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP