//#define TFT_ST7735 1
#define TFT_ST7789 1
//#define TFT_ILI9341 1
#if defined(TFT_ST7789) || defined(TFT_ST7735)
//ST7735 Adafruit 320x240 display
#include <ST7735_t3.h>
#include <ST7789_t3.h>
#include <font_Arial.h>
#include <font_ArialBold.h>
#else
#include <ILI9341_fonts.h>
#include <ILI9341_t3n.h>
#include <font_Arial.h>
#include <font_ArialBold.h>
#endif
elapsedMicros _dt;
#define dtSTART {_dt=0;}
#define dtEND(a) { Serial.printf( "\n%s()_%s : dt %ul us", __func__, a, (uint32_t)_dt);}
#define UPDATE_HALF_FRAME
#define ROTATION 3
#include "SPI.h"
//------------------------------------
#if defined(TFT_ST7789) || defined(TFT_ST7735)
#ifdef ARDUINO_TEENSY_MICROMOD
#define TFT_DC 1 // "TX1" on left side of Sparkfun ML Carrier
#define TFT_CS 4 // "CS" on left side of Sparkfun ML Carrier
#define TFT_RST 0 // "RX1" on left side of Sparkfun ML Carrier
#else
#define TFT_DC 9 // "TX1" on left side of Sparkfun ML Carrier
#define TFT_CS 10 // "CS" on left side of Sparkfun ML Carrier
#define TFT_RST 8 // "RX1" on left side of Sparkfun ML Carrier
#endif
#ifdef TFT_ST7789
ST7789_t3 tft = ST7789_t3(TFT_CS, TFT_DC, TFT_RST);
#else
ST7735_t3 tft = ST7735_t3(TFT_CS, TFT_DC, TFT_RST);
#endif
#define TFT_BLACK ST77XX_BLACK
#define TFT_YELLOW ST77XX_YELLOW
#define TFT_RED ST77XX_RED
#define TFT_GREEN ST77XX_GREEN
#define TFT_BLUE ST77XX_BLUE
#define TCENTER ST7735_t3::CENTER
uint16_t our_pallet[] = {
TFT_BLACK, TFT_RED, TFT_GREEN, TFT_BLUE,
ST77XX_YELLOW, ST77XX_ORANGE, ST77XX_CYAN,ST77XX_PINK
};
#else
#define TFT_BLACK ILI9341_BLACK
#define TFT_YELLOW ILI9341_YELLOW
#define TFT_RED ILI9341_RED
#define TFT_GREEN ILI9341_GREEN
#define TFT_BLUE ILI9341_BLUE
#define TCENTER ILI9341_t3n::CENTER
#define USE_SPI2
#ifdef USE_SPI2
#define TFT_DC 44
#define TFT_RST 46
#define TFT_CS 47 // any pin will work not hardware
// T4.1 SCK pins on SDCARD
#define USE_MEMORY_PINS
#ifdef USE_MEMORY_PINS
#define TFT_SCK 49
#define TFT_MISO 54
#define TFT_MOSI 50
#else
#define TFT_SCK 45
#define TFT_MISO 42
#define TFT_MOSI 43
#endif
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);
#else
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);
#endif
uint16_t our_pallet[] = {
ILI9341_BLACK, ILI9341_RED, ILI9341_GREEN, ILI9341_BLUE,
ILI9341_YELLOW, ILI9341_ORANGE, ILI9341_CYAN, ILI9341_PINK
};
#endif
#define COUNT_SHUTDOWN_FRAMES 16
volatile uint8_t shutdown_cont_update_count = 0xff;
uint16_t *tft_frame_buffer = nullptr;
#define FRAME_BUFFER_SIZE (320*240*2)
elapsedMicros my_us;
void setup() {
while (!Serial && (millis() < 4000)) ;
Serial.begin(115200);
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
Serial.printf("Begin: CS:%d, DC:%dRST: %d\n", TFT_CS, TFT_DC, TFT_RST);
#ifdef TFT_ST7789
//tft.init(240, 240); // Init ST7789 320x240
tft.init(240, 320); // Init ST7789 320x240
#elif defined(TFT_ST7735)
// Use this initializer if you're using a 1.8" TFT 128x160 displays
//tft.initR(INITR_BLACKTAB);
// Or use this initializer (uncomment) if you're using a 1.44" TFT (128x128)
tft.initR(INITR_144GREENTAB);
// Or use this initializer (uncomment) if you're using a .96" TFT(160x80)
//tft.initR(INITR_MINI160x80);
#else
tft.begin(26000000);
#endif
tft.setRotation(ROTATION);
tft.fillScreen(TFT_RED);
delay(500);
tft.fillScreen(TFT_GREEN);
delay(500);
tft.fillScreen(TFT_BLUE);
delay(500);
tft.fillScreen(TFT_BLACK);
delay(500);
tft.useFrameBuffer(true);
tft.fillScreen(TFT_BLACK);
tft.setCursor(TCENTER, TCENTER);
tft.setTextColor(TFT_RED);
tft.setFont(Arial_20_Bold);
tft.println("*** Auto start ***");
tft.updateScreen();
tft_frame_buffer = tft.getFrameBuffer();
delay(250);
#ifdef UPDATE_HALF_FRAME
tft.setFrameCompleteCB(&frame_callback, true);
#else
tft.setFrameCompleteCB(&frame_callback, false);
#endif
// We are not running DMA currently so start it up.
Serial.println("Starting up DMA Updates");
shutdown_cont_update_count = 0xff;
tft.updateScreenAsync(true);
Serial.println("==================================================");
Serial.println("\n*** Commands ***");
Serial.println(" t - Toggle display updates on or off");
}
void frame_callback() {
//Serial.printf("FCB: %d %d\n", tft.frameCount(), tft.subFrameCount());
uint32_t frameCount = tft.frameCount();
// See if end of test signalled.
if (shutdown_cont_update_count == COUNT_SHUTDOWN_FRAMES) {
uint8_t color_index = (frameCount >> 4) & 0x7;
tft.setCursor(TCENTER, TCENTER);
tft.setTextColor(our_pallet[(color_index + 3) & 7]);
tft.setFont(Arial_20_Bold);
tft.println("Stop Signalled");
shutdown_cont_update_count--;
arm_dcache_flush(tft_frame_buffer, FRAME_BUFFER_SIZE);
} else if (shutdown_cont_update_count == 0) {
tft.setCursor(TCENTER, tft.getCursorY());
tft.println("endUpdateAsync");
tft.endUpdateAsync();
Serial.println("after endUpdateAsync");
arm_dcache_flush(tft_frame_buffer, FRAME_BUFFER_SIZE);
} else if (shutdown_cont_update_count < COUNT_SHUTDOWN_FRAMES) {
shutdown_cont_update_count--;
} else {
#ifdef UPDATE_HALF_FRAME
bool draw_frame = false;
if (((frameCount & 0xf) == 0) && tft.subFrameCount()) {
draw_frame = true;
tft.setClipRect(0, 0, tft.width(), tft.height() / 2);
} else if (((frameCount & 0xf) == 1) && !tft.subFrameCount()) {
draw_frame = true;
tft.setClipRect(0, tft.height() / 2, tft.width(), tft.height() / 2);
}
if (draw_frame)
#else
if (tft.subFrameCount()) {
// lets ignore these right now
return;
}
if ((frameCount & 0xf) == 0)
#endif
{
// First pass ignore subframe...
uint8_t color_index = (frameCount >> 4) & 0x7;
tft.fillScreen(our_pallet[color_index]);
tft.drawRect(5, 5, tft.width() - 10, tft.height() - 10, our_pallet[(color_index + 1) & 7]);
tft.drawRect(25, 25, tft.width() - 50, tft.height() - 50, our_pallet[(color_index + 2) & 7]);
static uint8_t display_other = 0;
switch (display_other) {
case 0:
tft.fillRect(50, 50, tft.width() - 100, tft.height() - 100, our_pallet[(color_index + 1) & 7]);
break;
case 1:
tft.fillCircle(tft.width() / 2, tft.height() / 2, 100, our_pallet[(color_index + 1) & 7]);
break;
case 2:
tft.fillTriangle(50, 50, tft.width() - 50, 50, tft.width() / 2, tft.height() - 50, our_pallet[(color_index + 1) & 7]);
break;
}
if (!tft.subFrameCount()) {
display_other++;
if (display_other > 2) display_other = 0 ;
}
arm_dcache_flush(tft_frame_buffer, FRAME_BUFFER_SIZE);
tft.setClipRect();
}
}
}
void loop(void) {
// See if any text entered
int ich;
if ((ich = Serial.read()) != -1) {
while (Serial.read() != -1) ;
switch (ich) {
case 't':
toggleOnOffDisplay();
break;
}
}
}
void toggleOnOffDisplay() {
if (!tft.asyncUpdateActive()) {
// We are not running DMA currently so start it up.
Serial.println("Starting up DMA Updates");
shutdown_cont_update_count = 0xff;
tft.updateScreenAsync(true);
} else {
shutdown_cont_update_count = COUNT_SHUTDOWN_FRAMES;
while (shutdown_cont_update_count) ;
tft.waitUpdateAsyncComplete();
tft.setCursor(TCENTER, tft.getCursorY());
tft.print("Finished Test\n");
Serial.println("after waitUpdateAsyncComplete");
Serial.println("Finished test");
delay(2000);
Serial.println("Do normal update to see if data is there");
tft.updateScreen();
}
}