transfer size limiation of SPIMaster_TransferSequential() ? RRS feed

  • Question

  • In document, there is a remark to highlight each write (or read) transfer is limited to 4096 bytes.


    What I'm trying to do is split my large data blocks into multiple transfers. I wrote below code and did some debug. When I have two transfer descriptor, e.g. the first one is 4096, then second one is 8, I will get a invalid augment error. 

    Is this API limited to 4096 bytes in maximum or applied to each transfer descriptor?

    My code:

    #define MAX_SPI_TRANSFER_BYTES 4096

    int ll_spi_rx(uint8_t *rx_data, uint32_t rx_len) {

    size_t numOfXfer = (rx_len % MAX_SPI_TRANSFER_BYTES == 0) ? (rx_len / MAX_SPI_TRANSFER_BYTES) : (rx_len / MAX_SPI_TRANSFER_BYTES + 1);

    SPIMaster_Transfer *p_transfer_array = malloc(sizeof(SPIMaster_Transfer) * numOfXfer); int ret = SPIMaster_InitTransfers(p_transfer_array, numOfXfer); if (ret < 0) { Log_Debug("ERROR: SPIMaster_InitTransfers: errno=%d (%s)\n", errno, strerror(errno)); free(p_transfer_array); return -1; } int32_t offset = 0; int32_t sizeleft = rx_len; for (uint32_t i = 0; i < numOfXfer; i++) { p_transfer_array[i].flags = SPI_TransferFlags_Read; p_transfer_array[i].readData = rx_data + offset; p_transfer_array[i].length = sizeleft > MAX_SPI_TRANSFER_BYTES ? MAX_SPI_TRANSFER_BYTES : sizeleft; sizeleft -= MAX_SPI_TRANSFER_BYTES; offset += MAX_SPI_TRANSFER_BYTES; } ret = SPIMaster_TransferSequential(spiFd, p_transfer_array, numOfXfer); if (ret < 0) { Log_Debug("ERROR: SPIMaster_TransferSequential: errno=%d (%s)\n", errno, strerror(errno)); free(p_transfer_array); return -1; } else if (ret != rx_len) { Log_Debug("ERROR: SPIMaster_TransferSequential transfer %d bytes, expect %d bytes\n", ret, rx_len); free(p_transfer_array); return -1; } free(p_transfer_array); return 0;


    Sunday, October 20, 2019 8:25 AM

All replies

  • I found when I put a write and a read operation in a transfer sequence then total size can exceed 4096 for this API. But I have two read operation and total transfer number is higher than 4096 (whether it is 4096 + 104 or 2500 + 2500), I will get -1 for this API. Please double check internal. Thanks.
    Sunday, October 20, 2019 9:27 AM
  • Hi Xiong,

    I see you opened an issue on docs to: https://github.com/MicrosoftDocs/azure-sphere-issues/issues/169

    Would it be ok that we continue the thread there and close the one here?


    Thursday, October 24, 2019 4:08 PM
  • Hi,

    They're different, that one is a document issue. This is a potential bug waiting for your confirmation

    Thursday, October 24, 2019 6:32 PM
  • Hi, 

    Any update? There're many use case need to transfer more than 4096 bytes at once over SPI. I want to know whether we can divide bunch of data into multiple transfers structure provided in the API. Or user need call SPIMaster_TransferSequential() for several times.

    If there is any limitation to the API, better to document it well in API doc. Thanks.

    Thursday, November 14, 2019 4:31 AM
  • Hello Neo sorry for keep you waiting.

    I upgraded OS and SDK to 19.10 and tried to repro your issue adapting the code from this sample.

    I tweaked lines 151 and 155 of main.c to simulate your error though for my case, and with the specific accelerometer (ST LSM6DS3) + Azure Sphere MT3620 board the max I could transfer on each SPIMaster_TransferSequential() call was 1245 Bytes. The error I get when trying to transfer more than that is: errno=14 (Bad address)

    1) Can you share your Azure Sphere board and SPI sensor details?

    2) What is the errno in your case?

    I am reaching out to azure sphere team to take a look at this to.


    Thursday, November 21, 2019 4:43 PM
  • Hi, 

    I'm using some slave devices that you do not have. But this problem should be able to reproduce without any slave connecting to. Just init SPI and call transfer API with multiple transfer structures at the same directions. 

    I do not know why you stop at 1245. I guess if you only modify the number of transfer, the src or dst pointer will move to somewhere and may cause the problem.

    For errno, sorry I can't remember. 

    Again, my expectation is:

    If I have 40960 bytes need to be sent or read, I only need call the API transfer once, with 10 transfer structure installed.

    SPIMaster_TransferSequential(spifd, &trasnfer_array[0], 10);

    Saturday, November 23, 2019 6:16 AM
  • Hi,

    Update from the Git issue linked, 

    Each call to SPIMaster_TransferSequential or SPIMaster_WriteThenReadis limited to at most 4096 bytes to read, and 4096 bytes to write, independent of the number of actual transfers. To transfer additional data, you need to call this function multiple times. Note that chip select will be asserted multiple times in this case.

    The online documentation will be updated to include this information later this week

    Please check and let us know if that helps.

    Friday, February 7, 2020 4:40 AM