免费注册 查看新帖 |

Chinaunix

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

spi用户空间驱动问题咨询 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-05-08 14:08 |只看该作者 |倒序浏览
本人想用spi用户空间驱动往spi从设备发消息,现在驱动加载正常,可以在dev下生成dev1.0设备节点,用wirte和read函数操作从设备正常,但是write和read是半双工的方式不符合要求,本人需要用全双工的方式去读取spi从设备的数据,请各位大侠帮忙给点思路,这个问题困扰我好久了,谢谢

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <getopt.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

static void do_msg(int fd)
{
unsigned char tx[6] = {0x08, 0xff, 0x12, 0, 0, 0,};
unsigned char rx[6];
unsigned char *bp, *av;
int status;
int     len, len_rx;

len = sizeof tx;
len_rx = len;

    struct spi_ioc_transfer xfer = {
.tx_buf = (unsigned long long)tx,
.rx_buf = (unsigned long long)tx,
.len = 6,
.delay_usecs = 0,
.bits_per_word = 8,
     };


status = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer);
if (status < 0)
{
perror("SPI_IOC_MESSAGE");
return;
}

printf("response(%2d, %2d): ", len, status);
for (bp = tx; len; len--)
printf(" %02x", *bp++);
printf("\n");


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


int main(int argc, char **argv)
{
int fd;
unsigned char mode;  
unsigned char bits = 8;  
unsigned long speed = 10000000;  
unsigned short delay;
int ret;
const char *name = "/dev/spidev1.0";

fd = open(name, O_RDWR);
if (fd < 0)
{
perror("open");
return -1;
}

#if 1
mode |= SPI_CPHA;
         mode |= SPI_CPOL;

/*
  * spi mode
  */
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
pabort("can't set spi mode");

ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
pabort("can't get spi mode");

/*
  * bits per word
  */
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word");

ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word");

/*
  * max speed hz
  */
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz");

ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz");

printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %lu Hz (%lu KHz)\n", speed, speed/1000);
#endif
do_msg(fd);


close(fd);
return 0;
}


用spidev设备节点发消息ioctl(fd, SPI_IOC_MESSAGE(1), &xfer),发不通,报SPI_IOC_MESSAGE: Invalid argument错误,麻烦各位大侠帮忙给点提示?
这个是按照spidev_test.c去写的,我把.rx_buf = (unsigned long)tx,去掉或者赋NULL就可以把消息发出去。但是去掉.rx_buf,我怎么实现在一个片选信号下实现全双工读写消息?

如果我这么构造消息:
struct spi_ioc_transfer xfer[2];
unsigned char buf[6];
unsigned char *bp, *av;
int status;
int     len, len_rx;

memset(&xfer, 0, sizeof xfer);
memset(buf, 0, sizeof buf);

len = sizeof buf;
len_rx = len;

buf[0] = 0x08;
buf[1] = 0xff;
buf[2] = 0x12;
buf[3] = 0;
buf[4] = 0;
buf[6] = 0;
xfer[0].tx_buf = (unsigned long)buf;
xfer[0].rx_buf = NULL;
xfer[0].len = 6;
xfer[0].delay_usecs = 0;
xfer[0].bits_per_word = 8;


xfer[1].tx_buf = NULL;
xfer[1].rx_buf = (unsigned long)buf;
xfer[1].len = 6;
xfer[1].delay_usecs = 0;
xfer[1].bits_per_word = 8;

status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
if (status < 0)
{
perror("SPI_IOC_MESSAGE");
return;
}

消息是可以发出去的,但是用示波器抓信号,会发现有两个cs片选信号,这个是怎么回事?请问如果用SPI_IOC_MESSAGE(N)这个宏来发消息,该怎么实现全双工读写spi从设备?一个spi_ioc_transfer结构体数组不能实现全双工可读可写?

论坛徽章:
0
2 [报告]
发表于 2013-05-08 14:09 |只看该作者
SPI_IOC_MESSAGE(N)这个宏,网上说它是全双工读写,用该宏可以保持永远的片选信号,但我用示波器抓出来却是两个cs片选信号?我用的是spi_mode_3.
还有如果利用spidev.c这个驱动,能否利用中断和dma方式进行传输数据?比如spi从设备会主动给cpu报一个中断,在中断处理中将spi从设备数据取出来,如果想利用这种方式的话应该怎么修改代码,是修改spidev.c吗?
请高手帮忙解答

论坛徽章:
0
3 [报告]
发表于 2013-05-09 09:03 |只看该作者
有人帮忙解答下吗?

论坛徽章:
0
4 [报告]
发表于 2013-05-09 13:10 |只看该作者
有人能告诉我下,只定义一个struct spi_ioc_transfer xfer,即:
struct spi_ioc_transfer xfer = {
.tx_buf = (unsigned long long)tx,
.rx_buf = (unsigned long long)tx,
.len = 6,
.delay_usecs = 0,
.bits_per_word = 8,
      };


到底可不可以在一个片选信号之内实现全双工的对spi从设备写读吗?

论坛徽章:
0
5 [报告]
发表于 2016-08-30 18:31 |只看该作者
您好 请问您的问题最后是怎么解决的?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP