Skip to content

Conversation

@ukmaker
Copy link

@ukmaker ukmaker commented Apr 27, 2022

Redrawing a TFT screen over SPI can be fairly slow. Things like flood-fills to clear an area of the screen use multiple calls totransfer()or transfer16(), which carry substantial overhead.

This PR contibutes a couple of additional functions which allow for the same 8- or 16-bit values to be transferred multiple times with less overhead. This results in e.g. writing a block of colour using the Adafruit SPITFT library to be approx 3x faster. The practical result is that scrolling multiple lines of text now happens smoothly instead of blinking.

@ABOSTM
Copy link
Contributor

ABOSTM commented Apr 28, 2022

Hi @ukmaker ,
Thank you for sharing this Pull Request.
I understand your need, and I understand it improves the performance for your use case,
but I feel like there is no need for this PR, and you can improve even further the performance with a completely different approach, using existing functions:
Instead of those new functions, application can simply memcopy (or memset) values to a buffer and call
transfer(uint8_t pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
Thus we would reduce even more the overhead: SPIClass::transfer() and spi_transfer() are called only once for the whole buffer.

I know that it will be at a cost of buffer in RAM, but then user can tune and find a compromise between RAM footprint and performances by adjusting buffer size.

@ukmaker
Copy link
Author

ukmaker commented Apr 28, 2022

Hi (salut!) @ABOSTM

using a ram buffer in that way feels like pushing a lot of pain up to the application. Actually I'd turn your comment round and say there should be an equivalent of my PR at the spi_transfer level for best performance :-)

Rather than the pain of getting my app to manage RAM buffers I'll just access the SPI registers directly.

@ABOSTM
Copy link
Contributor

ABOSTM commented Apr 28, 2022

For sure, if you are looking for performances, accessing directly SPI registers is the best solution. And you will get performances you will never reach with Arduino API. This is possible within Arduino sketch with CMSIS or STM32 Cube LL API. But it is far more complex (you will need good knowledge of SPI Hardware implementation) . . . and way more complex than memset to a simple buffer.
I don't consider that 2 lines of code (1 to declare a buffer and 1 to memset) is a lot of pain. It is an optional small extra code for a gain in performances. And it is simpler than implementing the same at spi_transfer level

@fpistm fpistm added waiting feedback Further information is required abandoned No more work on this and removed waiting feedback Further information is required labels May 19, 2022
@fpistm fpistm closed this May 25, 2022
@fpistm fpistm linked an issue May 25, 2022 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

abandoned No more work on this

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi-byte SPI transfers - speeds up TFT support

3 participants