I was wondering about the Arduino Zero Pro and the hard-SPI ILI9341 TFT (320x240) shield. I hope this is a proper thread to share my findings and ask a question.
My question revolves around DMA and Adafruit's GFX library on the Arduino Zero Pro R3 (a genuine Arduino).
I am using Adafruit_GFX library version 1.10.4, Adafruit Zero DMA library version 1.0.8, board "Arduino M0 Pro", and have cut the traces on the Adafruit "2.8 TFT LCD shield w/Touchscreen and microSD card v2.0" (quoting the silkscreen; there's no part #). It's using the SPI on the ICSP port.
I begin my sketch as follows:
#define USE_SPI_DMA
#include <Adafruit_ZeroDMA.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_GFX.h> // Core graphics library
I wrap the Adafruit_ILI9341 class in a subclass to add a backlight PWM pin to the definition:
class TFT_Extension : public Adafruit_ILI9341 {
private:
int pinBacklightPWM;
public:
TFT_Extension(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK,
int8_t _PWM = -1,
int8_t _RST = -1, int8_t _MISO = -1);
TFT_Extension(int8_t _CS, int8_t _DC, int8_t _PWM = -1, int8_t _RST = -1);
#if !defined(ESP8266)
TFT_Extension(SPIClass *spiClass, int8_t dc, int8_t _PWM = -1, int8_t cs = -1,
int8_t rst = -1);
#endif // end !ESP8266
TFT_Extension(tftBusWidth busWidth, int8_t d0, int8_t wr, int8_t dc, int8_t _PWM = -1,
int8_t cs = -1, int8_t rst = -1, int8_t rd = -1);
void setBacklight(uint8_t level);
};
TFT_Extension::TFT_Extension(int8_t _CS, int8_t _DC, int8_t _PWM, int8_t _RST)
: Adafruit_ILI9341(_CS, _DC, _RST)
{
pinBacklightPWM = _PWM;
if (pinBacklightPWM >= 0) {
pinMode(pinBacklightPWM, OUTPUT);
}
}
// (.. remaining initializers are <here> ..)
TFT_Extension gTFT = TFT_Extension(TFT_CS, TFT_DC, TFT_BACKLIGHT);
I wrote a lot of code using drawBitmap() to move a GFXCanvas to the screen. Performance was discouraging. I put a scope on the SPI clock and the TFT CS wire and saw the SPI clock moving at 24MHz, but discouraging lags between individual bytes. Each byte moved in 310ns, but the time per byte was over five times that. (See attachment)
I would have expected a memory-to-perhiperal DMA from a bitmap in memory to be moving many bytes edge-to-edge, at least the SPI FIFO size (16 bytes on SAMD21 SERCOM) for a wide-enough GFXCanvas.
I removed the #define of USE_SPI_DMA and saw no added slowdowns. I write a loop to do a fillScreen() 100 times and take the average, and that confirms no difference: 251.14 milliseconds per fill with or without the #define.
Should I see any difference, or is my experiment flawed? Is my subclass intializer causing this? Should a drawBitmap() of a canvas as wide as the TFT and 16 scan line high create a burst of DMA-speed SPI traffic? Am I using the wrong #define (is it a good test case)?
Thank you for your interest in my questions.