- Tue Jun 30, 2020 1:26 pm
After digging into this for the last couple days, I have confirmed why things are so slow. The issue is that the original Arduino SPI library mechanisms assume that the underlying hardware supports single-byte SPI transfers that are fast&cheap. That assumption is carried on into the SPITft library, too. Finally, the GFX library defaults to work on a pixel-by-pixel basis. When the GFX library wants to write a pixel, it performs about 13 of what it thinks are fast, but separate SPI transfers to get the pixel color data written to the display hardware. This can get really ugly: when you copy an RGB bitmap to the display it gets copied pixel-by-pixel with 13 individual SPI transfers per pixel.
The bottom line is that single-byte transfers were cheap on an old AVR chip. The world has moved on though. Any modern chip with fancy silicon to manage its SPI port takes a certain amount of time to set up for a transfer regardless of the transfer length. The Apollo3 is no exception. As a result, a modern chip has a strong incentive to send as much data as possible per transfer to amortize the setup cost over as many bytes as possible.
With that in mind, I modified the SPITft code that displays a bitmap so that instead of doing it pixel by pixel (where each pixel requires 13 distinct SPI transfers), the logo data is set up in memory so that the modified driver can send it all in a single, massive SPI transfer. The original bitmap draw operation of my 110x128 pixel logo was taking 2.92 seconds. After my mods, it dropped to 11 mSec, or more than 260 times faster. In addition to that change, I also modified the display address setup sequence so that it only needs 6 SPI transactions instead of 13. That approximately doubles the speed of any per-pixel operation.
The bottom line is that the Artemis Apollo3 is plenty capable, but in this specific case, it really needs the SPITft/GFX display drivers to be rewritten with the goal of minimizing the number of SPI transfers.