3
4
5
6
7
8
9
10#include "TinyGPU/Emulation.h"
12#if defined(ARDUINO_ARCH_STM32)
24#include "TinyGPU/Boards/LCDBoardsCommon.h"
25#include "TinyGPU/Drivers/DisplayDriver.h"
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52class ST7735DriverHardwareSPI :
public DisplayDriver<RGB565> {
57 ST7735DriverHardwareSPI(SPIClass& spi, int8_t cs, int8_t dc, int8_t rst,
58 size_t xOffset, size_t yOffset, size_t width,
59 size_t height, uint8_t madctl,
60 uint32_t frequencyHz = 15000000)
70 frequencyHz_(frequencyHz) {}
72 size_t width()
const override {
return width_; }
73 size_t height()
const override {
return height_; }
75 bool begin() override {
78 digitalWrite(cs_, HIGH);
82 pinMode(rst_, OUTPUT);
83 digitalWrite(rst_, HIGH);
85 digitalWrite(rst_, LOW);
87 digitalWrite(rst_, HIGH);
106 uint8_t colmod = 0x05;
107 writeCommand(0x3A, &colmod, 1);
108 uint8_t madctlData = madctl_;
109 writeCommand(0x36, &madctlData, 1);
115 bool writeData(ISurface<RGB565>& surface) override {
116 return writeData(surface, 0, 0);
119 bool writeData(ISurface<RGB565>& surface, size_t x, size_t y) override {
121 setAddressWindow(x, y, surface.width(), surface.height());
126 const uint8_t* src = surface.data();
127 const size_t n = surface.size();
132 constexpr size_t kChunkBytes = 256;
133 uint8_t chunk[kChunkBytes];
134 size_t remaining = n;
135 const uint8_t* p = src;
136 while (remaining > 0) {
137 const size_t c = remaining < kChunkBytes ? remaining : kChunkBytes;
139 spi_.transfer(chunk, c);
143 digitalWrite(cs_, HIGH);
149 bool setAddressWindow(size_t x, size_t y, size_t w, size_t h) override {
151 static_cast<uint8_t>((x + xOffset_) >> 8),
152 static_cast<uint8_t>((x + xOffset_) & 0xFF),
153 static_cast<uint8_t>((x + xOffset_ + w - 1) >> 8),
154 static_cast<uint8_t>((x + xOffset_ + w - 1) & 0xFF)};
155 writeCommand(0x2A, caset, 4);
157 static_cast<uint8_t>((y + yOffset_) >> 8),
158 static_cast<uint8_t>((y + yOffset_) & 0xFF),
159 static_cast<uint8_t>((y + yOffset_ + h - 1) >> 8),
160 static_cast<uint8_t>((y + yOffset_ + h - 1) & 0xFF)};
161 writeCommand(0x2B, raset, 4);
164 digitalWrite(cs_, LOW);
165 digitalWrite(dc_, LOW);
166 spi_.transfer(
static_cast<uint8_t>(0x2C));
167 digitalWrite(dc_, HIGH);
173 int8_t cs_, dc_, rst_;
174 size_t xOffset_, yOffset_, width_, height_;
176 uint32_t frequencyHz_;
178 void beginTransaction() {
179 spi_.beginTransaction(SPISettings(frequencyHz_, MSBFIRST, SPI_MODE0));
181 void endTransaction() { spi_.endTransaction(); }
194 void writeCommand(uint8_t cmd,
const uint8_t* data =
nullptr,
196 digitalWrite(cs_, LOW);
197 digitalWrite(dc_, LOW);
200 digitalWrite(dc_, HIGH);
201 for (size_t i = 0; i < len; ++i) {
202 spi_.transfer(data[i]);
205 digitalWrite(cs_, HIGH);
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232class LCDBoardWeActMiniSTM32H750 :
public LCDBoard {
236 bool begin() override {
237 pinMode(kPinBacklight, OUTPUT);
238 analogWrite(kPinBacklight, 180);
240 return display_.begin();
244 size_t width()
const override {
return 160; }
246 size_t height()
const override {
return 80; }
249 ST7735DriverHardwareSPI& display() override {
return display_; }
251 TouchDriver* touch() override {
return nullptr; }
253 const I2SPins& i2s()
const override {
return i2s_; }
255 const LEDPins& led()
const override {
return led_; }
257 int8_t backlightPin()
const override {
return kPinBacklight; }
260 static constexpr int8_t kPinCs = PE11;
261 static constexpr int8_t kPinDc = PE13;
262 static constexpr int8_t kPinRst = PE15;
263 static constexpr int8_t kPinSck = PE12;
264 static constexpr int8_t kPinMosi = PE14;
265 static constexpr int8_t kPinBacklight = PE10;
273 static constexpr int8_t kPinMisoWorkaround = PE5;
275 SPIClass spi_{kPinMosi, kPinMisoWorkaround, kPinSck};
285 ST7735DriverHardwareSPI display_{spi_,
298using MiniSTM32H750 = LCDBoardWeActMiniSTM32H750;
299using MiniSTM32H7xx = LCDBoardWeActMiniSTM32H750;