Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 4547

SDK • spi_write_read_blocking() not blocking?

$
0
0
Hello everyone,

I've been writing some code to communicate with an MCP2515 (https://www.microchip.com/en-us/product/mcp2515) over SPI. The SPI is configured to mode 3, which avoids pulsing of the CS line between bytes, a known "feature" of the RP2040 in SPI mode 0.

Code:

spi_set_format(spi0, 8, SPI_CPOL_1, SPI_CPHA_1, SPI_MSB_FIRST); // SPI MODE 3
My code is using the spi_write_blocking() function to send commands and write to registers on the device. This works fine.
https://www.raspberrypi.com/documentati ... 8415f3b4c8

To read from the device, I use the spi_write_read_blocking() function.
https://www.raspberrypi.com/documentati ... b740717910

The MCP2515 register read function as implemented by me:

Code:

uint8_t reg_read_mcp2515(uint8_t reg){    uint8_t buf_read[3];    uint8_t buf_write[3];    buf_write[0] = 0b00000011;  // READ instruction    buf_write[1] = reg;    buf_write[2] = 0;    spi_write_read_blocking(spi0, buf_write, buf_read, 3);    return(buf_read[2]);}
While testing communication I noticed that my register write function was working as it should, but the reg_read_mcp2515() function was sometimes returning incorrect register values. To be precise, it returns incorrect values when there are multiple subsequent calls to it in the code or the SPI baudrate is set relatively low (below a few hundred kHz or so). Stepping through the code line-by-line with the debugger, multiple subsequent register reads return correct values. Adding a significant delay between subsequent "reg_read_mcp2515" calls or upping the SPI baudrate into the MHz range also fixes the issue.

When I hooked up the scope, the issue was pretty obvious: The CS line stayed low between subsequent calls to spi_write_read_blocking(), whereas it pulses high between subsequent calls to spi_write_blocking(). This is at low baudrates, 10,000 / 100,000kHz for example. If you increase the baudrate to say 10Mhz, the CS line DOES go high between the calls to spi_write_read_blocking(), which fixes communication issues with the SPI slave.

Looking at the SDK code for spi_write_blocking(), there is this part before the function returns:

Code:

    // Drain RX FIFO, then wait for shifting to finish (which may be *after*    // TX FIFO drains), then drain RX FIFO again    while (spi_is_readable(spi))        (void)spi_get_hw(spi)->dr;    while (spi_get_hw(spi)->sr & SPI_SSPSR_BSY_BITS)        tight_loop_contents();    while (spi_is_readable(spi))        (void)spi_get_hw(spi)->dr;
From my understanding,

Code:

    while (spi_get_hw(spi)->sr & SPI_SSPSR_BSY_BITS)        tight_loop_contents();
blocks until the spi hardware has finished shifting out the data and has pulled the CS line high again. Thus it "Blocks until all data is transferred" as described in the SDK documentation, not just until the data is in the TX FIFO.

The spi_write_read_blocking() function is documented as blocking in the exact same way, but the code for it completely lacks the part where SPI_SSPSR_BSY_BITS is checked, and thus the function may return early, causing communication to fail at low baud rates (CS stays low between calls) but not at high baud rates.

Modifying my own register read function to

Code:

uint8_t reg_read_mcp2515(uint8_t reg){    uint8_t buf_read[3];    uint8_t buf_write[3];    buf_write[0] = 0b00000011;  // READ instruction    buf_write[1] = reg;    buf_write[2] = 0;    spi_write_read_blocking(spi0, buf_write, buf_read, 3);    // Wait for SPI to really finish sending out data...    while (spi0_hw->sr & SPI_SSPSR_BSY_BITS){        tight_loop_contents();    }    return(buf_read[2]);}
fixes the communication issues with the slave.

Is there something I am missing that would explain this behavior of spi_write_read_blocking()? It is not what I expected from reading the SDK documentation or from my experience with the SPI write function.

Statistics: Posted by KTS — Wed Jan 31, 2024 5:33 pm — Replies 0 — Views 13



Viewing all articles
Browse latest Browse all 4547

Trending Articles