16*480*10/80 = 960 us per block of 10 rows
Now, I tested that with the gptimer and it actually gives me very close results, each block taking between 980 us and 1010 us (But mostly close to 1000 us), so it makes sense to me, considering aditional delays from the execution, including the handling of the timer itself. The timing worked like this (DebugTimer is an object of a hardware timer class I wrote with many functionalities):
- spi_transaction_t Transaction = {};
- //Transaction struct config
- Transtaction.foo_ = foo;
- Transtaction.foo1_ = foo1; Transtaction.foo2_ = foo1;
- spi_device_acquire_bus(...);
- DebugTimer.Tic();
- spi_device_polling_transmit(...);
- printf("Time: %lu us\n", DebugTimer.TocUs());
- spi_device_release_bus(...);
My conclusion is that "spi_device_queue_trans" buffers the transaction and the SPI peripheral is in charge of sending everything to the device. I read something about that in the esp-idf documentation, but I had asumed that I needed to write code in an ISR to handle the transaction, however this is surprisingly easy. And the reason why it takes little time at first, then longer, and then little again when I start timing before acquiring the bus is that some kind of buffer gets filled with transactions so I just can't buffer them anymore and have to wait.
Now... there are some things I don't fully understand. I don't have any problem if the refresh of the screen takes a few ms longer, but I do have a problem if the CPU is blocked for a few ms trying to send data to the screen.
Is an ISR called by default by the esp-idf framework that does all transactions? If so, is that ISR blocking the execution of other FreeRTOS tasks for a long time? Or are they short lived? From what I read in the esp-idf, a polling transaction keeps the CPU busy, so from what I understand other tasks won't be executed until the polling ends.
This is proving to be a bit confusing to me. I don't mind waiting for the transaction to complete in the task that handles the transaction. But I want other tasks to be able to run while a transaction is ongoing, even if it means refreshing the screen takes longer.
Is using "spi_device_queue_trans" and making sure no two different tasks try to access the same SPI device all I have to do to achieve that? I'm sorry if I'm not being clear, I'll keep an eye out on the comments. Thanks!
EDIT: I forgot to mention, if the reason why after some transaction it takes longer when I also time "spi_device_acquire_bus" is that some buffer is full, and the function blocks the task until that buffer is freed... how does it know that the next transaction will fit in the buffer? Or if that were to happen the function "spi_device_queue_trans" would block the task?