2#include <initializer_list>
6#include "TinyGPU/Drivers/DisplayDriver.h"
7#include "TinyGPU/Emulation.h"
12
13
14template <
typename RGB_T =
RGB565>
22 size_t xOffset = 0, size_t yOffset = 0,
23 uint32_t frequencyHz = 40000000,
24 uint32_t readFrequencyHz = 15000000, size_t width = 240,
57 bool writeData(ISurface<RGB_T>& surface, size_t x, size_t y)
override {
58 static_assert(
sizeof(RGB_T) == 2,
59 "writeData assumes a 16bpp RGB_T (RGB565) stored in "
61 setAddressWindow(x, y, surface.width(), surface.height());
62 spi_.beginTransaction(SPISettings(frequencyHz_, MSBFIRST, SPI_MODE0));
63 digitalWrite(dc_, HIGH);
64 digitalWrite(cs_, LOW);
78 constexpr size_t kChunkBytes = 256;
79 uint8_t chunk[kChunkBytes];
80 const uint8_t* src = surface.data();
81 size_t remaining = surface.size();
82 while (remaining > 0) {
83 const size_t n = remaining < kChunkBytes ? remaining : kChunkBytes;
84 memcpy(chunk, src, n);
85 if (swapOutputBytes_) {
90 for (size_t i = 0; i + 1 < n; i += 2) {
91 const uint8_t tmp = chunk[i];
92 chunk[i] = chunk[i + 1];
96 spi_.transfer(chunk, n);
100 digitalWrite(cs_, HIGH);
101 spi_.endTransaction();
105 bool readData(ISurface<RGB_T>& surface, size_t x, size_t y) {
106 size_t w = surface.width();
107 size_t h = surface.height();
108 size_t x0 = x + xOffset_;
109 size_t y0 = y + yOffset_;
111 spi_.beginTransaction(SPISettings(readFrequencyHz_, MSBFIRST, SPI_MODE0));
112 digitalWrite(cs_, LOW);
114 digitalWrite(dc_, LOW);
116 digitalWrite(dc_, HIGH);
117 spi_.transfer((x0) >> 8);
118 spi_.transfer((x0) & 0xFF);
119 spi_.transfer((x0 + w - 1) >> 8);
120 spi_.transfer((x0 + w - 1) & 0xFF);
122 digitalWrite(dc_, LOW);
124 digitalWrite(dc_, HIGH);
125 spi_.transfer((y0) >> 8);
126 spi_.transfer((y0) & 0xFF);
127 spi_.transfer((y0 + h - 1) >> 8);
128 spi_.transfer((y0 + h - 1) & 0xFF);
130 digitalWrite(dc_, LOW);
132 digitalWrite(dc_, HIGH);
135 size_t pixelCount = w * h;
136 for (size_t i = 0; i < pixelCount; ++i) {
137 uint8_t r = spi_.transfer(0);
138 uint8_t g = spi_.transfer(0);
139 uint8_t b = spi_.transfer(0);
140 surface.setPixel(i % w, i / w, RGB_T(r, g, b));
143 digitalWrite(cs_, HIGH);
144 spi_.endTransaction();
159 writeData16(x + xOffset_, x + xOffset_ + w - 1);
161 writeData16(y + yOffset_, y + yOffset_ + h - 1);
165 setColumnRowAddress(x, y, w, h);
171 pinMode(cs_, OUTPUT);
172 pinMode(dc_, OUTPUT);
174 pinMode(rst_, OUTPUT);
175 digitalWrite(rst_, LOW);
177 digitalWrite(rst_, HIGH);
180 digitalWrite(cs_, HIGH);
184 spi_.beginTransaction(SPISettings(frequencyHz_, MSBFIRST, SPI_MODE0));
185 digitalWrite(dc_, LOW);
186 digitalWrite(cs_, LOW);
188 digitalWrite(cs_, HIGH);
189 spi_.endTransaction();
193 spi_.beginTransaction(SPISettings(frequencyHz_, MSBFIRST, SPI_MODE0));
194 digitalWrite(dc_, HIGH);
195 digitalWrite(cs_, LOW);
196 spi_.transfer(d1 >> 8);
197 spi_.transfer(d1 & 0xFF);
198 spi_.transfer(d2 >> 8);
199 spi_.transfer(d2 & 0xFF);
200 digitalWrite(cs_, HIGH);
201 spi_.endTransaction();
205 spi_.beginTransaction(SPISettings(frequencyHz_, MSBFIRST, SPI_MODE0));
206 digitalWrite(dc_, HIGH);
207 digitalWrite(cs_, LOW);
209 digitalWrite(cs_, HIGH);
210 spi_.endTransaction();
216 for (uint8_t b : bytes) {
223
224
225template <
typename RGB_T =
RGB565>
245 size_t xOffset = 2, size_t yOffset = 1, size_t width = 128,
246 size_t height = 160,
int madctl = -1)
261 writeData8(
static_cast<uint8_t>(madctl_));
272
273
274template <
typename RGB_T =
RGB565>
298
299
300
301
302
303
304
305
306
307
308
309
310
311template <
typename RGB_T =
RGB565>
331 Rotation rotation = Rotation
::kNone,
332 uint32_t frequencyHz = 40000000,
333 size_t nativeWidth = 240, size_t nativeHeight = 320)
340 return isLandscapeFamily(rotation_) ? nativeHeight_ : nativeWidth_;
343 return isLandscapeFamily(rotation_) ? nativeWidth_ : nativeHeight_;
353 writeDataN({0x03, 0x80, 0x02});
356 writeDataN({0x00, 0xC1, 0x30});
359 writeDataN({0x64, 0x03, 0x12, 0x81});
362 writeDataN({0x85, 0x00, 0x78});
365 writeDataN({0x39, 0x2C, 0x00, 0x34, 0x02});
371 writeDataN({0x00, 0x00});
380 writeDataN({0x3E, 0x28});
392 writeDataN({0x00, 0x13});
395 writeDataN({0x08, 0x82, 0x27});
404 writeDataN({0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07,
405 0x10, 0x03, 0x0E, 0x09, 0x00});
408 writeDataN({0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08,
409 0x0F, 0x0C, 0x31, 0x36, 0x0F});
426 if (rotation == Rotation
::kNone)
return;
435
436
437
438
439
440
441
442
443
444
445
446
447
448
451 writeCommand(invert ? 0x21 : 0x20);
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496template <
typename RGB_T =
RGB565>
516 Rotation rotation = Rotation
::kNone,
517 size_t nativeWidth = 240, size_t nativeHeight = 320)
524 return isLandscapeFamily(rotation_) ? nativeHeight_ : nativeWidth_;
527 return isLandscapeFamily(rotation_) ? nativeWidth_ : nativeHeight_;
537 writeDataN({0x39, 0x2C, 0x00, 0x34, 0x02});
540 writeDataN({0x00, 0xC1, 0x30});
543 writeDataN({0x85, 0x00, 0x78});
546 writeDataN({0x00, 0x00});
549 writeDataN({0x64, 0x03, 0x12, 0x81});
561 writeDataN({0x3E, 0x28});
573 writeDataN({0x00, 0x18});
576 writeDataN({0x08, 0x82, 0x27});
585 writeDataN({0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07,
586 0x10, 0x03, 0x0E, 0x09, 0x00});
589 writeDataN({0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08,
590 0x0F, 0x0C, 0x31, 0x36, 0x0F});
600 if (rotation == Rotation
::kNone)
return;
629
630
631template <
typename RGB_T =
RGB565>
655
656
657template <
typename RGB_T =
RGB565>
Common base class for SPI-based display drivers.
Definition: DisplayDriverSPI.h:15
bool readData(ISurface< RGB_T > &surface, size_t x, size_t y)
Definition: DisplayDriverSPI.h:105
void setSwapOutputBytes(bool swap)
Definition: DisplayDriverSPI.h:55
SPIClass & spi_
Definition: DisplayDriverSPI.h:149
DisplayDriverSPI(SPIClass &spi, int8_t cs, int8_t dc, int8_t rst=-1, size_t xOffset=0, size_t yOffset=0, uint32_t frequencyHz=40000000, uint32_t readFrequencyHz=15000000, size_t width=240, size_t height=320)
Definition: DisplayDriverSPI.h:21
int8_t dc_
Definition: DisplayDriverSPI.h:150
bool swapOutputBytes_
Definition: DisplayDriverSPI.h:155
size_t xOffset_
Definition: DisplayDriverSPI.h:151
uint32_t frequencyHz_
Definition: DisplayDriverSPI.h:152
size_t yOffset_
Definition: DisplayDriverSPI.h:151
size_t width_
Definition: DisplayDriverSPI.h:154
void writeDataN(std::initializer_list< uint8_t > bytes)
Definition: DisplayDriverSPI.h:215
size_t height_
Definition: DisplayDriverSPI.h:154
size_t height() const override
Definition: DisplayDriverSPI.h:38
void setColumnRowAddress(size_t x, size_t y, size_t w, size_t h)
Definition: DisplayDriverSPI.h:157
int8_t cs_
Definition: DisplayDriverSPI.h:150
int8_t rst_
Definition: DisplayDriverSPI.h:150
void setupPinsAndReset()
Definition: DisplayDriverSPI.h:170
void writeCommand(uint8_t cmd)
Definition: DisplayDriverSPI.h:183
bool writeData(ISurface< RGB_T > &surface, size_t x, size_t y) override
Definition: DisplayDriverSPI.h:57
size_t width() const override
Definition: DisplayDriverSPI.h:37
bool setAddressWindow(size_t x, size_t y, size_t w, size_t h) override
Definition: DisplayDriverSPI.h:164
void writeData8(uint8_t data)
Definition: DisplayDriverSPI.h:204
uint32_t readFrequencyHz_
Definition: DisplayDriverSPI.h:153
bool writeData(ISurface< RGB_T > &surface) override
Definition: DisplayDriverSPI.h:40
void writeData16(uint16_t d1, uint16_t d2)
Definition: DisplayDriverSPI.h:192
Definition: DisplayDriver.h:49
Driver for HX8357 SPI display controller.
Definition: DisplayDriverSPI.h:632
HX8357Driver(SPIClass &spi, int8_t cs, int8_t dc, int8_t rst=-1)
Definition: DisplayDriverSPI.h:638
bool begin() override
Definition: DisplayDriverSPI.h:641
Driver for ILI9341 SPI display controller.
Definition: DisplayDriverSPI.h:312
static uint8_t madctlForRotation(Rotation rotation)
Definition: DisplayDriverSPI.h:464
size_t nativeHeight_
Definition: DisplayDriverSPI.h:456
size_t nativeWidth_
Definition: DisplayDriverSPI.h:456
void setInvertColor(bool invert)
Toggles the ILI9341's display inversion (DINVON/DINVOFF, 0x21/ 0x20). Some cheap ILI9341-compatible c...
Definition: DisplayDriverSPI.h:449
ILI9341Driver(SPIClass &spi, int8_t cs, int8_t dc, int8_t rst=-1, Rotation rotation=Rotation::kNone, uint32_t frequencyHz=40000000, size_t nativeWidth=240, size_t nativeHeight=320)
Definition: DisplayDriverSPI.h:330
size_t height() const override
Definition: DisplayDriverSPI.h:342
size_t width() const override
Definition: DisplayDriverSPI.h:339
Rotation rotation() const
Definition: DisplayDriverSPI.h:432
bool invertColor_
Definition: DisplayDriverSPI.h:458
bool begin() override
Definition: DisplayDriverSPI.h:346
void setRotation(Rotation rotation) override
Definition: DisplayDriverSPI.h:425
Rotation rotation_
Definition: DisplayDriverSPI.h:455
Driver for ILI9342 SPI display controller.
Definition: DisplayDriverSPI.h:497
static uint8_t madctlForRotation(Rotation rotation)
Definition: DisplayDriverSPI.h:612
size_t nativeHeight_
Definition: DisplayDriverSPI.h:610
size_t nativeWidth_
Definition: DisplayDriverSPI.h:610
size_t height() const override
Definition: DisplayDriverSPI.h:526
ILI9342Driver(SPIClass &spi, int8_t cs, int8_t dc, int8_t rst=-1, Rotation rotation=Rotation::kNone, size_t nativeWidth=240, size_t nativeHeight=320)
Definition: DisplayDriverSPI.h:515
size_t width() const override
Definition: DisplayDriverSPI.h:523
Rotation rotation() const
Definition: DisplayDriverSPI.h:606
bool begin() override
Definition: DisplayDriverSPI.h:530
void setRotation(Rotation rotation) override
Definition: DisplayDriverSPI.h:599
Rotation rotation_
Definition: DisplayDriverSPI.h:609
RGB color stored in 16-bit RGB565 format, byte-swapped from the conventional bit layout.
Definition: RGB565.h:24
Driver for ST7735 SPI display controller.
Definition: DisplayDriverSPI.h:226
ST7735Driver(SPIClass &spi, int8_t cs, int8_t dc, int8_t rst=-1, size_t xOffset=2, size_t yOffset=1, size_t width=128, size_t height=160, int madctl=-1)
Definition: DisplayDriverSPI.h:244
bool begin() override
Definition: DisplayDriverSPI.h:251
Driver for ST7789 SPI display controller.
Definition: DisplayDriverSPI.h:275
ST7789Driver(SPIClass &spi, int8_t cs, int8_t dc, int8_t rst=-1)
Definition: DisplayDriverSPI.h:281
bool begin() override
Definition: DisplayDriverSPI.h:284
Driver for ST7796 SPI display controller.
Definition: DisplayDriverSPI.h:658
ST7796Driver(SPIClass &spi, int8_t cs, int8_t dc, int8_t rst=-1)
Definition: DisplayDriverSPI.h:664
bool begin() override
Definition: DisplayDriverSPI.h:667
Definition: DSIBusESP32.h:19
void delay(unsigned long ms)
Definition: EmulationDesktop.h:52
DisplayRotation
Abstract base class for display drivers.
Definition: DisplayDriver.h:28