Trying to debug why the updates are slow compared to other boards I have used.
So I put together a small test sketch that just uses the keypadloop code from pacman embededed in the graphicstest sketch using the ILI9341_GIGA_n library.
//Library for Gamepad
#define USBHOST_OTHER
#include <LibPrintf.h>
#include <Arduino_USBHostMbed5.h>
#include "USBHostGamepadDevice.h"
USBHostGamepad joystick1;
/**********************************************************/
#include "SPI.h"
#include "ILI9341_GIGA_n.h"
// *************** Change to your Pin numbers ***************
#define TFT_DC 9
#define TFT_RST 8
#define TFT_CS 10
#define USE_FRAME_BUFFER 1
ILI9341_GIGA_n tft(&SPI1, TFT_CS, TFT_DC, TFT_RST);
/********************************************************/
uint32_t buttons = 0;
uint32_t buttons_prev = 0;
uint8_t ltv, rtv;
uint32_t button_time = 0;
boolean but_START = false; //38 //8, 168 or share////100
boolean but_SELECT = false; //40 //1 , 328 or options///200
boolean but_A = false; //44 //32768 sqr, 262152///1
boolean but_B = false; //42 //8192 circ, /// 4
boolean but_UP = false; //52 //16, 0 ///10000
boolean but_DOWN = false; //50 //64, 4 /////40000
boolean but_LEFT = false; //48 //128, 6 /////80000
boolean but_RIGHT = false; //46 //32, 2 /////20000
void ClearKeys() {
but_START = false;
but_SELECT = false;
but_A = false;
but_B = false;
but_UP = false;
but_DOWN = false;
but_LEFT = false;
but_RIGHT = false;
}
void KeyPadLoop() {
if (joystick1.available()) {
buttons = joystick1.getButtons();
//Serial.println(buttons);
switch (joystick1.gamepadType()) {
case USBHostGamepad::UNKNOWN:
case USBHostGamepad::PS4:
{
if (buttons == 256 ) {
ClearKeys(); //else but_START=false;
but_START = true;
delay(300);
}
if (buttons == 512 ) {
ClearKeys();
but_SELECT = true;
delay(300);
} else but_SELECT = false;
if (buttons == 1 ) {
ClearKeys();
but_A = true;
} else but_A = false;
if (buttons == 4) {
ClearKeys();
but_B = true;
} else but_B = false;
if (buttons == 65536) {
ClearKeys(); //else but_UP=false;
but_UP = true;
}
if (buttons == 262144) {
ClearKeys(); //else but_DOWN=false;
but_DOWN = true;
}
if (buttons == 524288) {
ClearKeys(); // else but_LEFT=false;
but_LEFT = true;
}
if (buttons == 131072) {
ClearKeys(); //else but_RIGHT=false;
but_RIGHT = true;
}
}
break;
case USBHostGamepad::NES:
{
if (buttons == 0x200000 ) {
ClearKeys(); //else but_START=false;
but_START = true;
delay(300);
}
if (buttons == 0x100000 ) {
ClearKeys();
but_SELECT = true;
delay(300);
} else but_SELECT = false;
if (buttons == 0x200 ) {
ClearKeys();
but_A = true;
} else but_A = false;
if (buttons == 0x400) {
ClearKeys();
but_B = true;
} else but_B = false;
if (buttons == 0x01) {
ClearKeys(); //else but_UP=false;
but_UP = true;
}
if (buttons == 0x04) {
ClearKeys(); //else but_DOWN=false;
but_DOWN = true;
}
if (buttons == 0x08) {
ClearKeys(); // else but_LEFT=false;
but_LEFT = true;
}
if (buttons == 0x02) {
ClearKeys(); //else but_RIGHT=false;
but_RIGHT = true;
}
}
break;
default:
break;
}
}
yield();
}
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 5000) {}
Serial.println("Starting PacMan...");
// Enable the USBHost
pinMode(PA_15, OUTPUT);
digitalWrite(PA_15, HIGH);
delay(500);
while (!joystick1.connect()) {
Serial.println("No gamepad connected");
delay(5000);
}
Serial.println("Joystick connected:");
tft.begin();
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_YELLOW);
tft.setTextSize(2);
tft.println("Waiting for Arduino Serial Monitor...");
Serial.println(F("Benchmark Time (microseconds)"));
Serial.print(F("Screen fill "));
Serial.println(testFillScreen());
delay(200);
Serial.print(F("Text "));
Serial.println(testText());
delay(600);
Serial.print(F("Lines "));
Serial.println(testLines(ILI9341_CYAN));
delay(200);
Serial.print(F("Horiz/Vert Lines "));
Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE));
delay(200);
Serial.print(F("Rectangles (outline) "));
Serial.println(testRects(ILI9341_GREEN));
delay(200);
Serial.print(F("Rectangles (filled) "));
Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA));
delay(200);
Serial.print(F("Circles (filled) "));
Serial.println(testFilledCircles(10, ILI9341_MAGENTA));
Serial.print(F("Circles (outline) "));
Serial.println(testCircles(10, ILI9341_WHITE));
delay(200);
Serial.print(F("Triangles (outline) "));
Serial.println(testTriangles());
delay(200);
Serial.print(F("Triangles (filled) "));
Serial.println(testFilledTriangles());
delay(200);
Serial.print(F("Rounded rects (outline) "));
Serial.println(testRoundRects());
delay(200);
Serial.print(F("Rounded rects (filled) "));
Serial.println(testFilledRoundRects());
#if USE_FRAME_BUFFER
WaitForUserInput();
Serial.print(F("Rectangles (filled) FB "));
Serial.println(testFilledRectsFB(ILI9341_YELLOW, ILI9341_MAGENTA));
delay(200);
WaitForUserInput();
Serial.print(F("Rounded rects (filled) FB "));
Serial.println(testFilledRoundRectsFB());
delay(200);
tft.useFrameBuffer(0); // turn back off
WaitForUserInput();
#endif
}
void loop() {
for (uint8_t rotation = 0; rotation < 4; rotation++) {
button_time = micros();
KeyPadLoop();
printf("button_time: %d\n", micros() - button_time); tft.setRotation(rotation);
testText();
delay(1000);
}
}
void WaitForUserInput() {
if (Serial) {
Serial.println("Hit key to continue");
while (Serial.read() == -1) ;
while (Serial.read() != -1) ;
Serial.println(F("Done!"));
}
}
unsigned long testFillScreen() {
unsigned long start = micros();
tft.fillScreen(ILI9341_BLACK);
tft.fillScreen(ILI9341_RED);
tft.fillScreen(ILI9341_GREEN);
tft.fillScreen(ILI9341_BLUE);
tft.fillScreen(ILI9341_BLACK);
return micros() - start;
}
unsigned long testText() {
tft.fillScreen(ILI9341_BLACK);
unsigned long start = micros();
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
tft.println(1234.56);
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
tft.println(0xDEADBEEF, HEX);
tft.println();
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(5);
tft.println("Groop");
tft.setTextSize(2);
tft.println("I implore thee,");
tft.setTextSize(1);
tft.println("my foonting turlingdromes.");
tft.println("And hooptiously drangle me");
tft.println("with crinkly bindlewurdles,");
tft.println("Or I will rend thee");
tft.println("in the gobberwarts");
tft.println("with my blurglecruncheon,");
tft.println("see if I don't!");
return micros() - start;
}
unsigned long testLines(uint16_t color) {
unsigned long start, t;
int x1, y1, x2, y2,
w = tft.width(),
h = tft.height();
tft.fillScreen(ILI9341_BLACK);
x1 = y1 = 0;
y2 = h - 1;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t = micros() - start; // fillScreen doesn't count against timing
tft.fillScreen(ILI9341_BLACK);
x1 = w - 1;
y1 = 0;
y2 = h - 1;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;
tft.fillScreen(ILI9341_BLACK);
x1 = 0;
y1 = h - 1;
y2 = 0;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;
tft.fillScreen(ILI9341_BLACK);
x1 = w - 1;
y1 = h - 1;
y2 = 0;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
return micros() - start;
}
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height();
tft.fillScreen(ILI9341_BLACK);
start = micros();
for (y = 0; y < h; y += 5) tft.drawFastHLine(0, y, w, color1);
for (x = 0; x < w; x += 5) tft.drawFastVLine(x, 0, h, color2);
return micros() - start;
}
unsigned long testRects(uint16_t color) {
unsigned long start;
int n, i, i2,
cx = tft.width() / 2,
cy = tft.height() / 2;
tft.fillScreen(ILI9341_BLACK);
n = min(tft.width(), tft.height());
start = micros();
for (i = 2; i < n; i += 6) {
i2 = i / 2;
tft.drawRect(cx - i2, cy - i2, i, i, color);
}
return micros() - start;
}
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
unsigned long start, t = 0;
int n, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
n = min(tft.width(), tft.height()) - 1;
for (i = n; i > 0; i -= 6) {
i2 = i / 2;
start = micros();
tft.fillRect(cx - i2, cy - i2, i, i, color1);
t += micros() - start;
// Outlines are not included in timing results
tft.drawRect(cx - i2, cy - i2, i, i, color2);
}
return t;
}
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
tft.fillScreen(ILI9341_BLACK);
start = micros();
for (x = radius; x < w; x += r2) {
for (y = radius; y < h; y += r2) {
tft.fillCircle(x, y, radius, color);
}
}
return micros() - start;
}
unsigned long testCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, r2 = radius * 2,
w = tft.width() + radius,
h = tft.height() + radius;
// Screen is not cleared for this one -- this is
// intentional and does not affect the reported time.
start = micros();
for (x = 0; x < w; x += r2) {
for (y = 0; y < h; y += r2) {
tft.drawCircle(x, y, radius, color);
}
}
return micros() - start;
}
unsigned long testTriangles() {
unsigned long start;
int n, i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
n = min(cx, cy);
start = micros();
for (i = 0; i < n; i += 5) {
tft.drawTriangle(
cx , cy - i, // peak
cx - i, cy + i, // bottom left
cx + i, cy + i, // bottom right
tft.color565(0, 0, i));
}
return micros() - start;
}
unsigned long testFilledTriangles() {
unsigned long start, t = 0;
int i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
start = micros();
for (i = min(cx, cy); i > 10; i -= 5) {
start = micros();
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(0, i, i));
t += micros() - start;
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(i, i, 0));
}
return t;
}
unsigned long testRoundRects() {
unsigned long start;
int w, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
w = min(tft.width(), tft.height()) - 1;
start = micros();
for (i = 0; i < w; i += 6) {
i2 = i / 2;
tft.drawRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(i, 0, 0));
}
return micros() - start;
}
unsigned long testFilledRoundRects() {
unsigned long start;
int i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
start = micros();
for (i = min(tft.width(), tft.height()) - 1; i > 20; i -= 6) {
i2 = i / 2;
tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, i, 0));
}
return micros() - start;
}
#if USE_FRAME_BUFFER
unsigned long testFilledRectsFB(uint16_t color1, uint16_t color2) {
unsigned long start, t = 0;
int n, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.useFrameBuffer(1);
tft.fillScreen(ILI9341_BLACK);
start = micros();
n = min(tft.width(), tft.height());
for (i = n; i > 0; i -= 6) {
i2 = i / 2;
tft.fillRect(cx - i2, cy - i2, i, i, color1);
t += micros() - start;
// Outlines are not included in timing results
tft.drawRect(cx - i2, cy - i2, i, i, color2);
}
tft.updateScreen();
return micros() - start;
}
unsigned long testFilledRoundRectsFB() {
unsigned long start;
int i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.useFrameBuffer(1);
tft.fillScreen(ILI9341_BLACK);
start = micros();
for (i = min(tft.width(), tft.height()); i > 20; i -= 6) {
i2 = i / 2;
tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, i, 0));
}
tft.updateScreen();
return micros() - start;
}
#endif
As a base line I ran the graphicstest sketch:
ILI9341 Test!
After TFT Begin
Display Power Mode: 0x0
MADCTL Mode: 0x0
Pixel Format: 0x0
Image Format: 0x0
Self Diagnostic: 0x0
Benchmark Time (microseconds)
Screen fill 230873
Text 38240
Lines 326527
Horiz/Vert Lines 20779
Rectangles (outline) 15141
Rectangles (filled) 474117
Circles (filled) 199044
Circles (outline) 250084
Triangles (outline) 72553
Triangles (filled) 219417
Rounded rects (outline) 95274
Rounded rects (filled) 558090
All ok so far. Now running the modified graphics test sketch what I am seeing does not look good. It keeps hitting the libraries SPI timeout code:
if (delta_time >= TIMEOUT_US) {
Serial.print("**TO** WTC: ");
Serial.print(wtcCallCount, DEC);
Serial.print(" ");
Serial.print(called_from, DEC);
Serial.print(" ");
Serial.print(sr_prev, HEX);
Serial.print(" ");
Serial.println(sr, HEX);
// Serial.print(" ");
// Serial.println(_data_sent_not_completed, DEC);
}
_data_sent_since_last_transmit_complete = false;
}
with corresponding output:
Joystick connected:
**TO** WTC: 52 1 2 3007
**TO** WTC: 139 1 2 2B
**TO** WTC: 294 2 2 3007
**TO** WTC: 427 6 2001 9007
**TO** WTC: 663 2 2 3007
**TO** WTC: 816 1 1002 2A
**TO** WTC: 884 6 2007 B007
**TO** WTC: 1203 6 2007 5007
**TO** WTC: 1271 1 2 5007
**TO** WTC: 1441 1 2 2C
Benchmark Time (microseconds)
Screen fill 2272711
Text **TO** WTC: 1755 1 2 7007
**TO** WTC: 1836 1 2 7007
**TO** WTC: 1868 1 2 3007
**TO** WTC: 2438 1 2 3007
**TO** WTC: 2591 6 2001 9007
**TO** WTC: 2718 1 2 2B
**TO** WTC: 3098 2 2 3007
**TO** WTC: 3190 6 2001 5007
**TO** WTC: 3346 1 2 3007
**TO** WTC: 3432 6 2007 5007
**TO** WTC: 3490 6 2007 3007
**TO** WTC: 3567 6 2001 0
**TO** WTC: 3650 2 2 3007
**TO** WTC: 3729 6 2007 7007
**TO** WTC: 3801 2 2 3007
**TO** WTC: 3873 1 2 7007
**TO** WTC: 3954 1 2 5007
**TO** WTC: 4145 1 2 7007
**TO** WTC: 4331 5 2 3007
**TO** WTC: 4732 1 2 7007
**TO** WTC: 4834 2 2 3007
**TO** WTC: 5037 1 2 5007
**TO** WTC: 5232 1 2 3007
**TO** WTC: 5325 5 2 3007
**TO** WTC: 5528 2 2 2C
.......
**TO** WTC: 320883 2 2 3007
**TO** WTC: 321097 1 4007 F047
**TO** WTC: 321170 1 4007 7007
**TO** WTC: 321226 1 2 2B
**TO** WTC: 321357 1 6007 5007
5967297
Horiz/Vert Lines **TO** WTC: 321608 5 2001 F007
**TO** WTC: 321618 5 40 F800
**TO** WTC: 321923 1 2 7007
216005
Rectangles (outline) **TO** WTC: 322053 2 2 7E0
**TO** WTC: 322105 2 2 3007
**TO** WTC: 322190 1 4007 9007
**TO** WTC: 322677 1 2001 0
**TO** WTC: 322724 1 2 7007
**TO** WTC: 322761 1 2001 3007
**TO** WTC: 322814 1 2007 9007
**TO** WTC: 322827 1 2 3007
184190
Rectangles (filled) **TO** WTC: 323000 1 2 2B
**TO** WTC: 323039 1 2 2C
**TO** WTC: 323074 1 2 3007
**TO** WTC: 323146 1 1002 2B
**TO** WTC: 323182 1 2002 2B
**TO** WTC: 323436 1 2007 5007
**TO** WTC: 323570 1 2007 F007
**TO** WTC: 323856 1 2007 9007
4662442
Circles (filled) **TO** WTC: 323923 1 2 2C
and this is not calling the keypadloop. Notice the order of magnitude increase in the time to draw.
Not sure the cause.