This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

long SPI communication unreliable

Hi teams,

I have build custom board connected to ethernet via ENC28J60 ethernet controller.

It uses SPI communication with ENC28J60, but some strange behaviour during bulk TX/RX.

Please see the following codes.

#if 0
    nrf_drv_spi_xfer_desc_t datadesc = NRF_DRV_SPI_XFER_RX(buf, len);
    APP_ERROR_CHECK(nrf_drv_spi_xfer(&spi, &datadesc, 0));
#else
    for (int i = 0; i < len; i++) {
        nrf_drv_spi_xfer_desc_t datadesc = NRF_DRV_SPI_XFER_RX(buf + i, sizeof(uint8_t));
        APP_ERROR_CHECK(nrf_drv_spi_xfer(&spi, &datadesc, 0));
    }
#endif
...
...
#if 0
    nrf_drv_spi_xfer_desc_t datadesc = NRF_DRV_SPI_XFER_TX(buf, len);
    APP_ERROR_CHECK(nrf_drv_spi_xfer(&spi, &datadesc, 0));
#else
    for (int i = 0; i < len; i++) {
        nrf_drv_spi_xfer_desc_t datadesc = NRF_DRV_SPI_XFER_TX(buf + i, sizeof(uint8_t));
        APP_ERROR_CHECK(nrf_drv_spi_xfer(&spi, &datadesc, 0));
    }
#endif

These codes are extracted my data tx/rx functions.

The #if 0 blocks should not be different from active ones, but in real, it does not work.

Why this happens?

  • After I tried to change transfer size, found my mistake eventually.

    Because SPI transfer length is limited to uint8_t, every transfers should break into several ones less than 256.

    So, the following codes works fine. Thanks, Edvin.

        for (int i = 0; i < len; i += UINT8_MAX) {
            nrf_drv_spi_xfer_desc_t datadesc = NRF_DRV_SPI_XFER_RX(buf + i, len - i > UINT8_MAX ? UINT8_MAX : len - i);
            APP_ERROR_CHECK(nrf_drv_spi_xfer(&spi, &datadesc, 0));
        }
    ...
        for (int i = 0; i < len; i += UINT8_MAX) {
            nrf_drv_spi_xfer_desc_t datadesc = NRF_DRV_SPI_XFER_TX(buf + i, len - i > UINT8_MAX ? UINT8_MAX : len - i);
            APP_ERROR_CHECK(nrf_drv_spi_xfer(&spi, &datadesc, 0));
        }
    

Related