How to know the length of the data obtained when reading SPI?

31 Views Asked by At

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;
}
0

There are 0 best solutions below