many updates..
new sensors.. display.. led.. drawing.. stuff..
This commit is contained in:
190
ext/lcd/Draw.h
Normal file
190
ext/lcd/Draw.h
Normal file
@@ -0,0 +1,190 @@
|
||||
#ifndef LCD_DRAW
|
||||
#define LCD_DRAW
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include "../../data/Color.h"
|
||||
//struct RGB {
|
||||
|
||||
// uint8_t r;
|
||||
// uint8_t g;
|
||||
// uint8_t b;
|
||||
|
||||
// RGB() : r(0), g(0), b(0) {;}
|
||||
// RGB(uint8_t r, uint8_t g, uint8_t b) : r(r), g(g), b(b) {;}
|
||||
|
||||
// uint16_t toRGB565() const {
|
||||
// return
|
||||
// ((r >> 3) << 11) |
|
||||
// ((g >> 2) << 5) |
|
||||
// ((b >> 3) << 0);
|
||||
// }
|
||||
|
||||
//};
|
||||
|
||||
class FontWrap {
|
||||
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
const uint8_t* data;
|
||||
const uint16_t* offsets;
|
||||
|
||||
static constexpr uint8_t off = 32;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
FontWrap(const uint16_t w, const uint16_t h, const uint8_t* data, const uint16_t* offsets) : w(w), h(h), data(data), offsets(offsets) {
|
||||
;
|
||||
}
|
||||
|
||||
/** get the pixel-width of the given char */
|
||||
uint8_t getCharWidht(char c) const {
|
||||
if (c == 32) {return 3;} // whitespace
|
||||
return offsets[c-off+1] - offsets[c-off];
|
||||
}
|
||||
|
||||
uint8_t getHeight() const {
|
||||
return h;
|
||||
}
|
||||
|
||||
uint16_t getWidth(const char* txt) const {
|
||||
uint16_t sum = 0;
|
||||
while(*txt) {
|
||||
sum += getCharWidht(*txt);
|
||||
++txt;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/** draw the given char at the given position */
|
||||
template <typename Scalar, typename Destination> void draw(const char* c, Scalar dx, Scalar dy, Destination& dst) {
|
||||
while(*c) {
|
||||
draw(*c, dx, dy, dst);
|
||||
dx += getCharWidht(*c);// + 1;
|
||||
++c;
|
||||
}
|
||||
}
|
||||
|
||||
/** draw the given char at the given position */
|
||||
template <typename Scalar, typename Destination> void draw(unsigned char c, Scalar dx, Scalar dy, Destination& dst) {
|
||||
|
||||
if (c == 32) {return;} // skip whitespace
|
||||
|
||||
|
||||
const uint16_t x1 = offsets[c-off];
|
||||
const uint16_t x2 = offsets[c-off+1];
|
||||
const uint16_t y1 = 0;
|
||||
const uint16_t y2 = h;
|
||||
|
||||
for (uint16_t y = y1; y < y2; ++y) {
|
||||
for (uint16_t x = x1; x < x2; ++x) {
|
||||
const uint16_t idx = (x/8) + (y*this->w/8);
|
||||
const uint8_t pixel = data[idx] & (1<<(x&7));
|
||||
if (pixel) {
|
||||
dst.setPixel(dx+x-x1, dy+y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename Scalar, typename Destination> class Draw {
|
||||
|
||||
Destination& dst;
|
||||
|
||||
public:
|
||||
|
||||
Draw(Destination& dst) : dst(dst) {
|
||||
|
||||
}
|
||||
|
||||
void set(const Scalar x1, const Scalar y1) {
|
||||
dst.set(x1, y1);
|
||||
}
|
||||
|
||||
void setColor(const Color color) {
|
||||
dst.setColor(color);
|
||||
}
|
||||
|
||||
/** draw a line from (x0,y0) to (x1,y1) */
|
||||
void drawLine(Scalar x1, Scalar y1, const Scalar x2, const Scalar y2) {
|
||||
|
||||
// int dx, dy, p, x, y;
|
||||
|
||||
// dx=x1-x0;
|
||||
// dy=y1-y0;
|
||||
|
||||
// x=x0;
|
||||
// y=y0;
|
||||
|
||||
// p=2*dy-dx;
|
||||
|
||||
// while(x < x1) {
|
||||
// if(p >= 0) {
|
||||
// dst.set(x,y);
|
||||
// y=y+1;
|
||||
// p=p+2*dy-2*dx;
|
||||
// } else {
|
||||
// dst.set(x,y);
|
||||
// p=p+2*dy;
|
||||
// }
|
||||
// x=x+1;
|
||||
// }
|
||||
|
||||
Scalar dx = abs(x2-x1);
|
||||
Scalar sx = (x1<x2 ? 1 : -1);
|
||||
Scalar dy = -abs(y2-y1);
|
||||
Scalar sy = (y1<y2 ? 1 : -1);
|
||||
Scalar err = dx+dy;
|
||||
Scalar e2;
|
||||
|
||||
while( (x1!=x2) || (y1!=y2) ) {
|
||||
dst.setPixel(x1,y1);
|
||||
e2 = 2*err;
|
||||
if (e2 > dy) { err += dy; x1 += sx; }
|
||||
if (e2 < dx) { err += dx; y1 += sy; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void fillRect(const Scalar x, const Scalar y, const Scalar w, const Scalar h) {
|
||||
dst.fillRect(x,y,w,h);
|
||||
}
|
||||
|
||||
void drawLineHor(const Scalar x1, const Scalar x2, const Scalar y) {
|
||||
dst.fillRect(x1,y,x2-x1,1);
|
||||
}
|
||||
void drawLineVer(const Scalar y1, const Scalar y2, const Scalar x) {
|
||||
dst.fillRect(x,y1,1,y2-y1);
|
||||
}
|
||||
|
||||
void drawRect(const Scalar x, const Scalar y, const Scalar w, const Scalar h) {
|
||||
drawLineHor(x,x+w, y); // top
|
||||
drawLineHor(x,x+w, y+h); // bottom
|
||||
drawLineVer(y,y+h, x); // left
|
||||
drawLineVer(y,y+h, x+w); // right
|
||||
}
|
||||
|
||||
// void drawRect(const Scalar x1, const Scalar y1, const Scalar x2, const Scalar y2) {
|
||||
|
||||
// for (Scalar s = x1; s <= x2; ++s) {dst.set(s, y1);}
|
||||
// for (Scalar s = x1; s <= x2; ++s) {dst.set(s, y2);}
|
||||
|
||||
// for (Scalar s = y1+1; s < y2; ++s) {dst.set(x1, s);}
|
||||
// for (Scalar s = y1+1; s < y2; ++s) {dst.set(x2, s);}
|
||||
|
||||
// }
|
||||
|
||||
Scalar abs(Scalar v) const {
|
||||
if (v >= 0) {return v;}
|
||||
return -v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
365
ext/lcd/ILI9341.h
Normal file
365
ext/lcd/ILI9341.h
Normal file
@@ -0,0 +1,365 @@
|
||||
#ifndef LCD_ILI9341
|
||||
#define LCD_ILI9341
|
||||
|
||||
#include "../../Debug.h"
|
||||
|
||||
// https://github.com/adafruit/Adafruit_ILI9341/blob/master/Adafruit_ILI9341.cpp
|
||||
// https://github.com/adafruit/Adafruit_ILI9341/blob/master/Adafruit_ILI9341.h
|
||||
|
||||
// http://datasheets.gpio.dk/dl/ILI9341.pdf
|
||||
|
||||
// e.g.
|
||||
// TJCTM24024-SPI
|
||||
// http://play.fallows.ca/wp/projects/electronics-projects/tjctm24024-mystery-modules-china/
|
||||
// http://datasheets.gpio.dk/dl/2.4inch-tft-touch/2.4%25e4%25b8%25b2%25e5%258f%25a3_TJC-024-9341/Module_SCH.pdf
|
||||
// http://datasheets.gpio.dk/dl/ILI9341.pdf
|
||||
|
||||
#define ILI9341_TFTWIDTH 240 ///< ILI9341 max TFT width
|
||||
#define ILI9341_TFTHEIGHT 320 ///< ILI9341 max TFT height
|
||||
|
||||
#define ILI9341_NOP 0x00 ///< No-op register
|
||||
#define ILI9341_SWRESET 0x01 ///< Software reset register
|
||||
#define ILI9341_RDDID 0x04 ///< Read display identification information
|
||||
#define ILI9341_RDDST 0x09 ///< Read Display Status
|
||||
|
||||
#define ILI9341_SLPIN 0x10 ///< Enter Sleep Mode
|
||||
#define ILI9341_SLPOUT 0x11 ///< Sleep Out
|
||||
#define ILI9341_PTLON 0x12 ///< Partial Mode ON
|
||||
#define ILI9341_NORON 0x13 ///< Normal Display Mode ON
|
||||
|
||||
#define ILI9341_RDMODE 0x0A ///< Read Display Power Mode
|
||||
#define ILI9341_RDMADCTL 0x0B ///< Read Display MADCTL
|
||||
#define ILI9341_RDPIXFMT 0x0C ///< Read Display Pixel Format
|
||||
#define ILI9341_RDIMGFMT 0x0D ///< Read Display Image Format
|
||||
#define ILI9341_RDSELFDIAG 0x0F ///< Read Display Self-Diagnostic Result
|
||||
|
||||
#define ILI9341_INVOFF 0x20 ///< Display Inversion OFF
|
||||
#define ILI9341_INVON 0x21 ///< Display Inversion ON
|
||||
#define ILI9341_GAMMASET 0x26 ///< Gamma Set
|
||||
#define ILI9341_DISPOFF 0x28 ///< Display OFF
|
||||
#define ILI9341_DISPON 0x29 ///< Display ON
|
||||
|
||||
#define ILI9341_CASET 0x2A ///< Column Address Set
|
||||
#define ILI9341_PASET 0x2B ///< Page Address Set
|
||||
#define ILI9341_RAMWR 0x2C ///< Memory Write
|
||||
#define ILI9341_RAMRD 0x2E ///< Memory Read
|
||||
|
||||
#define ILI9341_PTLAR 0x30 ///< Partial Area
|
||||
#define ILI9341_MADCTL 0x36 ///< Memory Access Control
|
||||
#define ILI9341_VSCRSADD 0x37 ///< Vertical Scrolling Start Address
|
||||
#define ILI9341_PIXFMT 0x3A ///< COLMOD: Pixel Format Set
|
||||
|
||||
#define ILI9341_FRMCTR1 0xB1 ///< Frame Rate Control (In Normal Mode/Full Colors)
|
||||
#define ILI9341_FRMCTR2 0xB2 ///< Frame Rate Control (In Idle Mode/8 colors)
|
||||
#define ILI9341_FRMCTR3 0xB3 ///< Frame Rate control (In Partial Mode/Full Colors)
|
||||
#define ILI9341_INVCTR 0xB4 ///< Display Inversion Control
|
||||
#define ILI9341_DFUNCTR 0xB6 ///< Display Function Control
|
||||
|
||||
#define ILI9341_PWCTR1 0xC0 ///< Power Control 1
|
||||
#define ILI9341_PWCTR2 0xC1 ///< Power Control 2
|
||||
#define ILI9341_PWCTR3 0xC2 ///< Power Control 3
|
||||
#define ILI9341_PWCTR4 0xC3 ///< Power Control 4
|
||||
#define ILI9341_PWCTR5 0xC4 ///< Power Control 5
|
||||
#define ILI9341_VMCTR1 0xC5 ///< VCOM Control 1
|
||||
#define ILI9341_VMCTR2 0xC7 ///< VCOM Control 2
|
||||
|
||||
#define ILI9341_RDID1 0xDA ///< Read ID 1
|
||||
#define ILI9341_RDID2 0xDB ///< Read ID 2
|
||||
#define ILI9341_RDID3 0xDC ///< Read ID 3
|
||||
#define ILI9341_RDID4 0xDD ///< Read ID 4
|
||||
|
||||
#define ILI9341_GMCTRP1 0xE0 ///< Positive Gamma Correction
|
||||
#define ILI9341_GMCTRN1 0xE1 ///< Negative Gamma Correction
|
||||
//#define ILI9341_PWCTR6 0xFC
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "../../io/SoftSPI.h"
|
||||
#include "../../io/HardSPI.h"
|
||||
|
||||
|
||||
static constexpr const uint8_t initcmd[] = {
|
||||
0xEF, 3, 0x03, 0x80, 0x02,
|
||||
0xCF, 3, 0x00, 0xC1, 0x30,
|
||||
0xED, 4, 0x64, 0x03, 0x12, 0x81,
|
||||
0xE8, 3, 0x85, 0x00, 0x78,
|
||||
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
||||
0xF7, 1, 0x20,
|
||||
0xEA, 2, 0x00, 0x00,
|
||||
ILI9341_PWCTR1, 1, 0x23, // Power control VRH[5:0]
|
||||
ILI9341_PWCTR2, 1, 0x10, // Power control SAP[2:0];BT[3:0]
|
||||
ILI9341_VMCTR1, 2, 0x3e, 0x28, // VCM control
|
||||
ILI9341_VMCTR2, 1, 0x86, // VCM control2
|
||||
ILI9341_MADCTL, 1, 0x48, // Memory Access Control
|
||||
ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero
|
||||
ILI9341_PIXFMT, 1, 0x55,
|
||||
ILI9341_FRMCTR1, 2, 0x00, 0x18,
|
||||
ILI9341_DFUNCTR, 3, 0x08, 0x82, 0x27, // Display Function Control
|
||||
0xF2, 1, 0x00, // 3Gamma Function Disable
|
||||
ILI9341_GAMMASET, 1, 0x01, // Gamma curve selected
|
||||
ILI9341_GMCTRP1, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
|
||||
ILI9341_GMCTRN1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, // Set Gamma
|
||||
//ILI9341_SLPOUT, 0x80, // Exit Sleep
|
||||
//ILI9341_DISPON, 0x80, // Display on
|
||||
0x00 // End of list
|
||||
};
|
||||
|
||||
//template <int PIN_CS, int PIN_MISO, int PIN_MOSI, int PIN_CLK, int PIN_DATA_COMMAND> class ILI9341 {
|
||||
template <int PIN_CS, int PIN_DATA_COMMAND, typename SPI> class ILI9341 {
|
||||
|
||||
private:
|
||||
|
||||
int w = 240;
|
||||
int h = 320;
|
||||
|
||||
static constexpr const char* MOD = "ILI9341";
|
||||
|
||||
//HardSPI<PIN_MISO, PIN_MOSI, PIN_CLK> spi;
|
||||
//SoftSPI<PIN_MISO, PIN_MOSI, PIN_CLK, true> spi;
|
||||
SPI& spi;
|
||||
|
||||
public:
|
||||
|
||||
ILI9341(SPI& spi) : spi(spi) {
|
||||
|
||||
GPIO::setOutput(PIN_DATA_COMMAND);
|
||||
GPIO::setOutput(PIN_CS);
|
||||
|
||||
//spi.init();
|
||||
|
||||
}
|
||||
|
||||
void setPixel(const uint16_t x, const uint16_t y, const uint16_t color) {
|
||||
chipSelect();
|
||||
setAddrWindow(x,y,1,1);
|
||||
sendWord(color);
|
||||
chipDeselect();
|
||||
}
|
||||
|
||||
void setPixel(const uint16_t x, const uint16_t y, const uint8_t w, const uint16_t color) {
|
||||
chipSelect();
|
||||
setAddrWindow(x-w/2,y-w/2,w,w);
|
||||
for (int i = 0; i < w*w; ++i) {
|
||||
sendWord(color);
|
||||
}
|
||||
chipDeselect();
|
||||
}
|
||||
|
||||
/** perform display software reset and initialization */
|
||||
void init() {
|
||||
|
||||
chipSelect();
|
||||
|
||||
// send reset command
|
||||
wait();
|
||||
sendCommand(ILI9341_SWRESET);
|
||||
wait();
|
||||
|
||||
// send init sequence
|
||||
const uint8_t* bytes = initcmd;
|
||||
while(*bytes) {
|
||||
const uint8_t cmd = *bytes; ++bytes;
|
||||
uint8_t numArgs = *bytes; ++bytes;
|
||||
debugMod2(MOD, "send command %d (%d bytes)", cmd, numArgs);
|
||||
sendCommand(cmd);
|
||||
while(numArgs--) {
|
||||
sendByte(*bytes);
|
||||
++bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// finalize init sequence
|
||||
sendCommand(ILI9341_SLPOUT); wait();
|
||||
sendCommand(ILI9341_DISPON); wait();
|
||||
|
||||
// done
|
||||
chipDeselect();
|
||||
|
||||
}
|
||||
|
||||
uint32_t getID() {
|
||||
chipSelect();
|
||||
sendCommand16(ILI9341_RDDID);
|
||||
uint32_t res = 0xFFFFFFFF;
|
||||
readBytes(reinterpret_cast<uint8_t*>(&res), 4); // dummy-byte + 3 data bytes
|
||||
chipDeselect();
|
||||
return res;
|
||||
}
|
||||
|
||||
void getStatus() {
|
||||
chipSelect();
|
||||
uint8_t buf[5];
|
||||
sendCommand16(ILI9341_RDDID);
|
||||
uint32_t res = 0xFFFFFFFF;
|
||||
readBytes(buf, 5); // dummy-byte + 4 data bytes
|
||||
chipDeselect();
|
||||
ESP_LOGI(MOD, "%d %d %d %d", buf[1],buf[2],buf[3],buf[4]);
|
||||
read();
|
||||
}
|
||||
|
||||
void read() {
|
||||
chipSelect();
|
||||
setAddrWindow(0,0,100,100);
|
||||
sendCommand(ILI9341_RAMRD);
|
||||
uint8_t buf[32];
|
||||
readBytes(buf, 32);
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
printf("%d ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
chipDeselect();
|
||||
}
|
||||
|
||||
|
||||
void draw(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t* data) {
|
||||
chipSelect();
|
||||
setAddrWindow(x,y,w,h);
|
||||
const int len = w*h;
|
||||
// for (int i = 0; i < len; ++i) {
|
||||
// spi::writeWord(data[i]);
|
||||
// }
|
||||
spi.write((const uint8_t*)data, w*h*2);
|
||||
chipDeselect();
|
||||
}
|
||||
|
||||
void fillRand() {
|
||||
|
||||
// chipSelect();
|
||||
// setAddrWindow(0,0,w,h);
|
||||
// for (int i = 0; i < w*h/2; ++i) {
|
||||
// sendQuad(rand());
|
||||
// }
|
||||
// chipDeselect();
|
||||
|
||||
chipSelect();
|
||||
setAddrWindow(0,0,w,h);
|
||||
for (int y = 0; y < h; ++y) {
|
||||
uint16_t buf[w];
|
||||
for (int x = 0; x < w; ++x) {buf[x] = rand();}
|
||||
sendBytes(reinterpret_cast<uint8_t*>(buf), w*2);
|
||||
}
|
||||
chipDeselect();
|
||||
|
||||
}
|
||||
|
||||
void fill(const uint16_t color) {
|
||||
|
||||
chipSelect();
|
||||
setAddrWindow(0,0,w,h);
|
||||
for (int y = 0; y < h; ++y) {
|
||||
uint16_t buf[w];
|
||||
for (int x = 0; x < w; ++x) {buf[x] = color;}
|
||||
sendBytes(reinterpret_cast<uint8_t*>(buf), w*2);
|
||||
}
|
||||
chipDeselect();
|
||||
|
||||
}
|
||||
|
||||
void fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t color) {
|
||||
|
||||
chipSelect();
|
||||
setAddrWindow(x,y,w,h);
|
||||
for (int i = 0; i < w*h; ++i) {
|
||||
sendWord(color);
|
||||
}
|
||||
chipDeselect();
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
void setAddrWindow(const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h) {
|
||||
|
||||
const uint32_t xa = ((uint32_t)x << 16) | (x+w-1);
|
||||
const uint32_t ya = ((uint32_t)y << 16) | (y+h-1);
|
||||
|
||||
sendCommand(ILI9341_CASET); // Column addr set
|
||||
sendQuad(xa);
|
||||
|
||||
sendCommand(ILI9341_PASET); // Row addr set
|
||||
sendQuad(ya);
|
||||
|
||||
sendCommand(ILI9341_RAMWR); // write to RAM
|
||||
// transmit data now
|
||||
|
||||
}
|
||||
|
||||
void wait() {
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
|
||||
/** select the display (CS=0) */
|
||||
inline void chipSelect() {
|
||||
//spi::chipSelect();
|
||||
GPIO::clear(PIN_CS);
|
||||
}
|
||||
|
||||
|
||||
/** send the given command to the display */
|
||||
void sendCommand(const uint8_t cmd) {
|
||||
modeCMD();
|
||||
spi.writeByte(cmd);
|
||||
modeDATA();
|
||||
}
|
||||
|
||||
/** send the given command to the display */
|
||||
void sendCommand16(const uint8_t cmd) {
|
||||
modeCMD();
|
||||
spi.writeByte(cmd);
|
||||
spi.writeByte(0x00);
|
||||
modeDATA();
|
||||
}
|
||||
|
||||
/** send the given data byte to the display */
|
||||
void sendByte(const uint8_t data) {
|
||||
spi.writeByte(data);
|
||||
}
|
||||
|
||||
/** send the given data word to the display */
|
||||
void sendWord(const uint16_t data) {
|
||||
spi.writeWord(data);
|
||||
}
|
||||
|
||||
/** send the given data quad to the display */
|
||||
void sendQuad(const uint32_t data) {
|
||||
spi.writeQuad(data);
|
||||
}
|
||||
|
||||
/** send the given data to the display */
|
||||
void sendBytes(const uint8_t* data, const size_t len) {
|
||||
spi.write(data, len);
|
||||
}
|
||||
|
||||
/** read the given data from the display */
|
||||
void readBytes(uint8_t* data, const size_t len) {
|
||||
spi.read(data, len);
|
||||
}
|
||||
|
||||
|
||||
/** unselect the display (CS=1) */
|
||||
inline void chipDeselect() {
|
||||
//spi::chipDeselect();
|
||||
GPIO::set(PIN_CS);
|
||||
}
|
||||
|
||||
/** switch to command-mode */
|
||||
inline void modeCMD() {
|
||||
//gpio_set_level((gpio_num_t)PIN_DATA_COMMAND, 0);
|
||||
GPIO::clear(PIN_DATA_COMMAND);
|
||||
}
|
||||
|
||||
/** switch to data-mode */
|
||||
inline void modeDATA() {
|
||||
//gpio_set_level((gpio_num_t)PIN_DATA_COMMAND, 1);
|
||||
GPIO::set(PIN_DATA_COMMAND);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
255
ext/lcd/SSD1306.h
Normal file
255
ext/lcd/SSD1306.h
Normal file
@@ -0,0 +1,255 @@
|
||||
#ifndef LCD_SSD1306
|
||||
#define LCD_SSD1306
|
||||
|
||||
#include "../../io/SoftI2C.h"
|
||||
|
||||
//#define SSD1306_128_64 1
|
||||
//#define SSD1306_64_48 1 // https://github.com/mcauser/Adafruit_SSD1306/blob/esp8266-64x48/Adafruit_SSD1306.cpp
|
||||
|
||||
#if defined SSD1306_128_64
|
||||
#define SSD1306_LCDWIDTH 128
|
||||
#define SSD1306_LCDHEIGHT 64
|
||||
#elif defined SSD1306_128_32
|
||||
#define SSD1306_LCDWIDTH 128
|
||||
#define SSD1306_LCDHEIGHT 32
|
||||
#elif defined SSD1306_96_16
|
||||
#define SSD1306_LCDWIDTH 96
|
||||
#define SSD1306_LCDHEIGHT 16
|
||||
#elif defined SSD1306_64_48
|
||||
#define SSD1306_LCDWIDTH 64
|
||||
#define SSD1306_LCDHEIGHT 48
|
||||
#else
|
||||
#error "SSD1306 display size not defined"
|
||||
#endif
|
||||
|
||||
#define SSD1306_SETCONTRAST 0x81
|
||||
#define SSD1306_DISPLAYALLON_RESUME 0xA4
|
||||
#define SSD1306_DISPLAYALLON 0xA5
|
||||
#define SSD1306_NORMALDISPLAY 0xA6
|
||||
#define SSD1306_INVERTDISPLAY 0xA7
|
||||
#define SSD1306_DISPLAYOFF 0xAE
|
||||
#define SSD1306_DISPLAYON 0xAF
|
||||
|
||||
#define SSD1306_SETDISPLAYOFFSET 0xD3
|
||||
#define SSD1306_SETCOMPINS 0xDA
|
||||
|
||||
#define SSD1306_SETVCOMDETECT 0xDB
|
||||
|
||||
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
|
||||
#define SSD1306_SETPRECHARGE 0xD9
|
||||
|
||||
#define SSD1306_SETMULTIPLEX 0xA8
|
||||
|
||||
#define SSD1306_SETLOWCOLUMN 0x00
|
||||
#define SSD1306_SETHIGHCOLUMN 0x10
|
||||
|
||||
#define SSD1306_SETSTARTLINE 0x40
|
||||
|
||||
#define SSD1306_MEMORYMODE 0x20
|
||||
#define SSD1306_COLUMNADDR 0x21
|
||||
#define SSD1306_PAGEADDR 0x22
|
||||
|
||||
#define SSD1306_COMSCANINC 0xC0
|
||||
#define SSD1306_COMSCANDEC 0xC8
|
||||
|
||||
#define SSD1306_SEGREMAP 0xA0
|
||||
|
||||
#define SSD1306_CHARGEPUMP 0x8D
|
||||
|
||||
#define SSD1306_EXTERNALVCC 0x1
|
||||
#define SSD1306_SWITCHCAPVCC 0x2
|
||||
|
||||
// Scrolling #defines
|
||||
#define SSD1306_ACTIVATE_SCROLL 0x2F
|
||||
#define SSD1306_DEACTIVATE_SCROLL 0x2E
|
||||
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
|
||||
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
|
||||
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
|
||||
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
|
||||
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
|
||||
|
||||
|
||||
|
||||
class SSD1306 {
|
||||
|
||||
private:
|
||||
|
||||
static constexpr uint8_t ADDR7 = 0b0111100;
|
||||
bool inited = false;
|
||||
|
||||
public:
|
||||
|
||||
bool isPresent() {
|
||||
return i2c::query(ADDR7);
|
||||
}
|
||||
|
||||
void initOnce() {
|
||||
if (inited) {return;}
|
||||
init();
|
||||
inited = true;
|
||||
}
|
||||
|
||||
|
||||
void flush(const uint8_t* data) {
|
||||
|
||||
sendCommand(SSD1306_COLUMNADDR);
|
||||
|
||||
// special handling for 64x48 oled shield
|
||||
#if SSD1306_LCDWIDTH == 64 && SSD1306_LCDHEIGHT == 48
|
||||
sendCommand(32);
|
||||
sendCommand(32 + SSD1306_LCDWIDTH - 1);
|
||||
#else
|
||||
sendCommand(0); // Column start address (0 = reset)
|
||||
sendCommand(SSD1306_LCDWIDTH-1); // Column end address (127 = reset)
|
||||
#endif
|
||||
|
||||
sendCommand(SSD1306_PAGEADDR);
|
||||
sendCommand(0); // Page start address (0 = reset)
|
||||
sendCommand( (SSD1306_LCDHEIGHT/8)-1 ); // Page end address
|
||||
// #if SSD1306_LCDHEIGHT == 64
|
||||
// sendCommand(7); // Page end address
|
||||
// #endif
|
||||
// #if SSD1306_LCDHEIGHT == 48
|
||||
// sendCommand(3); // Page end address
|
||||
// #endif
|
||||
// #if SSD1306_LCDHEIGHT == 32
|
||||
// sendCommand(3); // Page end address
|
||||
// #endif
|
||||
// #if SSD1306_LCDHEIGHT == 16
|
||||
// sendCommand(1); // Page end address
|
||||
// #endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
|
||||
// // send a bunch of data in one xmission
|
||||
// i2c::startWrite(ADDR7);
|
||||
// bool ok = i2c::writeByteAndCheck(0x40);
|
||||
// if (!ok) {os_printf("failed line\n");}
|
||||
|
||||
// for (uint8_t x = 0; x < 16; ++x) {
|
||||
// i2c::writeByteAndCheck(data[i]);
|
||||
// ++i;
|
||||
// }
|
||||
// i--;
|
||||
// i2c::stop();
|
||||
// }
|
||||
|
||||
i2c::startWrite(ADDR7);
|
||||
bool ok = i2c::writeByteAndCheck(0x40);
|
||||
if (!ok) {os_printf("failed write data\n");}
|
||||
|
||||
for (uint16_t i=0; i < (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
|
||||
i2c::writeByteAndCheck(data[i]);
|
||||
}
|
||||
|
||||
i2c::stop();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void init() {
|
||||
|
||||
uint8_t vccstate = 0;
|
||||
|
||||
sendCommand(SSD1306_DISPLAYOFF); // 0xAE
|
||||
sendCommand(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
|
||||
sendCommand(0x80); // the suggested ratio 0x80
|
||||
|
||||
sendCommand(SSD1306_SETMULTIPLEX); // 0xA8
|
||||
sendCommand(SSD1306_LCDHEIGHT - 1);
|
||||
|
||||
sendCommand(SSD1306_SETDISPLAYOFFSET); // 0xD3
|
||||
sendCommand(0x0); // no offset
|
||||
sendCommand(SSD1306_SETSTARTLINE | 0x0); // line #0
|
||||
sendCommand(SSD1306_CHARGEPUMP); // 0x8D
|
||||
if (vccstate == SSD1306_EXTERNALVCC) {
|
||||
sendCommand(0x10);
|
||||
} else {
|
||||
sendCommand(0x14);
|
||||
}
|
||||
sendCommand(SSD1306_MEMORYMODE); // 0x20
|
||||
sendCommand(0x00); // 0x0 act like ks0108
|
||||
sendCommand(SSD1306_SEGREMAP | 0x1);
|
||||
|
||||
sendCommand(SSD1306_COMSCANDEC); // rotate 180?
|
||||
|
||||
// OLD
|
||||
// #if defined SSD1306_128_32
|
||||
// sendCommand(SSD1306_SETCOMPINS); // 0xDA
|
||||
// sendCommand(0x02);
|
||||
// sendCommand(SSD1306_SETCONTRAST); // 0x81
|
||||
// sendCommand(0x8F);
|
||||
|
||||
// #elif defined SSD1306_128_64
|
||||
// sendCommand(SSD1306_SETCOMPINS); // 0xDA
|
||||
// sendCommand(0x12);
|
||||
// sendCommand(SSD1306_SETCONTRAST); // 0x81
|
||||
// if (vccstate == SSD1306_EXTERNALVCC)
|
||||
// { sendCommand(0x9F); }
|
||||
// else
|
||||
// { sendCommand(0xCF); }
|
||||
|
||||
// #elif defined SSD1306_96_16
|
||||
// sendCommand(SSD1306_SETCOMPINS); // 0xDA
|
||||
// sendCommand(0x2); //ada x12
|
||||
// sendCommand(SSD1306_SETCONTRAST); // 0x81
|
||||
// if (vccstate == SSD1306_EXTERNALVCC)
|
||||
// { sendCommand(0x10); }
|
||||
// else
|
||||
// { sendCommand(0xAF); }
|
||||
|
||||
// #endif
|
||||
|
||||
// NEW
|
||||
sendCommand(SSD1306_SETCOMPINS); // 0xDA
|
||||
sendCommand(0x12);
|
||||
|
||||
if (vccstate == SSD1306_EXTERNALVCC) {
|
||||
sendCommand(0x9F);
|
||||
} else {
|
||||
sendCommand(0xCF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
sendCommand(SSD1306_SETPRECHARGE); // 0xd9
|
||||
if (vccstate == SSD1306_EXTERNALVCC) {
|
||||
sendCommand(0x22);
|
||||
} else {
|
||||
sendCommand(0xF1);
|
||||
}
|
||||
|
||||
sendCommand(SSD1306_SETVCOMDETECT); // 0xDB
|
||||
sendCommand(0x40);
|
||||
sendCommand(SSD1306_DISPLAYALLON_RESUME); // 0xA4
|
||||
sendCommand(SSD1306_NORMALDISPLAY); // 0xA6
|
||||
|
||||
sendCommand(SSD1306_DEACTIVATE_SCROLL);
|
||||
|
||||
sendCommand(SSD1306_DISPLAYON);//--turn on oled panel
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void sendCommand(uint8_t cmd) {
|
||||
bool ok;
|
||||
ok = i2c::startWrite(ADDR7);
|
||||
if (!ok) {os_printf("failed start write\n");}
|
||||
ok = i2c::writeByteAndCheck(0x00); // command
|
||||
if (!ok) {os_printf("failed command mode\n");}
|
||||
ok = i2c::writeByteAndCheck(cmd);
|
||||
if (!ok) {os_printf("failed command\n");}
|
||||
i2c::stop();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
249
ext/lcd/SSD1306_old.h
Normal file
249
ext/lcd/SSD1306_old.h
Normal file
@@ -0,0 +1,249 @@
|
||||
#ifndef LCD_SSD1306
|
||||
#define LCD_SSD1306
|
||||
|
||||
#include "../../io/SoftI2C.h"
|
||||
|
||||
//#define SSD1306_128_64 1
|
||||
#define SSD1306_64_48 1
|
||||
|
||||
#if defined SSD1306_128_64
|
||||
#define SSD1306_LCDWIDTH 128
|
||||
#define SSD1306_LCDHEIGHT 64
|
||||
#endif
|
||||
#if defined SSD1306_128_32
|
||||
#define SSD1306_LCDWIDTH 128
|
||||
#define SSD1306_LCDHEIGHT 32
|
||||
#endif
|
||||
#if defined SSD1306_96_16
|
||||
#define SSD1306_LCDWIDTH 96
|
||||
#define SSD1306_LCDHEIGHT 16
|
||||
#endif
|
||||
#if defined SSD1306_64_48
|
||||
#define SSD1306_LCDWIDTH 64
|
||||
#define SSD1306_LCDHEIGHT 48
|
||||
#endif
|
||||
|
||||
#define SSD1306_SETCONTRAST 0x81
|
||||
#define SSD1306_DISPLAYALLON_RESUME 0xA4
|
||||
#define SSD1306_DISPLAYALLON 0xA5
|
||||
#define SSD1306_NORMALDISPLAY 0xA6
|
||||
#define SSD1306_INVERTDISPLAY 0xA7
|
||||
#define SSD1306_DISPLAYOFF 0xAE
|
||||
#define SSD1306_DISPLAYON 0xAF
|
||||
|
||||
#define SSD1306_SETDISPLAYOFFSET 0xD3
|
||||
#define SSD1306_SETCOMPINS 0xDA
|
||||
|
||||
#define SSD1306_SETVCOMDETECT 0xDB
|
||||
|
||||
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
|
||||
#define SSD1306_SETPRECHARGE 0xD9
|
||||
|
||||
#define SSD1306_SETMULTIPLEX 0xA8
|
||||
|
||||
#define SSD1306_SETLOWCOLUMN 0x00
|
||||
#define SSD1306_SETHIGHCOLUMN 0x10
|
||||
|
||||
#define SSD1306_SETSTARTLINE 0x40
|
||||
|
||||
#define SSD1306_MEMORYMODE 0x20
|
||||
#define SSD1306_COLUMNADDR 0x21
|
||||
#define SSD1306_PAGEADDR 0x22
|
||||
|
||||
#define SSD1306_COMSCANINC 0xC0
|
||||
#define SSD1306_COMSCANDEC 0xC8
|
||||
|
||||
#define SSD1306_SEGREMAP 0xA0
|
||||
|
||||
#define SSD1306_CHARGEPUMP 0x8D
|
||||
|
||||
#define SSD1306_EXTERNALVCC 0x1
|
||||
#define SSD1306_SWITCHCAPVCC 0x2
|
||||
|
||||
// Scrolling #defines
|
||||
#define SSD1306_ACTIVATE_SCROLL 0x2F
|
||||
#define SSD1306_DEACTIVATE_SCROLL 0x2E
|
||||
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
|
||||
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
|
||||
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
|
||||
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
|
||||
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
|
||||
|
||||
|
||||
|
||||
class SSD1306 {
|
||||
|
||||
private:
|
||||
|
||||
static constexpr uint8_t ADDR7 = 0b0111100;
|
||||
bool inited = false;
|
||||
|
||||
public:
|
||||
|
||||
bool isPresent() {
|
||||
return i2c::query(ADDR7);
|
||||
}
|
||||
|
||||
void initOnce() {
|
||||
if (inited) {return;}
|
||||
init();
|
||||
inited = true;
|
||||
}
|
||||
|
||||
|
||||
void flush(const uint8_t* data) {
|
||||
|
||||
sendCommand(SSD1306_COLUMNADDR);
|
||||
sendCommand(0); // Column start address (0 = reset)
|
||||
sendCommand(SSD1306_LCDWIDTH-1); // Column end address (127 = reset)
|
||||
|
||||
sendCommand(SSD1306_PAGEADDR);
|
||||
sendCommand(0); // Page start address (0 = reset)
|
||||
sendCommand( (SSD1306_LCDHEIGHT/8)-1 ); // Page end address
|
||||
// #if SSD1306_LCDHEIGHT == 64
|
||||
// sendCommand(7); // Page end address
|
||||
// #endif
|
||||
// #if SSD1306_LCDHEIGHT == 48
|
||||
// sendCommand(3); // Page end address
|
||||
// #endif
|
||||
// #if SSD1306_LCDHEIGHT == 32
|
||||
// sendCommand(3); // Page end address
|
||||
// #endif
|
||||
// #if SSD1306_LCDHEIGHT == 16
|
||||
// sendCommand(1); // Page end address
|
||||
// #endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
|
||||
// // send a bunch of data in one xmission
|
||||
// i2c::startWrite(ADDR7);
|
||||
// bool ok = i2c::writeByteAndCheck(0x40);
|
||||
// if (!ok) {os_printf("failed line\n");}
|
||||
|
||||
// for (uint8_t x = 0; x < 16; ++x) {
|
||||
// i2c::writeByteAndCheck(data[i]);
|
||||
// ++i;
|
||||
// }
|
||||
// i--;
|
||||
// i2c::stop();
|
||||
// }
|
||||
|
||||
i2c::startWrite(ADDR7);
|
||||
bool ok = i2c::writeByteAndCheck(0x40);
|
||||
if (!ok) {os_printf("failed write data\n");}
|
||||
|
||||
for (uint16_t i=0; i < 256; ++i) {//i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
|
||||
i2c::writeByteAndCheck(data[i]);
|
||||
}
|
||||
|
||||
i2c::stop();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void init() {
|
||||
|
||||
uint8_t vccstate = 0;
|
||||
|
||||
sendCommand(SSD1306_DISPLAYOFF); // 0xAE
|
||||
sendCommand(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
|
||||
sendCommand(0x80); // the suggested ratio 0x80
|
||||
|
||||
sendCommand(SSD1306_SETMULTIPLEX); // 0xA8
|
||||
sendCommand(SSD1306_LCDHEIGHT - 1);
|
||||
|
||||
sendCommand(SSD1306_SETDISPLAYOFFSET); // 0xD3
|
||||
sendCommand(0x0); // no offset
|
||||
sendCommand(SSD1306_SETSTARTLINE | 0x0); // line #0
|
||||
sendCommand(SSD1306_CHARGEPUMP); // 0x8D
|
||||
if (vccstate == SSD1306_EXTERNALVCC) {
|
||||
sendCommand(0x10);
|
||||
} else {
|
||||
sendCommand(0x14);
|
||||
}
|
||||
sendCommand(SSD1306_MEMORYMODE); // 0x20
|
||||
sendCommand(0x00); // 0x0 act like ks0108
|
||||
sendCommand(SSD1306_SEGREMAP | 0x1);
|
||||
|
||||
sendCommand(SSD1306_COMSCANDEC); // rotate 180?
|
||||
|
||||
// OLD
|
||||
// #if defined SSD1306_128_32
|
||||
// sendCommand(SSD1306_SETCOMPINS); // 0xDA
|
||||
// sendCommand(0x02);
|
||||
// sendCommand(SSD1306_SETCONTRAST); // 0x81
|
||||
// sendCommand(0x8F);
|
||||
|
||||
// #elif defined SSD1306_128_64
|
||||
// sendCommand(SSD1306_SETCOMPINS); // 0xDA
|
||||
// sendCommand(0x12);
|
||||
// sendCommand(SSD1306_SETCONTRAST); // 0x81
|
||||
// if (vccstate == SSD1306_EXTERNALVCC)
|
||||
// { sendCommand(0x9F); }
|
||||
// else
|
||||
// { sendCommand(0xCF); }
|
||||
|
||||
// #elif defined SSD1306_96_16
|
||||
// sendCommand(SSD1306_SETCOMPINS); // 0xDA
|
||||
// sendCommand(0x2); //ada x12
|
||||
// sendCommand(SSD1306_SETCONTRAST); // 0x81
|
||||
// if (vccstate == SSD1306_EXTERNALVCC)
|
||||
// { sendCommand(0x10); }
|
||||
// else
|
||||
// { sendCommand(0xAF); }
|
||||
|
||||
// #endif
|
||||
|
||||
// NEW
|
||||
sendCommand(SSD1306_SETCOMPINS); // 0xDA
|
||||
sendCommand(0x12);
|
||||
|
||||
if (vccstate == SSD1306_EXTERNALVCC) {
|
||||
sendCommand(0x9F);
|
||||
} else {
|
||||
sendCommand(0xCF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
sendCommand(SSD1306_SETPRECHARGE); // 0xd9
|
||||
if (vccstate == SSD1306_EXTERNALVCC) {
|
||||
sendCommand(0x22);
|
||||
} else {
|
||||
sendCommand(0xF1);
|
||||
}
|
||||
|
||||
sendCommand(SSD1306_SETVCOMDETECT); // 0xDB
|
||||
sendCommand(0x40);
|
||||
sendCommand(SSD1306_DISPLAYALLON_RESUME); // 0xA4
|
||||
sendCommand(SSD1306_NORMALDISPLAY); // 0xA6
|
||||
|
||||
sendCommand(SSD1306_DEACTIVATE_SCROLL);
|
||||
|
||||
sendCommand(SSD1306_DISPLAYON);//--turn on oled panel
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void sendCommand(uint8_t cmd) {
|
||||
bool ok;
|
||||
ok = i2c::startWrite(ADDR7);
|
||||
if (!ok) {os_printf("failed start write\n");}
|
||||
ok = i2c::writeByteAndCheck(0x00); // command
|
||||
if (!ok) {os_printf("failed command mode\n");}
|
||||
ok = i2c::writeByteAndCheck(cmd);
|
||||
if (!ok) {os_printf("failed command\n");}
|
||||
i2c::stop();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
295
ext/lcd/ST7735.h
Normal file
295
ext/lcd/ST7735.h
Normal file
@@ -0,0 +1,295 @@
|
||||
#ifndef LCD_SSD1306
|
||||
#define LCD_SSD1306
|
||||
|
||||
#include "../../io/SoftSPI.h"
|
||||
|
||||
|
||||
/**
|
||||
* https://www.displayfuture.com/Display/datasheet/controller/ST7735.pdf
|
||||
* https://www.aliexpress.com/item/1-8-inch-TFT-color-screen-module-ST7735-SPI-at-least-4IO-support-C51-STM32-with/32809505663.html?spm=2114.search0302.3.266.14d83b8cQXOxfz&ws_ab_test=searchweb0_0,searchweb201602_0_450_452_532_533_534_10618_535_317_318_319_10059_10696_10084_100031_10083_10547_10304_10546_10843_10887_320_10307_10548_204_448_10065_449_10068_10320_10103_10884_10820,searchweb201603_0,ppcSwitch_0&algo_pvid=7cf0bb24-ac60-4e97-9878-8716f61a79f3&algo_expid=7cf0bb24-ac60-4e97-9878-8716f61a79f3-33
|
||||
* https://sites.google.com/site/arduinomega2560projects/microchip-pic/level-3/st7735-1-8-tft (!!!!)
|
||||
*
|
||||
* display is SPI
|
||||
* CLK = clock
|
||||
* SDA = mosi
|
||||
* RS = data/command
|
||||
* RST = reset
|
||||
* CS = chip-select
|
||||
*/
|
||||
|
||||
class ST7735 {
|
||||
|
||||
private:
|
||||
|
||||
static constexpr const char* NAME = "ST7735";
|
||||
|
||||
bool inited = false;
|
||||
|
||||
/** switch D/C line low */
|
||||
inline void modeCommand() {
|
||||
GPIO5_OUTPUT_SET;
|
||||
GPIO5_L;
|
||||
}
|
||||
|
||||
/** switch D/C line high */
|
||||
inline void modeData() {
|
||||
GPIO5_OUTPUT_SET;
|
||||
GPIO5_H;
|
||||
}
|
||||
|
||||
/** set CS = low */
|
||||
inline void select() {
|
||||
spi::chipSelect();
|
||||
}
|
||||
|
||||
/** set CS = high */
|
||||
inline void deselect() {
|
||||
spi::chipDeselect();
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
void initOnce() {
|
||||
if (inited) {return;}
|
||||
init();
|
||||
inited = true;
|
||||
}
|
||||
|
||||
#define ST7735_NOP 0x00
|
||||
#define ST7735_SWRESET 0x01
|
||||
#define ST7735_RDDID 0x04
|
||||
#define ST7735_RDDST 0x09
|
||||
|
||||
#define ST7735_SLPIN 0x10
|
||||
#define ST7735_SLPOUT 0x11
|
||||
#define ST7735_PTLON 0x12
|
||||
#define ST7735_NORON 0x13
|
||||
|
||||
#define ST7735_INVOFF 0x20
|
||||
#define ST7735_INVON 0x21
|
||||
#define ST7735_DISPOFF 0x28
|
||||
#define ST7735_DISPON 0x29
|
||||
#define ST7735_CASET 0x2A
|
||||
#define ST7735_RASET 0x2B
|
||||
#define ST7735_RAMWR 0x2C
|
||||
#define ST7735_RAMRD 0x2E
|
||||
|
||||
#define ST7735_PTLAR 0x30
|
||||
#define ST7735_COLMOD 0x3A
|
||||
#define ST7735_MADCTL 0x36
|
||||
|
||||
#define ST7735_FRMCTR1 0xB1
|
||||
#define ST7735_FRMCTR2 0xB2
|
||||
#define ST7735_FRMCTR3 0xB3
|
||||
#define ST7735_INVCTR 0xB4
|
||||
#define ST7735_DISSET5 0xB6
|
||||
|
||||
#define ST7735_PWCTR1 0xC0
|
||||
#define ST7735_PWCTR2 0xC1
|
||||
#define ST7735_PWCTR3 0xC2
|
||||
#define ST7735_PWCTR4 0xC3
|
||||
#define ST7735_PWCTR5 0xC4
|
||||
#define ST7735_VMCTR1 0xC5
|
||||
|
||||
#define ST7735_RDID1 0xDA
|
||||
#define ST7735_RDID2 0xDB
|
||||
#define ST7735_RDID3 0xDC
|
||||
#define ST7735_RDID4 0xDD
|
||||
|
||||
#define ST7735_PWCTR6 0xFC
|
||||
|
||||
#define ST7735_GMCTRP1 0xE0
|
||||
#define ST7735_GMCTRN1 0xE1
|
||||
|
||||
|
||||
private:
|
||||
|
||||
#define V 128
|
||||
#define H 160
|
||||
|
||||
void waitLong() {
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
os_delay_us(10*1000);
|
||||
}
|
||||
}
|
||||
|
||||
void waitShort() {
|
||||
os_delay_us(10*1000);
|
||||
}
|
||||
|
||||
void init() {
|
||||
|
||||
spi::init();
|
||||
|
||||
select();
|
||||
|
||||
sendCommand(ST7735_SWRESET); // 1: Software reset, 0 args
|
||||
waitLong();
|
||||
|
||||
sendCommand(ST7735_SLPOUT); // 2: Out of sleep mode, 0 args
|
||||
waitLong();
|
||||
|
||||
sendCommand(ST7735_FRMCTR1); // 3: Frame rate ctrl - normal mode) 3 args: 0xb1
|
||||
sendData(0x01); sendData(0x2C); sendData(0x2D); // Rate = fosc/(1x2+40) * (LINE+2C+2D)
|
||||
|
||||
sendCommand(ST7735_FRMCTR2); // 4: Frame rate control - idle mode) 3 args: 0xb2
|
||||
sendData(0x01); sendData(0x2C); sendData(0x2D); // Rate = fosc/(1x2+40) * (LINE+2C+2D)
|
||||
|
||||
sendCommand(ST7735_FRMCTR3); // 5: Frame rate ctrl - partial mode) 6 args: 0xb3
|
||||
sendData(0x01); sendData(0x2C); sendData(0x2D); // Dot inversion mode
|
||||
sendData(0x01); sendData(0x2C); sendData(0x2D); // Line inversion mode
|
||||
|
||||
sendCommand(ST7735_INVCTR); // 6: Display inversion ctrl) 1 arg) no delay: 0xb4
|
||||
sendData(0x07); // No inversion
|
||||
|
||||
sendCommand(ST7735_PWCTR1); // 7: Power control) 3 args) no delay: 0xc0
|
||||
sendData(0xA2);
|
||||
sendData(0x02); // -4.6V
|
||||
sendData(0x84); // AUTO mode
|
||||
|
||||
sendCommand(ST7735_PWCTR2); // 8: Power control) 1 arg) no delay: 0xc1
|
||||
sendData(0xC5); // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
|
||||
|
||||
sendCommand(ST7735_PWCTR3); // 9: Power control) 2 args) no delay: 0xc2
|
||||
sendData(0x0A); // Opamp current small
|
||||
sendData(0x00); // Boost frequency
|
||||
|
||||
sendCommand(ST7735_PWCTR4); // 10: Power control) 2 args) no delay:
|
||||
sendData(0x8A); // BCLK/2) Opamp current small & Medium low
|
||||
sendData(0x2A);
|
||||
|
||||
sendCommand(ST7735_PWCTR5); // 11: Power control) 2 args) no delay:
|
||||
sendData(0x8A); sendData(0xEE);
|
||||
|
||||
sendCommand(ST7735_VMCTR1); // 12: Power control) 1 arg) no delay:
|
||||
sendData(0x0E);
|
||||
|
||||
sendCommand(ST7735_INVOFF); // 13: Don't invert display) no args) no delay 0x20
|
||||
|
||||
sendCommand(ST7735_MADCTL); // 14: Memory access control (directions)) 1 arg:
|
||||
sendData(0xC8); // row addr/col addr); bottom to top refresh
|
||||
|
||||
sendCommand(ST7735_COLMOD); // 15: set color mode); 1 arg); no delay:
|
||||
sendData(0x05); // 16-bit color
|
||||
|
||||
|
||||
// required???
|
||||
if (1 == 1) {
|
||||
|
||||
sendCommand(ST7735_GMCTRP1); // 1: Magical unicorn dust, 16 args, no delay:
|
||||
sendData(0x02); sendData(0x1c); sendData(0x07); sendData(0x12);
|
||||
sendData(0x37); sendData(0x32); sendData(0x29); sendData(0x2d);
|
||||
sendData(0x29); sendData(0x25); sendData(0x2B); sendData(0x39);
|
||||
sendData(0x00); sendData(0x01); sendData(0x03); sendData(0x10);
|
||||
|
||||
sendCommand(ST7735_GMCTRN1); // 2: Sparkles and rainbows, 16 args, no delay:
|
||||
sendData(0x03); sendData(0x1d); sendData(0x07); sendData(0x06);
|
||||
sendData(0x2E); sendData(0x2C); sendData(0x29); sendData(0x2D);
|
||||
sendData(0x2E); sendData(0x2E); sendData(0x37); sendData(0x3F);
|
||||
sendData(0x00); sendData(0x00); sendData(0x02); sendData(0x10);
|
||||
|
||||
}
|
||||
|
||||
sendCommand(ST7735_NORON); // 3: Normal display on, no args
|
||||
waitShort();
|
||||
|
||||
sendCommand(ST7735_DISPON); // 4: Main screen turn on, no args
|
||||
waitLong();
|
||||
|
||||
deselect();
|
||||
|
||||
debugMod(NAME, "init() done");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void clean(uint16_t color){
|
||||
|
||||
select();
|
||||
|
||||
uint8_t lo = color & 0xFF;
|
||||
uint8_t hi = color >> 8;
|
||||
|
||||
sendCommand(ST7735_CASET); // Column addr set
|
||||
sendData(0x00);
|
||||
sendData(0); // XSTART
|
||||
sendData(0x00);
|
||||
sendData(V-1); // XEND
|
||||
|
||||
sendCommand(ST7735_RASET); // Row addr set
|
||||
sendData(0x00);
|
||||
sendData(0); // YSTART
|
||||
sendData(0x00);
|
||||
sendData(H-1); // YEND
|
||||
|
||||
sendCommand(ST7735_RAMWR);
|
||||
|
||||
for(char x=0;x<V;x++){
|
||||
for(char y=0;y<H;y++){
|
||||
sendData(lo);
|
||||
sendData(hi);
|
||||
}
|
||||
}
|
||||
|
||||
deselect();
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void flush(uint16_t* data) {
|
||||
|
||||
select();
|
||||
|
||||
sendCommand(ST7735_CASET); // Column addr set
|
||||
sendData(0x00);
|
||||
sendData(0); // XSTART
|
||||
sendData(0x00);
|
||||
sendData(V-1); // XEND
|
||||
|
||||
sendCommand(ST7735_RASET); // Row addr set
|
||||
sendData(0x00);
|
||||
sendData(0); // YSTART
|
||||
sendData(0x00);
|
||||
sendData(H-1); // YEND
|
||||
|
||||
sendCommand(ST7735_RAMWR);
|
||||
|
||||
modeData();
|
||||
for (int i = 0; i < (V*H); ++i) {
|
||||
const uint16_t color = data[i];
|
||||
//const uint8_t lo = color & 0xFF;
|
||||
//const uint8_t hi = color >> 8;
|
||||
//sendData(lo);
|
||||
//sendData(hi);
|
||||
spi::writeWord(color);
|
||||
}
|
||||
|
||||
deselect();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void sendData(uint8_t data) {
|
||||
modeData();
|
||||
//select();
|
||||
spi::writeByte(data);
|
||||
//deselect();
|
||||
}
|
||||
|
||||
void sendCommand(uint8_t cmd) {
|
||||
modeCommand();
|
||||
//select();
|
||||
spi::writeByte(cmd);
|
||||
//deselect();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
413
ext/lcd/ST7735_old.h
Normal file
413
ext/lcd/ST7735_old.h
Normal file
@@ -0,0 +1,413 @@
|
||||
#ifndef LCD_SSD1306
|
||||
#define LCD_SSD1306
|
||||
|
||||
#include "../../io/SoftSPI.h"
|
||||
|
||||
|
||||
/**
|
||||
* https://www.displayfuture.com/Display/datasheet/controller/ST7735.pdf
|
||||
* https://www.aliexpress.com/item/1-8-inch-TFT-color-screen-module-ST7735-SPI-at-least-4IO-support-C51-STM32-with/32809505663.html?spm=2114.search0302.3.266.14d83b8cQXOxfz&ws_ab_test=searchweb0_0,searchweb201602_0_450_452_532_533_534_10618_535_317_318_319_10059_10696_10084_100031_10083_10547_10304_10546_10843_10887_320_10307_10548_204_448_10065_449_10068_10320_10103_10884_10820,searchweb201603_0,ppcSwitch_0&algo_pvid=7cf0bb24-ac60-4e97-9878-8716f61a79f3&algo_expid=7cf0bb24-ac60-4e97-9878-8716f61a79f3-33
|
||||
* https://sites.google.com/site/arduinomega2560projects/microchip-pic/level-3/st7735-1-8-tft (!!!!)
|
||||
*
|
||||
* display is SPI
|
||||
* CLK = clock
|
||||
* SDA = mosi
|
||||
* RS = data/command
|
||||
* RST = reset
|
||||
* CS = chip-select
|
||||
*/
|
||||
|
||||
class ST7735 {
|
||||
|
||||
private:
|
||||
|
||||
static constexpr const char* NAME = "ST7735";
|
||||
|
||||
bool inited = false;
|
||||
|
||||
/** switch D/C line low */
|
||||
inline void modeCommand() {
|
||||
GPIO5_OUTPUT_SET;
|
||||
GPIO5_L;
|
||||
}
|
||||
|
||||
/** switch D/C line high */
|
||||
inline void modeData() {
|
||||
GPIO5_OUTPUT_SET;
|
||||
GPIO5_H;
|
||||
}
|
||||
|
||||
/** set CS = low */
|
||||
inline void select() {
|
||||
spi::chipSelect();
|
||||
}
|
||||
|
||||
/** set CS = high */
|
||||
inline void deselect() {
|
||||
spi::chipDeselect();
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
void initOnce() {
|
||||
if (inited) {return;}
|
||||
init();
|
||||
inited = true;
|
||||
}
|
||||
|
||||
//#define ST77XX_NOP 0x00
|
||||
//#define ST77XX_SWRESET 0x01
|
||||
//#define ST77XX_RDDID 0x04
|
||||
//#define ST77XX_RDDST 0x09
|
||||
|
||||
//#define ST77XX_SLPIN 0x10
|
||||
//#define ST77XX_SLPOUT 0x11
|
||||
//#define ST77XX_PTLON 0x12
|
||||
//#define ST77XX_NORON 0x13
|
||||
|
||||
//#define ST77XX_INVOFF 0x20
|
||||
//#define ST77XX_INVON 0x21
|
||||
//#define ST77XX_DISPOFF 0x28
|
||||
//#define ST77XX_DISPON 0x29
|
||||
//#define ST77XX_CASET 0x2A
|
||||
//#define ST77XX_RASET 0x2B
|
||||
//#define ST77XX_RAMWR 0x2C
|
||||
//#define ST77XX_RAMRD 0x2E
|
||||
|
||||
//#define ST77XX_PTLAR 0x30
|
||||
//#define ST77XX_COLMOD 0x3A
|
||||
//#define ST77XX_MADCTL 0x36
|
||||
|
||||
//#define ST77XX_MADCTL_MY 0x80
|
||||
//#define ST77XX_MADCTL_MX 0x40
|
||||
//#define ST77XX_MADCTL_MV 0x20
|
||||
//#define ST77XX_MADCTL_ML 0x10
|
||||
//#define ST77XX_MADCTL_RGB 0x00
|
||||
|
||||
//#define ST77XX_RDID1 0xDA
|
||||
//#define ST77XX_RDID2 0xDB
|
||||
//#define ST77XX_RDID3 0xDC
|
||||
//#define ST77XX_RDID4 0xDD
|
||||
|
||||
//#define ST7735_MADCTL_BGR 0x08
|
||||
//#define ST7735_MADCTL_MH 0x04
|
||||
|
||||
//#define ST7735_FRMCTR1 0xB1
|
||||
//#define ST7735_FRMCTR2 0xB2
|
||||
//#define ST7735_FRMCTR3 0xB3
|
||||
//#define ST7735_INVCTR 0xB4
|
||||
//#define ST7735_DISSET5 0xB6
|
||||
|
||||
//#define ST7735_PWCTR1 0xC0
|
||||
//#define ST7735_PWCTR2 0xC1
|
||||
//#define ST7735_PWCTR3 0xC2
|
||||
//#define ST7735_PWCTR4 0xC3
|
||||
//#define ST7735_PWCTR5 0xC4
|
||||
//#define ST7735_VMCTR1 0xC5
|
||||
|
||||
//#define ST7735_PWCTR6 0xFC
|
||||
|
||||
//#define ST7735_GMCTRP1 0xE0
|
||||
//#define ST7735_GMCTRN1 0xE1
|
||||
|
||||
|
||||
|
||||
#define ST7735_NOP 0x00
|
||||
#define ST7735_SWRESET 0x01
|
||||
#define ST7735_RDDID 0x04
|
||||
#define ST7735_RDDST 0x09
|
||||
|
||||
#define ST7735_SLPIN 0x10
|
||||
#define ST7735_SLPOUT 0x11
|
||||
#define ST7735_PTLON 0x12
|
||||
#define ST7735_NORON 0x13
|
||||
|
||||
#define ST7735_INVOFF 0x20
|
||||
#define ST7735_INVON 0x21
|
||||
#define ST7735_DISPOFF 0x28
|
||||
#define ST7735_DISPON 0x29
|
||||
#define ST7735_CASET 0x2A
|
||||
#define ST7735_RASET 0x2B
|
||||
#define ST7735_RAMWR 0x2C
|
||||
#define ST7735_RAMRD 0x2E
|
||||
|
||||
#define ST7735_PTLAR 0x30
|
||||
#define ST7735_COLMOD 0x3A
|
||||
#define ST7735_MADCTL 0x36
|
||||
|
||||
#define ST7735_FRMCTR1 0xB1
|
||||
#define ST7735_FRMCTR2 0xB2
|
||||
#define ST7735_FRMCTR3 0xB3
|
||||
#define ST7735_INVCTR 0xB4
|
||||
#define ST7735_DISSET5 0xB6
|
||||
|
||||
#define ST7735_PWCTR1 0xC0
|
||||
#define ST7735_PWCTR2 0xC1
|
||||
#define ST7735_PWCTR3 0xC2
|
||||
#define ST7735_PWCTR4 0xC3
|
||||
#define ST7735_PWCTR5 0xC4
|
||||
#define ST7735_VMCTR1 0xC5
|
||||
|
||||
#define ST7735_RDID1 0xDA
|
||||
#define ST7735_RDID2 0xDB
|
||||
#define ST7735_RDID3 0xDC
|
||||
#define ST7735_RDID4 0xDD
|
||||
|
||||
#define ST7735_PWCTR6 0xFC
|
||||
|
||||
#define ST7735_GMCTRP1 0xE0
|
||||
#define ST7735_GMCTRN1 0xE1
|
||||
|
||||
|
||||
private:
|
||||
|
||||
#define V 128
|
||||
#define H 160
|
||||
|
||||
void waitLong() {
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
os_delay_us(10*1000);
|
||||
}
|
||||
}
|
||||
|
||||
void waitShort() {
|
||||
os_delay_us(10*1000);
|
||||
}
|
||||
|
||||
void init() {
|
||||
|
||||
spi::init();
|
||||
|
||||
debugMod(NAME, "init()");
|
||||
|
||||
// sendCommand(ST77XX_SWRESET); waitLong();
|
||||
// sendCommand(ST77XX_SLPOUT); waitLong();
|
||||
// sendCommand(ST77XX_COLMOD, 0x05); waitShort();
|
||||
|
||||
// sendCommand(ST7735_FRMCTR1, 0x00, 0x06, 0x03); waitShort();
|
||||
// sendCommand(ST77XX_MADCTL, 0x08);
|
||||
// sendCommand(ST7735_DISSET5, 0x15, 0x02);
|
||||
// sendCommand(ST7735_INVCTR, 0x0);
|
||||
|
||||
// sendCommand(ST7735_PWCTR1, 0x02, 0x70); waitShort();
|
||||
|
||||
// sendCommand(ST7735_PWCTR2, 0x05);
|
||||
// sendCommand(ST7735_PWCTR3, 0x01, 0x02);
|
||||
// sendCommand(ST7735_VMCTR1, 0x3C, 0x38); waitShort();
|
||||
// sendCommand(ST7735_PWCTR6, 0x11, 0x15);
|
||||
|
||||
// sendCommand(ST7735_GMCTRP1,
|
||||
// 0x09, 0x16, 0x09, 0x20,
|
||||
// 0x21, 0x1B, 0x13, 0x19,
|
||||
// 0x17, 0x15, 0x1E, 0x2B,
|
||||
// 0x04, 0x05, 0x02, 0x0E);
|
||||
// sendCommand(ST7735_GMCTRN1,
|
||||
// 0x0B, 0x14, 0x08, 0x1E,
|
||||
// 0x22, 0x1D, 0x18, 0x1E,
|
||||
// 0x1B, 0x1A, 0x24, 0x2B,
|
||||
// 0x06, 0x06, 0x02, 0x0F);
|
||||
// waitShort();
|
||||
|
||||
// sendCommand(ST77XX_CASET, 0x00, 0x02, 0x00, 0x81);
|
||||
// sendCommand(ST77XX_RASET, 0x00, 0x02, 0x00, 0x81);
|
||||
// sendCommand(ST77XX_NORON); waitShort();
|
||||
// sendCommand(ST77XX_DISPON); waitLong();
|
||||
|
||||
|
||||
sendCommand(ST7735_SWRESET); // 1: Software reset, 0 args, w/delay 150ms 0x01
|
||||
waitLong();
|
||||
sendCommand(ST7735_SLPOUT); // 2: Out of sleep mode, 0 args, w/delay 500ms 0x11
|
||||
waitLong();
|
||||
sendCommand(ST7735_FRMCTR1); // 3: Frame rate ctrl - normal mode) 3 args: 0xb1
|
||||
sendData(0x01); sendData(0x2C); sendData(0x2D); // Rate = fosc/(1x2+40) * (LINE+2C+2D)
|
||||
sendCommand(ST7735_FRMCTR2); // 4: Frame rate control - idle mode) 3 args: 0xb2
|
||||
sendData(0x01); sendData(0x2C); sendData(0x2D); // Rate = fosc/(1x2+40) * (LINE+2C+2D)
|
||||
sendCommand(ST7735_FRMCTR3); // 5: Frame rate ctrl - partial mode) 6 args: 0xb3
|
||||
sendData(0x01); sendData(0x2C); sendData(0x2D); // Dot inversion mode
|
||||
sendData(0x01); sendData(0x2C); sendData(0x2D); // Line inversion mode
|
||||
sendCommand(ST7735_INVCTR); // 6: Display inversion ctrl) 1 arg) no delay: 0xb4
|
||||
sendData(0x07); // No inversion
|
||||
sendCommand(ST7735_PWCTR1); // 7: Power control) 3 args) no delay: 0xc0
|
||||
sendData(0xA2);
|
||||
sendData(0x02); // -4.6V
|
||||
sendData(0x84); // AUTO mode
|
||||
sendCommand(ST7735_PWCTR2); // 8: Power control) 1 arg) no delay: 0xc1
|
||||
sendData(0xC5); // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
|
||||
sendCommand(ST7735_PWCTR3); // 9: Power control) 2 args) no delay: 0xc2
|
||||
sendData(0x0A); // Opamp current small
|
||||
sendData(0x00); // Boost frequency
|
||||
sendCommand(ST7735_PWCTR4); // 10: Power control) 2 args) no delay:
|
||||
sendData(0x8A); // BCLK/2) Opamp current small & Medium low
|
||||
sendData(0x2A);
|
||||
sendCommand(ST7735_PWCTR5); // 11: Power control) 2 args) no delay:
|
||||
sendData(0x8A); sendData(0xEE);
|
||||
sendCommand(ST7735_VMCTR1); // 12: Power control) 1 arg) no delay:
|
||||
sendData(0x0E);
|
||||
sendCommand(ST7735_INVOFF); // 13: Don't invert display) no args) no delay 0x20
|
||||
sendCommand(ST7735_MADCTL); // 14: Memory access control (directions)) 1 arg:
|
||||
sendData(0xC8); // row addr/col addr); bottom to top refresh
|
||||
sendCommand(ST7735_COLMOD); // 15: set color mode); 1 arg); no delay:
|
||||
sendData(0x05); // 16-bit color
|
||||
sendCommand(ST7735_NORON); // 3: Normal display on, no args, w/delay 10ms 0x13
|
||||
waitShort();
|
||||
sendCommand(ST7735_DISPON); // 4: Main screen turn on, no args w/delay 100ms 0x29
|
||||
waitLong();
|
||||
|
||||
|
||||
|
||||
debugMod(NAME, "init() done");
|
||||
|
||||
clean(0x1111110000001111);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void clean(uint16_t color){
|
||||
|
||||
uint8_t lo = color & 0xFF;
|
||||
uint8_t hi = color >> 8;
|
||||
|
||||
sendCommand(ST7735_CASET); // Column addr set
|
||||
sendData(0x00);
|
||||
sendData(0); // XSTART
|
||||
sendData(0x00);
|
||||
sendData(V); // XEND
|
||||
|
||||
sendCommand(ST7735_RASET); // Row addr set
|
||||
sendData(0x00);
|
||||
sendData(0); // YSTART
|
||||
sendData(0x00);
|
||||
sendData(H); // YEND
|
||||
|
||||
sendCommand(ST7735_RAMWR);
|
||||
|
||||
for(char x=0;x<V;x++){
|
||||
for(char y=0;y<H;y++){
|
||||
sendData(lo);
|
||||
sendData(hi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void flush(uint16_t* data) {
|
||||
|
||||
sendCommand(ST7735_CASET); // Column addr set
|
||||
sendData(0x00);
|
||||
sendData(0); // XSTART
|
||||
sendData(0x00);
|
||||
sendData(V); // XEND
|
||||
|
||||
sendCommand(ST7735_RASET); // Row addr set
|
||||
sendData(0x00);
|
||||
sendData(0); // YSTART
|
||||
sendData(0x00);
|
||||
sendData(H); // YEND
|
||||
|
||||
sendCommand(ST7735_RAMWR);
|
||||
|
||||
for (int i = 0; i < (V*H); ++i) {
|
||||
uint16_t color = data[i];
|
||||
uint8_t lo = color & 0xFF;
|
||||
uint8_t hi = color >> 8;
|
||||
sendData(lo);
|
||||
sendData(hi);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void sendData(uint8_t data) {
|
||||
modeData();
|
||||
select();
|
||||
spi::writeByte(data);
|
||||
deselect();
|
||||
}
|
||||
|
||||
void sendCommand(uint8_t cmd) {
|
||||
modeCommand();
|
||||
select();
|
||||
spi::writeByte(cmd);
|
||||
deselect();
|
||||
}
|
||||
|
||||
// void sendCommand(uint8_t cmd, uint8_t arg1) {
|
||||
// modeCommand();
|
||||
// select();
|
||||
// spi::writeByte(cmd);
|
||||
// deselect();
|
||||
// sendData(arg1);
|
||||
// }
|
||||
|
||||
// void sendCommand(uint8_t cmd, uint8_t arg1, uint8_t arg2) {
|
||||
// modeCommand();
|
||||
// select();
|
||||
// spi::writeByte(cmd);
|
||||
// deselect();
|
||||
// sendData(arg1);
|
||||
// sendData(arg2);
|
||||
// }
|
||||
|
||||
// void sendCommand(uint8_t cmd, uint8_t arg1, uint8_t arg2, uint8_t arg3) {
|
||||
// modeCommand();
|
||||
// select();
|
||||
// spi::writeByte(cmd);
|
||||
// deselect();
|
||||
// sendData(arg1);
|
||||
// sendData(arg2);
|
||||
// sendData(arg3);
|
||||
// }
|
||||
|
||||
// void sendCommand(uint8_t cmd, uint8_t arg1, uint8_t arg2, uint8_t arg3, uint8_t arg4) {
|
||||
// modeCommand();
|
||||
// select();
|
||||
// spi::writeByte(cmd);
|
||||
// deselect();
|
||||
// sendData(arg1);
|
||||
// sendData(arg2);
|
||||
// sendData(arg3);
|
||||
// sendData(arg4);
|
||||
// }
|
||||
|
||||
// void sendCommand(uint8_t cmd,
|
||||
// uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4,
|
||||
// uint8_t a5, uint8_t a6, uint8_t a7, uint8_t a8,
|
||||
// uint8_t a9, uint8_t a10, uint8_t a11, uint8_t a12,
|
||||
// uint8_t a13, uint8_t a14, uint8_t a15, uint8_t a16) {
|
||||
// modeCommand();
|
||||
// select();
|
||||
// spi::writeByte(cmd);
|
||||
// deselect();
|
||||
|
||||
// sendData(a1);
|
||||
// sendData(a2);
|
||||
// sendData(a3);
|
||||
// sendData(a4);
|
||||
|
||||
// sendData(a5);
|
||||
// sendData(a6);
|
||||
// sendData(a7);
|
||||
// sendData(a8);
|
||||
|
||||
// sendData(a9);
|
||||
// sendData(a10);
|
||||
// sendData(a11);
|
||||
// sendData(a12);
|
||||
|
||||
// sendData(a13);
|
||||
// sendData(a14);
|
||||
// sendData(a15);
|
||||
// sendData(a16);
|
||||
|
||||
// }
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
101
ext/lcd/ui/UI.h
Normal file
101
ext/lcd/ui/UI.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#ifndef UI_H
|
||||
#define UI_H
|
||||
|
||||
#include <cstdint>
|
||||
#include "../Draw.h"
|
||||
#include "../../../Debug.h"
|
||||
|
||||
|
||||
class Setter;
|
||||
extern Setter setter;
|
||||
|
||||
//uint8_t f1_data[] = {84,18,71,192,137,130,0,0,32,135,28,7,250,156,207,113,0,0,112,124,156,199,121,190,207,137,130,162,32,40,114,30,231,113,190,40,10,138,162,239,226,8,16,64,0,64,0,7,4,65,65,0,0,0,0,0,0,0,0,0,0,0,172,1,84,146,170,32,74,164,2,0,160,200,162,8,11,34,40,138,0,0,136,130,162,40,138,130,32,138,130,162,32,40,138,162,40,138,136,40,10,138,34,40,130,20,32,64,0,64,128,0,4,0,65,0,0,0,0,0,32,0,0,0,0,0,34,74,84,191,162,36,40,200,33,0,160,168,32,136,10,2,40,138,10,129,128,178,162,40,136,130,32,136,130,146,96,44,138,162,40,10,136,40,74,138,34,40,130,34,0,206,227,120,142,224,61,65,81,55,143,243,120,153,243,68,81,80,20,125,34,74,4,146,66,34,32,168,34,0,144,140,16,72,122,2,36,138,128,60,65,170,162,40,136,130,32,136,130,138,160,106,138,162,40,10,136,40,74,82,20,36,132,0,0,81,20,69,209,19,69,65,73,73,81,20,69,69,36,68,81,80,20,65,34,74,4,18,7,193,33,136,248,240,144,138,8,38,130,30,194,241,64,0,34,170,162,39,136,142,35,251,130,134,32,169,138,158,232,113,136,40,74,34,8,34,132,0,0,80,20,68,145,16,69,65,69,73,81,20,69,67,32,68,81,146,18,33,33,76,4,18,138,36,34,8,32,0,144,137,4,232,131,34,33,130,128,60,33,170,190,40,136,130,32,138,130,138,32,40,139,130,168,128,136,40,74,82,8,33,132,0,0,94,20,68,159,16,69,65,67,73,81,20,69,129,35,68,81,18,17,17,34,74,4,63,74,42,34,8,32,0,136,136,2,8,130,162,32,130,0,129,32,114,162,40,136,130,32,138,130,146,32,40,138,130,42,129,136,40,74,138,136,32,136,0,0,81,20,68,129,16,69,65,69,73,81,20,69,1,36,68,81,146,18,9,34,74,0,146,10,42,66,4,0,0,136,136,130,8,138,162,32,138,0,0,0,2,162,40,138,130,32,138,138,162,32,40,138,130,36,138,136,72,73,138,136,32,136,0,0,81,20,69,145,224,69,65,73,65,81,20,69,65,36,68,74,82,228,5,34,74,4,18,7,196,131,2,0,2,10,135,62,7,114,156,192,113,10,0,32,124,162,199,121,190,192,139,114,162,47,40,114,2,43,114,8,135,176,137,136,239,232,0,0,222,227,120,142,0,69,65,81,65,145,243,120,129,195,57,132,77,4,125,172,73,};
|
||||
//uint16_t f1_offsets[] = {0,1,3,7,14,20,28,34,36,40,44,50,56,59,64,66,70,76,80,86,92,98,104,110,116,122,128,130,133,137,142,146,152,160,166,172,178,184,190,196,202,208,210,216,222,228,236,242,248,254,260,266,272,278,284,290,298,304,310,316,320,324,328,334,340,343,349,355,361,367,373,379,385,391,393,399,405,407,415,421,427,433,439,445,451,457,463,469,477,483,489,495,500,502,507,};
|
||||
//FontWrap fnt_f1(512,9,f1_data,f1_offsets);
|
||||
|
||||
//uint8_t f1_data[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40,128,0,128,20,0,0,0,0,0,0,0,0,0,0,0,0,0,240,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,53,0,2,229,155,6,162,138,0,128,156,227,251,162,239,251,190,15,8,226,11,250,158,239,249,190,47,250,184,40,136,162,239,249,158,239,139,162,40,138,190,4,34,0,124,207,247,124,223,23,125,92,20,124,223,247,125,223,247,69,81,21,69,159,36,0,130,175,88,18,34,135,0,64,34,2,130,162,32,128,162,168,228,4,234,138,162,32,10,130,32,34,160,36,216,166,40,138,162,128,136,162,72,137,144,8,82,0,64,81,16,69,65,16,17,80,18,84,81,20,69,65,64,68,81,165,68,136,36,0,2,229,35,62,162,239,227,32,34,226,227,190,239,131,190,15,2,136,171,250,190,32,58,142,238,35,160,35,168,170,232,171,190,143,136,162,138,248,136,16,138,0,124,95,16,125,71,247,17,208,17,84,81,244,85,193,71,68,81,69,124,196,100,0,128,143,210,18,34,135,0,16,34,34,128,32,40,130,34,8,228,4,232,139,162,32,10,130,40,34,160,36,136,178,40,72,18,136,136,148,77,33,132,32,2,0,68,81,16,5,65,20,17,80,18,84,81,20,36,1,68,68,74,165,64,130,36,0,2,229,203,62,162,138,8,10,156,239,251,160,231,131,190,175,8,130,8,136,158,239,249,130,47,250,158,232,139,162,47,184,162,143,248,136,40,34,190,64,2,0,124,207,247,124,193,23,125,79,244,85,209,23,92,193,71,124,196,23,125,159,36,0,0,128,0,0,20,0,8,0,0,0,0,0,0,0,0,128,0,0,240,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,1,3,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,49,0,};
|
||||
//uint16_t f1_offsets[] = {0,1,3,7,13,19,25,31,33,36,39,45,51,53,57,59,65,71,77,83,89,95,101,107,113,119,125,127,129,133,137,141,147,155,161,167,173,179,185,191,197,203,209,215,221,227,233,239,245,251,257,263,269,275,281,287,293,299,305,311,314,320,323,329,335,338,344,350,356,362,368,374,380,386,392,398,404,410,416,422,428,434,440,446,452,458,464,470,476,482,488,494,498,500,};
|
||||
//FontWrap fnt_f1(512,9,f1_data,f1_offsets);
|
||||
|
||||
//static uint8_t f1_data[] = {40,0,4,0,0,130,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,10,158,16,132,130,42,0,0,64,140,56,142,228,49,15,195,0,16,32,48,0,140,195,57,239,113,210,129,36,33,52,113,56,140,195,249,164,72,80,36,242,137,0,2,4,4,0,1,12,16,36,4,1,0,0,0,0,16,0,0,0,0,48,26,0,2,10,69,9,138,130,8,0,0,32,210,64,144,36,8,136,36,1,8,64,72,0,146,36,72,33,8,146,128,36,97,54,137,72,146,36,32,164,72,144,34,2,9,1,2,12,4,0,1,2,16,0,36,1,0,0,0,0,16,0,0,0,0,16,18,0,130,63,133,4,132,130,0,2,0,16,146,64,144,36,8,136,36,1,196,135,64,60,146,36,72,33,8,146,128,20,161,85,137,72,146,36,32,164,72,146,66,129,8,2,2,192,28,199,25,135,113,36,20,253,112,204,193,53,183,148,130,34,233,17,18,0,2,10,14,194,10,130,0,2,30,8,146,48,12,231,56,4,195,73,2,0,33,66,158,35,72,231,105,158,128,12,33,84,137,56,146,195,32,36,133,10,65,65,8,4,2,0,165,32,37,66,146,36,12,37,145,82,34,141,144,148,146,20,9,9,34,0,130,63,20,9,17,130,128,15,0,4,146,8,16,4,73,132,4,1,196,135,16,89,146,36,72,33,72,146,144,20,33,84,137,8,146,4,33,36,133,138,130,32,8,8,2,192,165,32,29,66,146,36,20,37,145,82,34,5,147,148,146,8,201,16,18,0,2,10,148,20,17,130,0,66,0,2,146,8,16,4,73,132,4,65,8,64,0,85,146,36,72,33,72,146,144,36,33,148,137,8,146,4,33,36,133,138,130,16,8,16,2,32,165,32,5,66,146,36,36,37,145,82,34,5,148,164,146,20,41,16,18,0,2,10,79,136,14,130,0,66,64,1,140,120,14,228,48,4,195,72,16,32,16,57,146,195,57,47,48,210,97,36,47,148,113,8,140,228,32,24,130,77,132,240,9,32,226,193,29,199,25,130,147,36,36,37,145,204,193,133,35,71,108,34,238,49,26,0,0,0,4,0,0,130,0,32,0,0,0,0,0,0,0,0,0,32,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,8,0,2,0,0,0,0,0,2,32,0,0,0,64,0,1,0,0,0,0,8,0,0,0,2,0,0,0,0,68,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,2,0,0,0,0,128,1,16,0,0,0,64,0,1,0,0,0,0,6,0,0,0,};
|
||||
//static uint16_t f1_offsets[] = {0,1,3,7,15,22,30,38,41,45,49,55,61,65,70,72,80,86,90,96,102,108,114,120,126,132,138,141,144,150,156,162,168,176,182,188,194,200,205,210,216,222,227,233,239,245,252,259,266,272,278,284,290,297,303,310,318,325,332,339,343,351,355,356,362,365,370,375,380,386,391,397,403,409,412,417,423,426,435,441,446,452,458,463,468,471,476,481,489,495,501,507,512,515,};
|
||||
//static FontWrap fnt_f1(528,10,f1_data,f1_offsets);
|
||||
|
||||
//static uint8_t f1_data[] = {42,202,49,130,17,133,0,0,228,144,227,32,158,243,57,14,0,0,224,224,3,225,195,121,124,31,71,40,20,10,130,66,28,15,199,199,243,133,130,33,36,20,228,91,140,0,4,8,0,8,32,32,40,33,0,0,0,0,0,2,0,0,0,0,128,10,42,170,74,65,146,200,1,0,20,89,20,49,66,132,68,17,0,0,16,25,132,34,38,138,4,129,72,40,20,9,198,70,34,145,72,40,68,132,130,81,68,34,2,73,72,1,8,8,0,8,16,32,0,33,0,0,0,0,0,2,0,0,0,0,64,18,170,175,72,65,82,144,16,0,18,21,4,41,65,128,68,81,65,64,0,201,138,34,22,8,5,65,80,40,148,8,198,74,65,81,80,40,64,132,68,82,66,34,130,136,72,1,192,105,28,203,57,171,41,169,158,199,105,172,114,39,138,34,138,162,79,18,2,197,177,128,65,80,17,0,18,17,228,40,207,67,56,17,56,159,131,164,139,226,23,8,125,79,192,47,212,8,170,74,65,81,208,199,64,132,68,82,130,65,129,136,40,2,32,154,162,44,146,108,42,165,165,40,154,178,137,34,138,82,82,34,68,18,2,133,130,70,65,16,124,0,18,17,2,37,80,68,68,30,4,0,68,148,201,38,22,8,5,65,92,40,180,8,170,82,65,79,80,2,67,132,40,138,130,129,64,136,8,0,192,139,130,232,147,40,42,163,164,40,138,162,48,34,82,84,33,20,34,34,130,143,66,41,70,16,16,28,18,17,1,125,80,36,68,16,56,159,67,148,201,39,22,8,5,65,80,168,20,9,170,82,65,65,86,4,68,132,40,138,66,130,64,136,8,0,32,138,130,40,144,40,42,165,164,40,138,162,64,34,82,84,33,20,66,18,128,162,66,41,66,16,16,0,17,145,16,33,81,36,68,17,64,64,0,148,37,40,38,138,4,129,72,168,20,9,146,98,34,129,72,36,68,132,16,4,65,130,32,8,9,0,32,155,162,44,146,44,42,165,164,40,154,178,136,34,35,136,80,8,65,18,130,194,33,198,69,16,0,65,225,208,231,32,142,35,56,78,1,0,64,228,35,232,195,121,124,1,71,40,19,250,146,66,28,1,87,200,67,120,16,4,33,132,240,11,9,0,192,106,28,203,17,43,42,169,164,200,105,172,112,198,34,136,136,136,79,18,0,128,0,0,128,8,0,1,0,0,0,0,0,0,0,0,1,0,0,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,0,0,0,0,0,0,8,32,0,0,0,8,32,0,0,0,0,0,8,64,18,0,0,0,0,0,5,0,1,0,0,0,0,0,0,0,0,1,0,0,240,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,12,248,1,0,0,0,128,7,16,0,0,0,8,32,0,0,0,0,0,4,128,10,};
|
||||
//static uint16_t f1_offsets[] = {0,1,3,7,13,19,29,36,38,42,46,50,56,58,62,64,68,74,78,84,90,96,102,108,114,120,126,128,130,136,142,148,154,165,173,180,187,194,200,206,214,221,223,228,235,241,249,256,264,270,278,285,292,298,305,313,325,332,340,347,350,354,357,363,370,373,379,385,391,397,403,407,413,419,421,424,429,431,439,445,451,457,463,467,473,477,483,489,499,505,511,517,521,523,};
|
||||
//static FontWrap fnt_f1(528,10,f1_data,f1_offsets);
|
||||
|
||||
static uint8_t f1_data[] = {0,0,5,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,137,159,16,35,155,10,0,0,144,179,231,65,62,231,115,28,0,1,193,241,113,30,231,249,62,39,58,40,10,66,145,243,56,30,231,139,162,160,40,250,46,224,4,16,32,0,32,128,1,65,10,1,0,0,0,0,64,0,0,0,0,0,204,102,0,170,95,69,137,164,32,7,0,0,72,36,8,98,130,0,138,34,128,0,34,10,138,162,40,10,130,40,18,40,9,102,81,20,69,162,136,136,162,160,40,130,66,128,10,32,32,0,32,64,0,1,8,1,0,0,0,0,64,0,0,0,0,0,34,137,0,2,73,133,132,164,160,138,0,0,68,38,8,82,130,0,137,162,77,0,4,234,138,162,32,10,130,32,18,168,8,90,83,20,69,162,128,136,162,36,37,66,130,128,0,0,231,113,60,231,120,79,74,253,60,206,227,53,239,69,81,82,20,125,34,136,0,2,137,15,130,131,32,130,0,0,66,37,199,73,158,7,113,188,45,124,8,169,250,158,32,122,158,238,19,104,8,66,85,20,69,34,135,136,162,36,66,33,2,129,0,0,40,138,162,72,68,81,42,37,69,81,20,141,64,68,81,146,18,33,33,8,1,130,31,21,73,138,32,224,195,3,193,164,0,250,160,136,136,32,64,0,132,232,139,162,32,10,130,40,18,168,8,66,89,244,68,30,136,136,20,21,133,16,2,130,0,0,47,10,162,79,68,81,26,37,69,81,20,5,71,68,74,18,17,17,66,132,0,0,9,149,84,132,32,128,24,152,64,164,0,66,160,136,136,160,141,124,2,8,136,162,40,10,130,40,146,40,9,66,81,20,100,146,136,136,20,149,136,8,2,132,0,128,40,138,162,64,68,81,42,37,69,81,20,5,72,68,74,146,18,9,130,130,0,2,192,79,136,11,27,128,24,88,128,163,239,65,30,71,112,156,13,1,129,240,137,30,231,249,2,39,58,39,250,66,145,19,120,34,135,112,8,138,136,248,14,232,224,7,239,113,60,79,120,81,74,37,69,206,227,133,135,57,132,77,228,125,12,97,0,0,0,5,0,0,0,0,16,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,2,0,0,64,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,1,0,0,64,0,1,0,0,0,0,224,0,0,0,0,};
|
||||
static uint16_t f1_offsets[] = {0,1,3,7,14,22,30,37,39,43,47,53,59,62,67,70,78,84,87,93,99,105,111,117,123,129,135,138,141,146,152,157,163,171,177,183,189,195,201,207,213,219,223,229,235,241,248,254,260,266,273,279,285,291,297,303,311,317,323,329,333,341,345,349,356,359,365,371,377,383,389,394,400,406,408,411,416,418,426,432,438,444,450,455,461,466,472,478,486,492,498,504,509,517,};
|
||||
static FontWrap fnt_f1(528,10,f1_data,f1_offsets);
|
||||
|
||||
|
||||
|
||||
#include "UIElement.h"
|
||||
#include "UIStructs.h"
|
||||
#include "UIPainter.h"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#include <vector>
|
||||
|
||||
class UI {
|
||||
|
||||
UIPainter p;
|
||||
UIElement root;
|
||||
|
||||
UIElement* eFocused = nullptr;
|
||||
UIElement* eDown = nullptr;
|
||||
|
||||
Color cBackground = Color::fromRGB(180,240,180);
|
||||
|
||||
public:
|
||||
|
||||
UI() {
|
||||
root.setRect(0,0,240,320);
|
||||
root.setVisible(true);
|
||||
p.setFG(cBackground);
|
||||
p.fillRect(root.getRect());
|
||||
}
|
||||
|
||||
void add(UIElement* e) {
|
||||
root.addChild(e);
|
||||
}
|
||||
|
||||
void onTouch(const uint16_t x, const uint16_t y) {
|
||||
|
||||
if (eDown) {
|
||||
|
||||
const uint16_t x1 = x - eDown->getRect().x; // (x,y) relative to elements top-left
|
||||
const uint16_t y1 = y - eDown->getRect().y;
|
||||
eDown->onTouch(x1, y1);
|
||||
|
||||
} else {
|
||||
|
||||
ESP_LOGI("UI", "root_onTouch(%d, %d)", x,y );
|
||||
eDown = root._onTouch(x,y);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void onTouchDone() {
|
||||
if (eDown) {
|
||||
eDown->onTouchUp();
|
||||
eDown = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
//debugMod1("UI", "draw %zu elements", elements.size());
|
||||
// for (UIElement* e : elements) {
|
||||
// e->_draw(p);
|
||||
// }
|
||||
root._draw(p);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // UI_H
|
||||
97
ext/lcd/ui/UIButton.h
Normal file
97
ext/lcd/ui/UIButton.h
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef UI_BUTTON_H
|
||||
#define UI_BUTTON_H
|
||||
|
||||
#include "UIElement.h"
|
||||
|
||||
class UIButton : public UIElement {
|
||||
|
||||
public:
|
||||
|
||||
class Listener {
|
||||
public:
|
||||
virtual void onClick(UIButton*) = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
bool enabled = true;
|
||||
|
||||
const char* txt;
|
||||
uint8_t txtH;
|
||||
uint16_t txtW;
|
||||
bool down = false;
|
||||
|
||||
const Color fillNormal = Color::fromRGB(180,180,180);
|
||||
const Color fillDown = Color::fromRGB(120,120,120);
|
||||
const Color frameBright = Color::fromRGB(230,230,230);
|
||||
const Color frameDark = Color::fromRGB(50,50,50);
|
||||
|
||||
const Color cText = Color::fromRGB(0,0,0);
|
||||
const Color cTextDisabled = Color::fromRGB(140,140,140);
|
||||
|
||||
Listener* listener = nullptr;
|
||||
|
||||
static constexpr const char* TAG = "UIButton";
|
||||
|
||||
public:
|
||||
|
||||
UIButton(const char* txt) : txt(txt) {
|
||||
txtW = fnt_f1.getWidth(txt);
|
||||
txtH = fnt_f1.getHeight();
|
||||
}
|
||||
|
||||
void setText(const char* txt) {
|
||||
this->txt = txt;
|
||||
}
|
||||
const char* getText() const {
|
||||
return this->txt;
|
||||
}
|
||||
|
||||
void setListener(Listener* l) {
|
||||
this->listener = l;
|
||||
}
|
||||
|
||||
void setEnabled(const bool en) {
|
||||
this->enabled = en;
|
||||
setNeedsRedraw();
|
||||
}
|
||||
|
||||
void draw(UIPainter& p) override {
|
||||
|
||||
p.setFG( down ? fillDown : fillNormal );
|
||||
p.fillRect(rect);
|
||||
|
||||
p.setFG( down ? frameDark : frameBright );
|
||||
// p.drawLine(rect.x, rect.y, rect.x+rect.w, rect.y); // top
|
||||
// p.drawLine(rect.x, rect.y, rect.x, rect.y+rect.h); // left
|
||||
p.drawLineHor(rect.x, rect.x+rect.w, rect.y); // top
|
||||
p.drawLineVer(rect.y, rect.y+rect.h, rect.x); // left;
|
||||
|
||||
p.setFG( down ? frameBright : frameDark );
|
||||
// p.drawLine(rect.x, rect.y+rect.h, rect.x+rect.w, rect.y+rect.h); // bottom
|
||||
// p.drawLine(rect.x+rect.w, rect.y, rect.x+rect.w, rect.y+rect.h); // right
|
||||
p.drawLineHor(rect.x, rect.x+rect.w, rect.y+rect.h); // bottom
|
||||
p.drawLineVer(rect.y, rect.y+rect.h, rect.x+rect.w); // right;
|
||||
|
||||
p.setFG( enabled ? cText : cTextDisabled );
|
||||
uint16_t o = down ? 1 : 0;
|
||||
p.drawText(rect.x+rect.w/2-txtW/2+o, rect.y+rect.h/2-txtH/2+o, txt);
|
||||
|
||||
}
|
||||
|
||||
void onTouchDown(const uint16_t, const uint16_t) override {
|
||||
ESP_LOGI(TAG, "onTouchDown()");
|
||||
if (!enabled) {return;}
|
||||
down = true;
|
||||
setNeedsRedraw();
|
||||
}
|
||||
void onTouchUp() override {
|
||||
if (!enabled) {return;}
|
||||
down = false;
|
||||
setNeedsRedraw();
|
||||
if (listener) {listener->onClick(this);}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // UI_BUTTON_H
|
||||
121
ext/lcd/ui/UIElement.h
Normal file
121
ext/lcd/ui/UIElement.h
Normal file
@@ -0,0 +1,121 @@
|
||||
#ifndef UI_ELEMENT_H
|
||||
#define UI_ELEMENT_H
|
||||
|
||||
#include "UIStructs.h"
|
||||
#include "UIPainter.h"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#include <vector>
|
||||
|
||||
class UIElement {
|
||||
|
||||
protected:
|
||||
|
||||
UIRect rect;
|
||||
bool _visible = true;
|
||||
bool _needsRedraw = true;
|
||||
|
||||
std::vector<UIElement*> children;
|
||||
|
||||
static constexpr const char* TAG = "UIElement";
|
||||
|
||||
public:
|
||||
|
||||
void setRect(const UIRect r) {
|
||||
this->rect = r;
|
||||
setNeedsRedraw();
|
||||
reLayout();
|
||||
}
|
||||
void setRect(const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h) {
|
||||
this->rect = UIRect(x,y,w,h);
|
||||
setNeedsRedraw();
|
||||
reLayout();
|
||||
}
|
||||
const UIRect& getRect() const {
|
||||
return rect;
|
||||
}
|
||||
|
||||
void setVisible(bool visible) {
|
||||
this->_visible = visible;
|
||||
setNeedsRedraw();
|
||||
}
|
||||
bool isVisible() const {
|
||||
return this->_visible;
|
||||
}
|
||||
|
||||
void setNeedsRedraw() {
|
||||
this->_needsRedraw = true;
|
||||
}
|
||||
bool needsRedraw() const {
|
||||
return this->_needsRedraw;
|
||||
}
|
||||
|
||||
void addChild(UIElement* e) {
|
||||
children.push_back(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
friend class UI;
|
||||
|
||||
virtual void draw(UIPainter& p) {;}
|
||||
|
||||
/** layout needs updating */
|
||||
virtual void reLayout() {;}
|
||||
|
||||
virtual void onTouchDown(uint16_t, uint16_t) {;} // relative (x,y) coordinate
|
||||
virtual void onTouch(uint16_t, uint16_t) {;} // relative (x,y) coordinate
|
||||
virtual void onTouchUp() {;}
|
||||
|
||||
protected:
|
||||
|
||||
UIElement* _onTouch(const uint16_t x, const uint16_t y) {
|
||||
|
||||
|
||||
// if i'm invisible, ignore for me and children
|
||||
if (!isVisible()) {return nullptr;}
|
||||
|
||||
// touch outside of me, ignore for me and children
|
||||
if (!getRect().contains(x,y)) {return nullptr;}
|
||||
|
||||
// find first child that takes the event
|
||||
for (UIElement* e : children) {
|
||||
UIElement* taken = e->_onTouch(x, y);
|
||||
if (taken) {return taken;}
|
||||
}
|
||||
|
||||
// take the event myself
|
||||
const uint16_t x1 = x - getRect().x; // (x,y) relative to elements top-left
|
||||
const uint16_t y1 = y - getRect().y;
|
||||
debugMod2(TAG, "onTouchDown(%d,%d)", x1, y1);
|
||||
onTouchDown(x1, y1);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
void _draw(UIPainter& p) {
|
||||
|
||||
// if hidde, ignore for me and children
|
||||
if (!_visible) {return;}
|
||||
|
||||
// draw myself (if needed)
|
||||
if (_needsRedraw) {
|
||||
draw(p);
|
||||
_needsRedraw = false;
|
||||
}
|
||||
|
||||
// call for children as well
|
||||
for (UIElement* child : children) {
|
||||
child->_draw(p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // UI_ELEMENT_H
|
||||
45
ext/lcd/ui/UILabel.h
Normal file
45
ext/lcd/ui/UILabel.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef UI_LABEL_H
|
||||
#define UI_LABEL_H
|
||||
|
||||
#include "UIElement.h"
|
||||
#include "UIStructs.h"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#include <string>
|
||||
|
||||
class UILabel : public UIElement {
|
||||
|
||||
std::string txt;
|
||||
|
||||
Color cBackground = Color::fromRGB(255,255,255);
|
||||
Color cText = Color::fromRGB(0,0,0);
|
||||
|
||||
public:
|
||||
|
||||
UILabel() {
|
||||
;
|
||||
}
|
||||
|
||||
void setText(const std::string& txt) {
|
||||
this->txt = txt;
|
||||
setNeedsRedraw();
|
||||
}
|
||||
|
||||
void draw(UIPainter& p) {
|
||||
|
||||
p.setFG(cBackground);
|
||||
p.fillRect(rect);
|
||||
|
||||
//const uint16_t txtW = fnt_f1.getWidth(txt);
|
||||
//const uint16_t txtH = fnt_f1.getHeight();
|
||||
|
||||
p.setFG(cText);
|
||||
p.drawText(rect.x, rect.y, txt.c_str());
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // UI_LABEL_H
|
||||
208
ext/lcd/ui/UIList.h
Normal file
208
ext/lcd/ui/UIList.h
Normal file
@@ -0,0 +1,208 @@
|
||||
#ifndef UI_LIST_H
|
||||
#define UI_LIST_H
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "UIElement.h"
|
||||
#include "UIButton.h"
|
||||
|
||||
class UIListModel {
|
||||
|
||||
std::vector<std::string> entries;
|
||||
|
||||
public:
|
||||
|
||||
void add(const std::string& str) {
|
||||
entries.push_back(str);
|
||||
}
|
||||
|
||||
void remove(const size_t idx) {
|
||||
entries.erase(entries.begin()+idx);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return entries.size();
|
||||
}
|
||||
|
||||
const std::string& get(const size_t idx) const {
|
||||
return entries[idx];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class UIList : public UIElement, public UIButton::Listener {
|
||||
|
||||
public:
|
||||
|
||||
class Listener {
|
||||
public:
|
||||
virtual void onSelected(UIList* lst, int idx) = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
UIListModel model;
|
||||
int offset = 0;
|
||||
int selectedIndex = -1;
|
||||
|
||||
UIButton btnUp;
|
||||
UIButton btnDown;
|
||||
|
||||
static constexpr const int btnW = 32;
|
||||
|
||||
Color cRect = Color::fromRGB(0,0,0);
|
||||
Color cNormalBG = Color::fromRGB(230,230,230);
|
||||
Color cSelectedBG = Color::fromRGB(190,190,255);
|
||||
Color cText = Color::fromRGB(0,0,0);
|
||||
|
||||
Listener* listener = nullptr;
|
||||
|
||||
static constexpr const char* TAG = "UIList";
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
UIList() : btnUp("<"), btnDown(">") {
|
||||
addChild(&btnUp);
|
||||
addChild(&btnDown);
|
||||
btnUp.setListener(this);
|
||||
btnDown.setListener(this);
|
||||
}
|
||||
|
||||
void setListener(Listener* l) {
|
||||
this->listener = l;
|
||||
}
|
||||
|
||||
// UIListModel& getModel() {
|
||||
// setNeedsRedraw();
|
||||
// return model;
|
||||
// }
|
||||
|
||||
// const UIListModel& getModel() const {
|
||||
// return model;
|
||||
// }
|
||||
|
||||
void add(const std::string& str) {
|
||||
model.add(str);
|
||||
btnUp.setVisible(needsScroll());
|
||||
btnDown.setVisible(needsScroll());
|
||||
setNeedsRedraw();
|
||||
}
|
||||
|
||||
void remove(const size_t idx) {
|
||||
model.remove(idx);
|
||||
if (idx == selectedIndex) {
|
||||
selectedIndex = -1;
|
||||
if (listener) {listener->onSelected(this, selectedIndex);}
|
||||
} else if (idx < selectedIndex) {
|
||||
--selectedIndex;
|
||||
if (listener) {listener->onSelected(this, selectedIndex);}
|
||||
}
|
||||
if (offset > maxOffset()) {offset = maxOffset();}
|
||||
btnUp.setVisible(needsScroll());
|
||||
btnDown.setVisible(needsScroll());
|
||||
setNeedsRedraw();
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return model.size();
|
||||
}
|
||||
|
||||
const std::string& get(const size_t idx) const {
|
||||
return model.get(idx);
|
||||
}
|
||||
|
||||
int getSelectedIndex() const {
|
||||
return this->selectedIndex;
|
||||
}
|
||||
|
||||
void reLayout() override {
|
||||
int h = rect.h / 2 - 1;
|
||||
btnUp.setRect(rect.x+rect.w-btnW-1, rect.y+1, btnW, h);
|
||||
btnDown.setRect(rect.x+rect.w-btnW-1, rect.y+h+2, btnW, h);
|
||||
}
|
||||
|
||||
virtual void draw(UIPainter& p) override {
|
||||
|
||||
debugMod(TAG, "draw()");
|
||||
debugMod4(TAG, "rect: %d %d %d %d", rect.x, rect.y, rect.w, rect.h);
|
||||
|
||||
const uint8_t oy = (elementHeight() - fnt_f1.getHeight()) / 2;
|
||||
const uint16_t entryW = rect.w - (needsScroll() ? btnW : 0);
|
||||
|
||||
// outline rectangle
|
||||
p.setFG(cNormalBG);
|
||||
p.fillRect(rect.x+1, rect.y+1, entryW, rect.h-2);
|
||||
p.setFG(cRect);
|
||||
p.drawRect(rect);
|
||||
|
||||
// display as many elements as fit within the list's height
|
||||
for (unsigned int i = 0; i < elementsVisible(); ++i) {
|
||||
|
||||
// determine position (y-coordinate)
|
||||
const uint16_t y = i * elementHeight();
|
||||
|
||||
// determine element from model
|
||||
const int idx = i+offset;
|
||||
const bool selected = idx == selectedIndex;
|
||||
|
||||
// draw background depending on selection
|
||||
//p.setFG( selected ? cSelectedBG : cNormalBG );
|
||||
//p.fillRect(UIRect(rect.x+1, rect.y+y+1, entryW-1, elementHeight()-1));
|
||||
if (selected) {
|
||||
p.setFG( cSelectedBG );
|
||||
p.fillRect(UIRect(rect.x+1, rect.y+y+1, entryW-1, elementHeight()-1));
|
||||
}
|
||||
|
||||
// draw text
|
||||
p.setFG(cText);
|
||||
p.drawText(rect.x+3, rect.y + y + oy, model.get(idx).c_str());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
virtual void onTouchDown(uint16_t, uint16_t y) override {
|
||||
unsigned int idx = y / elementHeight() + offset;
|
||||
this->selectedIndex = (idx < numElements()) ? (idx) : (-1);
|
||||
debugMod1(TAG, "selected: %d", selectedIndex);
|
||||
setNeedsRedraw();
|
||||
if (listener) {listener->onSelected(this, selectedIndex);}
|
||||
}
|
||||
|
||||
virtual void onTouch(uint16_t, uint16_t) override {
|
||||
|
||||
}
|
||||
|
||||
virtual void onTouchUp() override {
|
||||
|
||||
}
|
||||
|
||||
virtual void onClick(UIButton* btn) override {
|
||||
if (btn == &btnUp) {
|
||||
if (offset > 0) {--offset; setNeedsRedraw();}
|
||||
} else if (btn == &btnDown) {
|
||||
if (offset < maxOffset()) {++offset; setNeedsRedraw();}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
unsigned int elementHeight() const {return 16;}
|
||||
unsigned int maxElementsVisible() const {return rect.h / elementHeight();}
|
||||
unsigned int elementsVisible() const {return std::min(maxElementsVisible(), numElements());}
|
||||
unsigned int numElements() const {return model.size();}
|
||||
unsigned int maxOffset() const {return numElements()-maxElementsVisible();}
|
||||
bool needsScroll() const {return numElements() > maxElementsVisible();}
|
||||
|
||||
};
|
||||
|
||||
#endif // UI_LIST_H
|
||||
52
ext/lcd/ui/UIPainter.h
Normal file
52
ext/lcd/ui/UIPainter.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef UI_PAINTER_H
|
||||
#define UI_PAINTER_H
|
||||
|
||||
#include "../../../Debug.h"
|
||||
#include "../Draw.h"
|
||||
#include "UIStructs.h"
|
||||
|
||||
class Setter;
|
||||
class FontWrap;
|
||||
|
||||
extern FontWrap fnt_f1;
|
||||
extern Setter setter;
|
||||
|
||||
class UIPainter {
|
||||
|
||||
public:
|
||||
|
||||
void drawLine(const uint16_t x1, const uint16_t y1, const uint16_t x2, const uint16_t y2) {
|
||||
debugMod("UI", "draw line");
|
||||
drawer.drawLine(x1,y1, x2,y2);
|
||||
}
|
||||
|
||||
void drawLineHor(const uint16_t x1, const uint16_t x2, const uint16_t y) {
|
||||
drawer.drawLineHor(x1,x2,y);
|
||||
}
|
||||
void drawLineVer(const uint16_t y1, const uint16_t y2, const uint16_t x) {
|
||||
drawer.drawLineVer(y1,y2,x);
|
||||
}
|
||||
|
||||
void drawRect(UIRect r) {
|
||||
drawer.drawRect(r.x, r.y, r.w, r.h);
|
||||
}
|
||||
|
||||
void drawText(const uint16_t x, const uint16_t y, const char* str) {
|
||||
fnt_f1.draw(str, x, y, setter);
|
||||
}
|
||||
|
||||
void setFG(const Color fg) {
|
||||
drawer.setColor(fg);
|
||||
}
|
||||
|
||||
void fillRect(const UIRect rect) {
|
||||
drawer.fillRect(rect.x, rect.y, rect.w, rect.h);
|
||||
}
|
||||
void fillRect(const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h) {
|
||||
drawer.fillRect(x,y,w,h);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // UI_PAINTER_H
|
||||
|
||||
39
ext/lcd/ui/UIStructs.h
Normal file
39
ext/lcd/ui/UIStructs.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef UI_STRUCTS_H
|
||||
#define UI_STRUCTS_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
struct UIPoint {
|
||||
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
|
||||
UIPoint() : x(0), y(0) {;}
|
||||
|
||||
UIPoint(uint16_t x, uint16_t y) : x(x), y(y) {;}
|
||||
|
||||
};
|
||||
|
||||
struct UIRect {
|
||||
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
|
||||
UIRect() : x(0), y(0), w(0), h(0) {;}
|
||||
|
||||
UIRect(const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h) : x(x), y(y), w(w), h(h) {;}
|
||||
|
||||
bool contains(const uint16_t x, const uint16_t y) const {
|
||||
return
|
||||
(this->x <= x) &&
|
||||
(this->y <= y) &&
|
||||
(x <= this->x+this->w) &&
|
||||
(y <= this->y+this->h);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // UI_STRUCTS_H
|
||||
BIN
ext/lcd/ui/ui.tar.gz
Normal file
BIN
ext/lcd/ui/ui.tar.gz
Normal file
Binary file not shown.
Reference in New Issue
Block a user