Pregunta

I'm trying to implement a timeout for some hardware transmissions, to add security to a big project. I already implemented timeout using select for UART transmission, but I don't know how to add a timeout in a SPI transmission.

This is my reading code:

int spi_read(int fd, char command, char* buffer, int size, int timeout)
{
    struct spi_ioc_transfer xfer[2];
    int status;

    memset(buffer, 0, sizeof(buffer));
    memset(xfer, 0, sizeof(xfer));

    xfer[0].tx_buf = (unsigned int)(&command);
    xfer[0].len = 1;

    xfer[1].rx_buf = (unsigned int)buffer;
    xfer[1].len = size;

    status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
    if(status < 0)
        return NOERROR;
    else
        return EHWFAULT1;
}

It sends a byte sized command and receives a response of certain size (in half duplex mode). How can I implement a timeout in the response? Can it be implemented using select? Should I separe both transactions and use select or better use an alarm?

Then, I have the same question for a full duplex mode, which is implemented too using ioctl. Can you give me any hints?

¿Fue útil?

Solución

In hardware the SPI master does not 'wait' for a response. By definition, the SPI master provides the clock cycles and the slave must reply. The concept of waiting for a response doesn't apply to the SPI bus. (I'm assuming you're operating the SPI master)

(deeper in the protocol, the SPI might poll the hardware to see if it's done/ready; but the SPI bus itself is getting an immediate answer every time).

To clarify: the SPI clocks in whatever is on the SPI MISO pin. Whatever level is on the MISO pin is the reply, even if the slave is not explicitly driving a level. The only way to detect a non responsive slave is to pullup/pulldown the MISO in a way that can not be interpreted as a valid message.

Typical SPI protocol

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top