#define LGFX_USE_V1
#include <LovyanGFX.hpp>
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_ILI9341 _panel;
lgfx::Bus_SPI _bus;
public:
LGFX(void)
{
{
auto cfg = _bus.config();
cfg.spi_host = VSPI_HOST;
cfg.spi_mode = 0;
// 80MHz works on many CYD boards
cfg.freq_write = 80000000;
cfg.freq_read = 20000000;
cfg.spi_3wire = false;
cfg.use_lock = true;
cfg.dma_channel = SPI_DMA_CH_AUTO;
cfg.pin_sclk = 14;
cfg.pin_mosi = 13;
cfg.pin_miso = 12;
cfg.pin_dc = 2;
_bus.config(cfg);
_panel.setBus(&_bus);
}
{
auto cfg = _panel.config();
cfg.pin_cs = 15;
cfg.pin_rst = -1;
cfg.pin_busy = -1;
cfg.memory_width = 240;
cfg.memory_height = 320;
cfg.panel_width = 240;
cfg.panel_height = 320;
cfg.offset_x = 0;
cfg.offset_y = 0;
cfg.offset_rotation = 0;
cfg.dummy_read_pixel = 8;
cfg.dummy_read_bits = 1;
cfg.readable = true;
cfg.invert = false;
cfg.rgb_order = false;
cfg.dlen_16bit = false;
cfg.bus_shared = true;
_panel.config(cfg);
}
setPanel(&_panel);
}
};
LGFX tft;
// DMA sprite buffer
LGFX_Sprite sprite(&tft);
#define TFT_BL 21
uint32_t frameCount = 0;
uint32_t lastMillis = 0;
void setup()
{
Serial.begin(115200);
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);
tft.init();
tft.setRotation(1);
// Create framebuffer in RAM
sprite.setColorDepth(16);
// Full screen sprite
sprite.createSprite(320, 240);
sprite.setTextDatum(middle_center);
tft.fillScreen(TFT_BLACK);
}
void loop()
{
static float angle = 0;
// Direct framebuffer access
sprite.fillScreen(TFT_BLACK);
int cx = 160;
int cy = 120;
// FAST rotating lines
for (int i = 0; i < 360; i += 8)
{
float a = (i + angle) * 0.0174532925;
int x = cx + cos(a) * 110;
int y = cy + sin(a) * 110;
sprite.drawLine(cx, cy, x, y,
sprite.color565(
abs(sin(a) * 255),
abs(cos(a) * 255),
255
));
}
// Moving circles
for (int i = 0; i < 20; i++)
{
int x = 160 + sin((millis() * 0.002f) + i) * 100;
int y = 120 + cos((millis() * 0.003f) + i) * 80;
sprite.fillCircle(x, y, 10,
sprite.color565(i * 10, 255 - i * 10, 128));
}
// FPS Counter
frameCount++;
if (millis() - lastMillis >= 1000)
{
Serial.printf("FPS: %lu\n", frameCount);
frameCount = 0;
lastMillis = millis();
}
sprite.setTextColor(TFT_WHITE);
sprite.setTextSize(2);
sprite.drawString("ESP32 CYD FAST DMA", 160, 20);
// DMA transfer to LCD
sprite.pushSprite(0, 0);
angle += 2;
}