Asked by:
transfer size limiation of SPIMaster_TransferSequential() ?

Question
-
In document, there is a remark to highlight each write (or read) transfer is limited to 4096 bytes.
https://docs.microsoft.com/en-us/azure-sphere/reference/applibs-reference/applibs-spi/function-spimaster-transfersequential
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;
}
- Edited by Neo (Yu) Xiong Sunday, October 20, 2019 8:26 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.
-
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?
Thanks!
- Proposed as answer by António Sérgio Azevedo - MSFTMicrosoft employee, Moderator Thursday, October 24, 2019 4:10 PM
- Unproposed as answer by António Sérgio Azevedo - MSFTMicrosoft employee, Moderator Friday, October 25, 2019 5:55 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.
-
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.
Thanks!
-
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);