- 论坛徽章:
- 0
|
本人想用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结构体数组不能实现全双工可读可写? |
|