I encountered a strange problem when reading and writing SPI through the application layer. I found that I can only set the length of data I send, and I cannot obtain the length of data I receive. However, the length of data I receive each time is not fixed. How can I modify my code?
spidev.c
#include <linux/spi/spidev.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
enum
{
SPI_MODE = 0,
SPI_DELAY = 0,
SPI_SPEED = 500 * 1000,
SPI_BITS = 8
};
int TransferSpi(int fd, const uint8_t *tx, int txSize, uint8_t *rx)
{
int ret;
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = txSize,
.delay_usecs = SPI_DELAY,
.speed_hz = SPI_SPEED,
.bits_per_word = SPI_BITS,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
{
perror("can't send spi message");
return -1;
}
return ret;
}
int OpenSpiDev(const char *devName)
{
uint8_t mode = SPI_MODE;
uint8_t bits = SPI_BITS;
uint32_t speed = SPI_SPEED;
uint16_t delay = SPI_DELAY;
int fd = -1;
int ret = -1;
fd = open(devName, O_RDWR);
if (fd < 0)
{
perror("can't open device");
return -1;
}
/*
* spi mode
*/
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
{
perror("can't set spi mode");
return -1;
}
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
{
perror("can't get spi mode");
return -1;
}
/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
{
perror("can't set bits per word");
return -1;
}
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
{
perror("can't get bits per word");
return -1;
}
/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
{
perror("can't set max speed hz");
return -1;
}
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
{
perror("can't get max speed hz");
return -1;
}
return fd;
}
int main(int argc, char *argv[])
{
int fd = OpenSpiDev("/dev/spidev1.0");
uint8_t tx[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d};
uint8_t rx[ARRAY_SIZE(tx)] = {
0,
};
transfer(fd, tx, ARRAY_SIZE(tx), rx);
for (int i = 0; i < ARRAY_SIZE(tx); i++)
{
if (!(i % 6))
puts("");
printf("%.2X ", rx[i]);
}
puts("");
close(fd);
return 0;
}