Merge pull request #11821 from gemu2015/mdisp

multi display support
This commit is contained in:
Theo Arends 2021-04-21 11:56:20 +02:00 committed by GitHub
commit 108383e04b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 452 additions and 277 deletions

View File

@ -220,7 +220,7 @@ virtual void
uint16_t
textcolor, ///< 16-bit background color for print()
textbgcolor; ///< 16-bit text color for print()
uint8_t *framebuffer;
protected:
void
charBounds(char c, int16_t *x, int16_t *y,

View File

@ -38,7 +38,8 @@ However, SH1106 driver don't provide several functions such as scroll commands.
#define DISPLAY_INIT_MODE 0
// the memory buffer for the LCD
extern uint8_t *buffer;
uint8_t *dbuff;
Adafruit_SH1106::Adafruit_SH1106(int16_t width, int16_t height) :
Renderer(width,height) {
@ -59,6 +60,7 @@ void Adafruit_SH1106::Updateframe() {
void Adafruit_SH1106::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) {
// ignore update mode
//if (p==DISPLAY_INIT_MODE) {
// allocate screen buffer
setRotation(rot);
invertDisplay(false);
setTextWrap(false); // Allow text to run off edges
@ -67,6 +69,7 @@ void Adafruit_SH1106::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) {
setTextSize(size);
setTextColor(WHITE, BLACK);
setCursor(0,0);
//fillScreen(BLACK);
fillScreen(BLACK);
Updateframe();
//}
@ -77,9 +80,13 @@ void Adafruit_SH1106::Begin(int16_t p1,int16_t p2,int16_t p3) {
}
void Adafruit_SH1106::begin(uint8_t vccstate, uint8_t i2caddr, bool reset) {
boolean Adafruit_SH1106::begin(uint8_t vccstate, uint8_t i2caddr, bool reset) {
_vccstate = vccstate;
_i2caddr = i2caddr;
framebuffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8));
if (!framebuffer) return false;
// I2C Init
Wire.begin();
@ -193,6 +200,9 @@ void Adafruit_SH1106::begin(uint8_t vccstate, uint8_t i2caddr, bool reset) {
#endif
SH1106_command(SH1106_DISPLAYON);//--turn on oled panel
return true;
}
@ -277,7 +287,7 @@ void Adafruit_SH1106::display(void) {
Wire.beginTransmission(_i2caddr);
Wire.write(0x40);
for ( k = 0; k < width; k++, p++) {
Wire.write(buffer[p]);
Wire.write(framebuffer[p]);
}
Wire.endTransmission();
}
@ -287,5 +297,5 @@ void Adafruit_SH1106::display(void) {
// clear everything
void Adafruit_SH1106::clearDisplay(void) {
memset(buffer, 0, (SH1106_LCDWIDTH*SH1106_LCDHEIGHT/8));
memset(framebuffer, 0, (SH1106_LCDWIDTH*SH1106_LCDHEIGHT/8));
}

View File

@ -133,7 +133,7 @@ class Adafruit_SH1106 : public Renderer {
public:
Adafruit_SH1106(int16_t width, int16_t height);
void begin(uint8_t switchvcc = SH1106_SWITCHCAPVCC, uint8_t i2caddr = SH1106_I2C_ADDRESS, bool reset=true);
boolean begin(uint8_t switchvcc = SH1106_SWITCHCAPVCC, uint8_t i2caddr = SH1106_I2C_ADDRESS, bool reset=true);
void SH1106_command(uint8_t c);
void SH1106_data(uint8_t c);

View File

@ -326,9 +326,9 @@ Adafruit_SSD1306::Adafruit_SSD1306(int8_t rst_pin) :
@brief Destructor for Adafruit_SSD1306 object.
*/
Adafruit_SSD1306::~Adafruit_SSD1306(void) {
if(buffer) {
free(buffer);
buffer = NULL;
if (framebuffer) {
free (framebuffer);
framebuffer = NULL;
}
}
@ -451,8 +451,8 @@ void Adafruit_SSD1306::ssd1306_command(uint8_t c) {
boolean Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, boolean reset,
boolean periphBegin) {
// if((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8))))
// return false;
framebuffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8));
if (!framebuffer) return false;
clearDisplay();
@ -627,6 +627,10 @@ void Adafruit_SSD1306::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font)
commands as needed by one's own application.
*/
void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) {
if (!framebuffer) return;
if((x >= 0) && (x < width()) && (y >= 0) && (y < height())) {
// Pixel is in-bounds. Rotate coordinates if needed.
switch(getRotation()) {
@ -644,9 +648,9 @@ void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) {
break;
}
switch(color) {
case WHITE: buffer[x + (y/8)*WIDTH] |= (1 << (y&7)); break;
case BLACK: buffer[x + (y/8)*WIDTH] &= ~(1 << (y&7)); break;
case INVERSE: buffer[x + (y/8)*WIDTH] ^= (1 << (y&7)); break;
case WHITE: framebuffer[x + (y/8)*WIDTH] |= (1 << (y&7)); break;
case BLACK: framebuffer[x + (y/8)*WIDTH] &= ~(1 << (y&7)); break;
case INVERSE: framebuffer[x + (y/8)*WIDTH] ^= (1 << (y&7)); break;
}
}
}
@ -659,7 +663,8 @@ void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) {
commands as needed by one's own application.
*/
void Adafruit_SSD1306::clearDisplay(void) {
memset(buffer, 0, WIDTH * ((HEIGHT + 7) / 8));
if (!framebuffer) return;
memset(framebuffer, 0, WIDTH * ((HEIGHT + 7) / 8));
}
/*!
@ -759,7 +764,7 @@ void Adafruit_SSD1306::drawFastVLine(
void Adafruit_SSD1306::drawFastHLineInternal (
int16_t x, int16_t y, int16_t w, uint16_t color) {
if (!framebuffer) return;
if((y >= 0) && (y < HEIGHT)) { // Y coord in bounds?
if(x < 0) { // Clip left
w += x;
@ -769,7 +774,7 @@ void Adafruit_SSD1306::drawFastHLineInternal(
w = (WIDTH - x);
}
if(w > 0) { // Proceed only if width is positive
uint8_t *pBuf = &buffer[(y / 8) * WIDTH + x],
uint8_t *pBuf = &framebuffer[(y / 8) * WIDTH + x],
mask = 1 << (y & 7);
switch(color) {
case WHITE: while(w--) { *pBuf++ |= mask; }; break;
@ -782,7 +787,7 @@ void Adafruit_SSD1306::drawFastHLineInternal(
void Adafruit_SSD1306::drawFastVLineInternal(
int16_t x, int16_t __y, int16_t __h, uint16_t color) {
if (!framebuffer) return;
if((x >= 0) && (x < WIDTH)) { // X coord in bounds?
if(__y < 0) { // Clip top
__h += __y;
@ -795,7 +800,7 @@ void Adafruit_SSD1306::drawFastVLineInternal(
// this display doesn't need ints for coordinates,
// use local byte registers for faster juggling
uint8_t y = __y, h = __h;
uint8_t *pBuf = &buffer[(y / 8) * WIDTH + x];
uint8_t *pBuf = &framebuffer[(y / 8) * WIDTH + x];
// do the first partial byte, if necessary - this requires some masking
uint8_t mod = (y & 7);
@ -875,6 +880,8 @@ void Adafruit_SSD1306::drawFastVLineInternal(
screen if display() has not been called.
*/
boolean Adafruit_SSD1306::getPixel(int16_t x, int16_t y) {
if (!framebuffer) return 0;
if((x >= 0) && (x < width()) && (y >= 0) && (y < height())) {
// Pixel is in-bounds. Rotate coordinates if needed.
switch(getRotation()) {
@ -891,7 +898,7 @@ boolean Adafruit_SSD1306::getPixel(int16_t x, int16_t y) {
y = HEIGHT - y - 1;
break;
}
return (buffer[x + (y / 8) * WIDTH] & (1 << (y & 7)));
return (framebuffer[x + (y / 8) * WIDTH] & (1 << (y & 7)));
}
return false; // Pixel out of bounds
}
@ -902,7 +909,7 @@ boolean Adafruit_SSD1306::getPixel(int16_t x, int16_t y) {
to full byte boundary if needed.
*/
uint8_t *Adafruit_SSD1306::getBuffer(void) {
return xbuffer;
return framebuffer;
}
@ -916,6 +923,7 @@ uint8_t *Adafruit_SSD1306::getBuffer(void) {
of graphics commands, as best needed by one's own application.
*/
void Adafruit_SSD1306::display(void) {
if (!framebuffer) return;
int16_t col_start = 0;
int16_t col_end = WIDTH - 1;
if ((64 == WIDTH) && (48 == HEIGHT)) { // for 64x48, we need to shift by 32 in both directions
@ -943,7 +951,7 @@ void Adafruit_SSD1306::display(void) {
yield();
#endif
uint16_t count = WIDTH * ((HEIGHT + 7) / 8);
uint8_t *ptr = buffer;
uint8_t *ptr = framebuffer;
if(wire) { // I2C
wire->beginTransmission(i2caddr);
WIRE_WRITE((uint8_t)0x40);

View File

@ -27,8 +27,6 @@
#include <pgmspace.h>
#include "epdpaint.h"
extern uint8_t *buffer;
Paint::Paint(int16_t width, int16_t height) :
Renderer(width,height) {
}
@ -66,15 +64,15 @@ void Paint::DrawAbsolutePixel(int x, int y, int16_t color) {
}
if (IF_INVERT_COLOR) {
if (color) {
buffer[(x + y * w) / 8] |= 0x80 >> (x % 8);
framebuffer[(x + y * w) / 8] |= 0x80 >> (x % 8);
} else {
buffer[(x + y * w) / 8] &= ~(0x80 >> (x % 8));
framebuffer[(x + y * w) / 8] &= ~(0x80 >> (x % 8));
}
} else {
if (color) {
buffer[(x + y * w) / 8] &= ~(0x80 >> (x % 8));
framebuffer[(x + y * w) / 8] &= ~(0x80 >> (x % 8));
} else {
buffer[(x + y * w) / 8] |= 0x80 >> (x % 8);
framebuffer[(x + y * w) / 8] |= 0x80 >> (x % 8);
}
}
}
@ -120,7 +118,7 @@ void Paint::drawPixel(int16_t x, int16_t y, uint16_t color) {
void Paint::drawPixel(int16_t x, int16_t y, uint16_t color) {
if (!buffer) return;
if (!framebuffer) return;
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;

View File

@ -35,8 +35,6 @@
uint8_t wr_redir=0;
uint8_t *buffer;
#define register
#define SPRINT(A) char str[32];sprintf(str,"val: %d ",A);Serial.println((char*)str);
@ -87,6 +85,17 @@ void Renderer::Updateframe() {
}
void Renderer::TS_RotConvert(int16_t *x, int16_t *y) {
}
uint8_t *Renderer::allocate_framebuffer(uint32_t size) {
if (framebuffer) free(framebuffer);
framebuffer = (unsigned char*)calloc(size, 1);
if (!framebuffer) return 0;
return framebuffer;
}
void Renderer::setTextSize(uint8_t sf) {
if (sf < 1) sf = 1;
@ -306,7 +315,7 @@ void Renderer::clearDisplay(void) {
void Renderer::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
boolean bSwap = false;
if (!buffer) return;
if (!framebuffer) return;
switch(getRotation()) {
case 0:
// 0 degree rotation, do nothing
@ -358,7 +367,7 @@ void Renderer::drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t c
if(w <= 0) { return; }
// set up the pointer for movement through the buffer
register uint8_t *pBuf = buffer;
register uint8_t *pBuf = framebuffer;
// adjust the buffer pointer for the current row
pBuf += ((y/8) * WIDTH);
// and offset x columns in
@ -375,7 +384,7 @@ void Renderer::drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t c
}
void Renderer::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
if (!buffer) return;
if (!framebuffer) return;
bool bSwap = false;
switch(getRotation()) {
case 0:
@ -410,7 +419,7 @@ void Renderer::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
void Renderer::drawFastVLineInternal(int16_t x, int16_t __y, int16_t __h, uint16_t color) {
if (!framebuffer) return;
// do nothing if we're off the left or right side of the screen
if(x < 0 || x >= WIDTH) { return; }
@ -438,7 +447,7 @@ void Renderer::drawFastVLineInternal(int16_t x, int16_t __y, int16_t __h, uint16
// set up the pointer for fast movement through the buffer
register uint8_t *pBuf = buffer;
register uint8_t *pBuf = framebuffer;
// adjust the buffer pointer for the current row
pBuf += ((y/8) * WIDTH);
// and offset x columns in
@ -530,7 +539,7 @@ void Renderer::drawPixel(int16_t x, int16_t y, uint16_t color) {
// the most basic function, set a single pixel
void Renderer::drawPixel(int16_t x, int16_t y, uint16_t color) {
if (!buffer) return;
if (!framebuffer) return;
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;
@ -553,9 +562,9 @@ void Renderer::drawPixel(int16_t x, int16_t y, uint16_t color) {
// x is which column
switch (color)
{
case WHITE: buffer[x+ (y/8)*WIDTH] |= (1 << (y&7)); break;
case BLACK: buffer[x+ (y/8)*WIDTH] &= ~(1 << (y&7)); break;
case INVERSE: buffer[x+ (y/8)*WIDTH] ^= (1 << (y&7)); break;
case WHITE: framebuffer[x+ (y/8)*WIDTH] |= (1 << (y&7)); break;
case BLACK: framebuffer[x+ (y/8)*WIDTH] &= ~(1 << (y&7)); break;
case INVERSE: framebuffer[x+ (y/8)*WIDTH] ^= (1 << (y&7)); break;
}
}

View File

@ -41,10 +41,13 @@ public:
virtual void reverseDisplay(boolean i);
virtual void setScrollMargins(uint16_t top, uint16_t bottom);
virtual void scrollTo(uint16_t y);
virtual void TS_RotConvert(int16_t *x, int16_t *y);
void setDrawMode(uint8_t mode);
uint8_t drawmode;
virtual void FastString(uint16_t x,uint16_t y,uint16_t tcolor, const char* str);
void setTextSize(uint8_t s);
virtual uint8_t *allocate_framebuffer(uint32_t size);
private:
void DrawCharAt(int16_t x, int16_t y, char ascii_char,int16_t colored);
inline void drawFastVLineInternal(int16_t x, int16_t y, int16_t h, uint16_t color) __attribute__((always_inline));

View File

@ -27,7 +27,6 @@
#include <stdlib.h>
#include "epd2in9.h"
extern uint8_t *buffer;
Epd::Epd(int16_t width, int16_t height) :
Paint(width,height) {
@ -37,7 +36,7 @@ void Epd::DisplayOnff(int8_t on) {
}
void Epd::Updateframe() {
SetFrameMemory(buffer, 0, 0, EPD_WIDTH,EPD_HEIGHT);
SetFrameMemory(framebuffer, 0, 0, EPD_WIDTH,EPD_HEIGHT);
DisplayFrame();
//Serial.printf("update\n");
}
@ -110,6 +109,10 @@ int Epd::Init(const unsigned char* lut) {
mosi_pin=pin[GPIO_SSPI_MOSI];
sclk_pin=pin[GPIO_SSPI_SCLK];
*/
framebuffer = (uint8_t*)malloc(EPD_WIDTH * EPD_HEIGHT / 8);
if (!framebuffer) return -1;
pinMode(cs_pin, OUTPUT);
pinMode(mosi_pin, OUTPUT);
pinMode(sclk_pin, OUTPUT);

View File

@ -29,8 +29,6 @@
//#define SSPI_USEANYPIN
extern uint8_t *buffer;
uint8_t epd42_mode;
Epd42::Epd42(int16_t width, int16_t height) :
@ -47,7 +45,7 @@ void Epd42::DisplayOnff(int8_t on) {
void Epd42::Updateframe() {
//SetFrameMemory(buffer, 0, 0, EPD_WIDTH,EPD_HEIGHT);
SetPartialWindow(buffer, 0, 0, width,height,2);
SetPartialWindow(framebuffer, 0, 0, width,height,2);
if (epd42_mode==DISPLAY_INIT_PARTIAL) {
DisplayFrameQuick();
} else {
@ -103,6 +101,10 @@ void Epd42::Init(int8_t p) {
}
int Epd42::Init(void) {
framebuffer = (uint8_t*)malloc(EPD_WIDTH42 * EPD_HEIGHT42 / 8);
if (!framebuffer) return -1;
pinMode(cs_pin, OUTPUT);
pinMode(mosi_pin, OUTPUT);
pinMode(sclk_pin, OUTPUT);
@ -115,19 +117,19 @@ int Epd42::Init(void) {
height = EPD_HEIGHT42;
Reset();
SendCommand(EPD_42_POWER_SETTING);
SendCommand(EPD_42_POWER_SETTING); // 0xa1
SendData(0x03); // VDS_EN, VDG_EN
SendData(0x00); // VCOM_HV, VGHL_LV[1], VGHL_LV[0]
SendData(0x2b); // VDH
SendData(0x2b); // VDL
SendData(0xff); // VDHR
SendCommand(EPD_42_BOOSTER_SOFT_START);
SendCommand(EPD_42_BOOSTER_SOFT_START); // axa6
SendData(0x17);
SendData(0x17);
SendData(0x17); //07 0f 17 1f 27 2F 37 2f
SendCommand(EPD_42_POWER_ON);
SendCommand(EPD_42_POWER_ON); // 04
WaitUntilIdle();
SendCommand(EPD_42_PANEL_SETTING);
SendCommand(EPD_42_PANEL_SETTING); //0x00
// SendData(0xbf); // KW-BF KWR-AF BWROTP 0f
// SendData(0x0b);
// SendData(0x0F); //300x400 Red mode, LUT from OTP
@ -135,7 +137,7 @@ int Epd42::Init(void) {
SendData(0x3F); //300x400 B/W mode, LUT set by register
// SendData(0x2F); //300x400 Red mode, LUT set by register
SendCommand(EPD_42_PLL_CONTROL);
SendCommand(EPD_42_PLL_CONTROL); // 0x30
SendData(0x3C); // 3A 100Hz 29 150Hz 39 200Hz 31 171Hz 3C 50Hz (default) 0B 10Hz
//SendData(0x0B); //0B is 10Hz
/* EPD hardware init end */

View File

@ -193,6 +193,8 @@ void ILI9341_2::init(uint16_t width, uint16_t height) {
if (_hwspi > 2) {
spi2->begin(_sclk, _miso, _mosi, -1);
}
#else
SPI.begin();
#endif // ESP32
} else {
#ifdef ESP32

View File

@ -465,7 +465,6 @@ void ILI9488::begin(void) {
writedata(0x02); //2-dot
writecommand(0XB6); //Display Function Control RGB/MCU Interface Control
writedata(0x02); //MCU
writedata(0x02); //Source,Gate scan dieection

0
lib/lib_display/UDisplay/keywords.txt Normal file → Executable file
View File

0
lib/lib_display/UDisplay/library.properties Normal file → Executable file
View File

62
lib/lib_display/UDisplay/uDisplay.cpp Normal file → Executable file
View File

@ -20,7 +20,7 @@
#include <Arduino.h>
#include "uDisplay.h"
//#define UDSP_DEBUG
#define UDSP_DEBUG
const uint16_t udisp_colors[]={UDISP_BLACK,UDISP_WHITE,UDISP_RED,UDISP_GREEN,UDISP_BLUE,UDISP_CYAN,UDISP_MAGENTA,\
UDISP_YELLOW,UDISP_NAVY,UDISP_DARKGREEN,UDISP_DARKCYAN,UDISP_MAROON,UDISP_PURPLE,UDISP_OLIVE,\
@ -31,11 +31,16 @@ uint16_t uDisplay::GetColorFromIndex(uint8_t index) {
return udisp_colors[index];
}
extern uint8_t *buffer;
extern uint8_t color_type;
uDisplay::~uDisplay(void) {
if (framebuffer) {
free(framebuffer);
}
}
uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
// analyse decriptor
framebuffer = 0;
col_mode = 16;
sa_mode = 16;
saw_3 = 0xff;
@ -103,13 +108,17 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
setheight(gys);
bpp = next_val(&lp1);
if (bpp == 1) {
color_type = uCOLOR_BW;
col_type = uCOLOR_BW;
} else {
color_type = uCOLOR_COLOR;
col_type = uCOLOR_COLOR;
}
str2c(&lp1, ibuff, sizeof(ibuff));
if (!strncmp(ibuff, "I2C", 3)) {
interface = _UDSP_I2C;
wire_n = 0;
if (!strncmp(ibuff, "I2C2", 4)) {
wire_n = 1;
}
i2caddr = next_hex(&lp1);
i2c_scl = next_val(&lp1);
i2c_sda = next_val(&lp1);
@ -350,17 +359,24 @@ Renderer *uDisplay::Init(void) {
}
if (interface == _UDSP_I2C) {
if (wire_n == 0) {
wire = &Wire;
}
#ifdef ESP32
if (wire_n == 1) {
wire = &Wire1;
}
#endif
wire->begin(i2c_sda, i2c_scl);
if (bpp < 16) {
if (buffer) free(buffer);
if (framebuffer) free(framebuffer);
#ifdef ESP8266
buffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);
framebuffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);
#else
if (psramFound()) {
buffer = (uint8_t*)heap_caps_malloc((gxs * gys * bpp) / 8, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
framebuffer = (uint8_t*)heap_caps_malloc((gxs * gys * bpp) / 8, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
} else {
buffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);
framebuffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);
}
#endif
}
@ -380,12 +396,12 @@ Renderer *uDisplay::Init(void) {
if (ep_mode) {
#ifdef ESP8266
buffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);
framebuffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);
#else
if (psramFound()) {
buffer = (uint8_t*)heap_caps_malloc((gxs * gys * bpp) / 8, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
framebuffer = (uint8_t*)heap_caps_malloc((gxs * gys * bpp) / 8, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
} else {
buffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);
framebuffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);
}
#endif
}
@ -654,7 +670,7 @@ void uDisplay::Updateframe(void) {
i2c_command(i2c_col_end);
uint16_t count = gxs * ((gys + 7) / 8);
uint8_t *ptr = buffer;
uint8_t *ptr = framebuffer;
wire->beginTransmission(i2caddr);
i2c_command(saw_3);
uint8_t bytesOut = 1;
@ -695,7 +711,7 @@ void uDisplay::Updateframe(void) {
wire->beginTransmission(i2caddr);
wire->write(0x40);
for ( k = 0; k < xs; k++, p++) {
wire->write(buffer[p]);
wire->write(framebuffer[p]);
}
wire->endTransmission();
}
@ -1453,12 +1469,12 @@ void uDisplay::DisplayFrame_42(void) {
spi_command_EPD(saw_2);
for (uint16_t j = 0; j < Height; j++) {
for (uint16_t i = 0; i < Width; i++) {
spi_data8_EPD(buffer[i + j * Width] ^ 0xff);
spi_data8_EPD(framebuffer[i + j * Width] ^ 0xff);
}
}
spi_command_EPD(saw_3);
delay(100);
//Serial.printf("EPD Diplayframe\n");
Serial.printf("EPD Diplayframe\n");
}
@ -1483,7 +1499,7 @@ void uDisplay::ClearFrame_42(void) {
spi_command_EPD(saw_3);
delay(100);
//Serial.printf("EPD Clearframe\n");
Serial.printf("EPD Clearframe\n");
}
@ -1497,7 +1513,7 @@ void uDisplay::SetLut(const unsigned char* lut) {
void uDisplay::Updateframe_EPD(void) {
if (ep_mode == 1) {
SetFrameMemory(buffer, 0, 0, gxs, gys);
SetFrameMemory(framebuffer, 0, 0, gxs, gys);
DisplayFrame_29();
} else {
DisplayFrame_42();
@ -1609,21 +1625,21 @@ void uDisplay::DrawAbsolutePixel(int x, int y, int16_t color) {
}
if (IF_INVERT_COLOR) {
if (color) {
buffer[(x + y * w) / 8] |= 0x80 >> (x % 8);
framebuffer[(x + y * w) / 8] |= 0x80 >> (x % 8);
} else {
buffer[(x + y * w) / 8] &= ~(0x80 >> (x % 8));
framebuffer[(x + y * w) / 8] &= ~(0x80 >> (x % 8));
}
} else {
if (color) {
buffer[(x + y * w) / 8] &= ~(0x80 >> (x % 8));
framebuffer[(x + y * w) / 8] &= ~(0x80 >> (x % 8));
} else {
buffer[(x + y * w) / 8] |= 0x80 >> (x % 8);
framebuffer[(x + y * w) / 8] |= 0x80 >> (x % 8);
}
}
}
void uDisplay::drawPixel_EPD(int16_t x, int16_t y, uint16_t color) {
if (!buffer) return;
if (!framebuffer) return;
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;

4
lib/lib_display/UDisplay/uDisplay.h Normal file → Executable file
View File

@ -72,6 +72,7 @@ enum uColorType { uCOLOR_BW, uCOLOR_COLOR };
class uDisplay : public Renderer {
public:
uDisplay(char *);
~uDisplay(void);
Renderer *Init(void);
void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font);
void Updateframe();
@ -80,6 +81,7 @@ class uDisplay : public Renderer {
char *devname(void);
uint16_t fgcol(void) const { return fg_col; };
uint16_t bgcol(void) const { return bg_col; };
int8_t color_type(void) const { return col_type; };
void dim(uint8_t dim);
uint16_t GetColorFromIndex(uint8_t index);
void setRotation(uint8_t m);
@ -137,10 +139,12 @@ class uDisplay : public Renderer {
void setAddrWindow_int(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
char dname[16];
int8_t bpp;
uint8_t col_type;
uint8_t interface;
uint8_t i2caddr;
int8_t i2c_scl;
TwoWire *wire;
int8_t wire_n;
int8_t i2c_sda;
uint8_t i2c_col_start;
uint8_t i2c_col_end;

View File

@ -31,6 +31,11 @@ enum ColorType { COLOR_BW, COLOR_COLOR };
#define MAX_TOUCH_BUTTONS 16
#endif
#ifdef USE_UFILESYS
extern FS *ufsp;
extern FS *ffsp;
#endif
#ifdef USE_TOUCH_BUTTONS
VButton *buttons[MAX_TOUCH_BUTTONS];
#endif
@ -41,6 +46,45 @@ uint16_t fg_color = 1;
uint16_t bg_color = 0;
uint8_t color_type = COLOR_BW;
uint8_t auto_draw = 1;
int16_t disp_xpos = 0;
int16_t disp_ypos = 0;
#ifdef USE_MULTI_DISPLAY
struct MULTI_DISP {
Renderer *display;
uint16_t fg_color;
uint16_t bg_color;
int16_t disp_xpos;
int16_t disp_ypos;
uint8_t color_type;
uint8_t auto_draw;
} displays[3];
uint8_t cur_display;
Renderer *Init_uDisplay(const char *desc);
void Set_display(uint8_t index) {
displays[index].display = renderer;
displays[index].fg_color = fg_color;
displays[index].bg_color = bg_color;
displays[index].color_type = color_type;
displays[index].auto_draw = auto_draw;
displays[index].disp_xpos = disp_xpos;
displays[index].disp_ypos = disp_ypos;
cur_display = index;
}
void Get_display(uint8_t index) {
renderer = displays[index].display;
fg_color = displays[index].fg_color;
bg_color = displays[index].bg_color;
color_type = displays[index].color_type;
auto_draw = displays[index].auto_draw;
disp_xpos = displays[index].disp_xpos;
disp_ypos = displays[index].disp_ypos;
if (renderer) renderer->setDrawMode(auto_draw >> 1);
cur_display = index;
}
#endif // USE_MULTI_DISPLAY
const uint8_t DISPLAY_MAX_DRIVERS = 32; // Max number of display drivers/models supported by xdsp_interface.ino
const uint8_t DISPLAY_MAX_COLS = 64; // Max number of columns allowed with command DisplayCols
@ -175,8 +219,6 @@ uint16_t dsp_y2;
uint16_t dsp_rad;
uint16_t dsp_color;
int16_t dsp_len;
int16_t disp_xpos = 0;
int16_t disp_ypos = 0;
uint8_t disp_power = 0;
uint8_t disp_device = 0;
@ -512,6 +554,49 @@ void DisplayText(void)
}
}
break;
#ifdef USE_MULTI_DISPLAY
case 'S':
{
var = atoiv(cp, &temp);
cp += var;
if (temp < 1 || temp > 3) {
temp = 1;
}
temp--;
if (*cp == ':') {
cp++;
if (displays[temp].display) {
Set_display(cur_display);
Get_display(temp);
}
} else {
char *ep=strchr(cp,':');
if (ep) {
*ep=0;
ep++;
File fp;
if (ffsp) {
AddLog(LOG_LEVEL_INFO, PSTR("DSP: File: %s"),cp);
fp = ffsp->open(cp, "r");
if (fp > 0) {
uint32_t size = fp.size();
char *fdesc = (char *)calloc(size + 4, 1);
if (fdesc) {
fp.read((uint8_t*)fdesc, size);
fp.close();
Get_display(temp);
renderer = Init_uDisplay(fdesc);
Set_display(temp);
AddLog(LOG_LEVEL_INFO, PSTR("DSP: File descriptor loaded %x"),renderer);
}
}
}
}
cp = ep;
}
}
break;
#endif // USE_MULTI_DISPLAY
#endif // USE_UFILESYS
case 'h':
// hor line to
@ -736,7 +821,7 @@ extern FS *ffsp;
{ char *ep = strchr(cp,':');
if (ep) {
static uint8_t *ram_font;
char fname[24];
char fname[32];
*ep = 0;
ep++;
if (*cp != '/') {
@ -1024,7 +1109,6 @@ extern FS *ffsp;
}
#ifdef USE_UFILESYS
extern FS *ufsp;
void Display_Text_From_File(const char *file) {
File fp;
if (!ufsp) return;
@ -1188,7 +1272,7 @@ void draw_dt_vars(void) {
// restore display vars
renderer->setTextColor(fg_color, bg_color);
renderer->setDrawMode(auto_draw);
renderer->setDrawMode(auto_draw>>1);
}
}
}
@ -1657,6 +1741,10 @@ void DisplayInitDriver(void)
{
XdspCall(FUNC_DISPLAY_INIT_DRIVER);
#ifdef USE_MULTI_DISPLAY
Set_display(0);
#endif // USE_MULTI_DISPLAY
if (renderer) {
renderer->setTextFont(Settings.display_font);
renderer->setTextSize(Settings.display_size);
@ -2043,6 +2131,9 @@ void CmndDisplayScrollText(void) {
void DisplayReInitDriver(void) {
XdspCall(FUNC_DISPLAY_INIT_DRIVER);
#ifdef USE_MULTI_DISPLAY
Set_display(0);
#endif // USE_MULTI_DISPLAY
ResponseCmndDone();
}
@ -2578,70 +2669,84 @@ void AddValue(uint8_t num,float fval) {
\*********************************************************************************************/
#if defined(USE_FT5206) || defined(USE_XPT2046)
bool FT5206_found = false;
bool XPT2046_found = false;
int16_t touch_xp;
int16_t touch_yp;
bool touched;
#ifdef USE_M5STACK_CORE2
uint8_t tbstate[3];
#endif // USE_M5STACK_CORE2
#ifdef USE_FT5206
#include <FT5206.h>
// touch panel controller
#undef FT5206_address
#define FT5206_address 0x38
FT5206_Class *touchp;
TP_Point pLoc;
bool FT5206_found;
FT5206_Class *FT5206_touchp;
bool Touch_Init(TwoWire &i2c) {
bool FT5206_Touch_Init(TwoWire &i2c) {
FT5206_found = false;
touchp = new FT5206_Class();
if (touchp->begin(i2c, FT5206_address)) {
FT5206_touchp = new FT5206_Class();
if (FT5206_touchp->begin(i2c, FT5206_address)) {
I2cSetActiveFound(FT5206_address, "FT5206");
FT5206_found = true;
}
return FT5206_found;
}
uint32_t Touch_Status(uint32_t sel) {
if (FT5206_found) {
switch (sel) {
case 0:
return touchp->touched();
case 1:
bool FT5206_touched() {
return FT5206_touchp->touched();
}
int16_t FT5206_x() {
TP_Point pLoc = FT5206_touchp->getPoint(0);
return pLoc.x;
case 2:
}
int16_t FT5206_y() {
TP_Point pLoc = FT5206_touchp->getPoint(0);
return pLoc.y;
}
return 0;
} else {
return 0;
}
}
#endif // USE_FT5206
#if defined(USE_XPT2046) && defined(USE_DISPLAY_ILI9341)
#ifdef USE_XPT2046
#include <XPT2046_Touchscreen.h>
XPT2046_Touchscreen *XPT2046_touchp;
XPT2046_Touchscreen *touchp;
TS_Point pLoc;
bool XPT2046_found;
bool Touch_Init(uint16_t CS) {
touchp = new XPT2046_Touchscreen(CS);
XPT2046_found = touchp->begin();
bool XPT2046_Touch_Init(uint16_t CS) {
XPT2046_touchp = new XPT2046_Touchscreen(CS);
XPT2046_found = XPT2046_touchp->begin();
if (XPT2046_found) {
AddLog(LOG_LEVEL_INFO, PSTR("TS: XPT2046"));
}
return XPT2046_found;
}
bool XPT2046_touched() {
return XPT2046_touchp->touched();
}
int16_t XPT2046_x() {
TS_Point pLoc = XPT2046_touchp->getPoint();
return pLoc.x;
}
int16_t XPT2046_y() {
TS_Point pLoc = XPT2046_touchp->getPoint();
return pLoc.y;
}
#endif // USE_XPT2046
uint32_t Touch_Status(uint32_t sel) {
if (XPT2046_found) {
if (FT5206_found || XPT2046_found) {
switch (sel) {
case 0:
return touchp->touched();
return touched;
case 1:
return pLoc.x;
return touch_xp;
case 2:
return pLoc.y;
return touch_yp;
}
return 0;
} else {
@ -2649,51 +2754,34 @@ uint32_t Touch_Status(uint32_t sel) {
}
}
#endif // USE_XPT2046 && USE_DISPLAY_ILI9341
void Touch_Check(void(*rotconvert)(int16_t *x, int16_t *y)) {
#ifdef USE_FT5206
if (FT5206_found) {
touch_xp = FT5206_x();
touch_yp = FT5206_y();
touched = FT5206_touched();
}
#endif // USE_FT5206
#ifdef USE_XPT2046
if (XPT2046_found) {
touch_xp = XPT2046_x();
touch_yp = XPT2046_y();
touched = XPT2046_touched();
}
#endif // USE_XPT2046
if (touched) {
#ifdef USE_TOUCH_BUTTONS
void Touch_MQTT(uint8_t index, const char *cp, uint32_t val) {
#if defined(USE_FT5206)
ResponseTime_P(PSTR(",\"FT5206\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
#elif defined(USE_XPT2046)
ResponseTime_P(PSTR(",\"XPT2046\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
#endif // USE_XPT2046
MqttPublishTeleSensor();
}
void Touch_RDW_BUTT(uint32_t count, uint32_t pwr) {
buttons[count]->xdrawButton(pwr);
if (pwr) buttons[count]->vpower.on_off = 1;
else buttons[count]->vpower.on_off = 0;
}
#ifdef USE_M5STACK_CORE2
uint8_t tbstate[3];
#endif
// check digitizer hit
void Touch_Check(void(*rotconvert)(int16_t *x, int16_t *y)) {
uint16_t temp;
uint8_t rbutt=0;
uint8_t vbutt=0;
if (touchp->touched()) {
// did find a hit
#if defined(USE_FT5206)
pLoc = touchp->getPoint(0);
#elif defined(USE_XPT2046)
pLoc = touchp->getPoint();
#endif // USE_XPT2046
if (renderer) {
#ifdef USE_M5STACK_CORE2
// handle 3 built in touch buttons
uint16_t xcenter = 80;
#define TDELTA 30
#define TYPOS 275
for (uint32_t tbut = 0; tbut < 3; tbut++) {
if (pLoc.x>(xcenter-TDELTA) && pLoc.x<(xcenter+TDELTA) && pLoc.y>(TYPOS-TDELTA) && pLoc.y<(TYPOS+TDELTA)) {
if (touch_xp > (xcenter - TDELTA) && touch_xp < (xcenter + TDELTA) && touch_yp > (TYPOS - TDELTA) && touch_yp < (TYPOS + TDELTA)) {
// hit a button
if (!(tbstate[tbut] & 1)) {
// pressed
@ -2705,16 +2793,67 @@ void Touch_Check(void(*rotconvert)(int16_t *x, int16_t *y)) {
xcenter += 100;
}
#endif // USE_M5STACK_CORE2
#endif // USE_TOUCH_BUTTONS
rotconvert(&pLoc.x, &pLoc.y);
rotconvert(&touch_xp, &touch_yp);
#ifdef USE_TOUCH_BUTTONS
CheckTouchButtons(touched, touch_xp, touch_yp);
#endif // USE_TOUCH_BUTTONS
} else {
#ifdef USE_M5STACK_CORE2
for (uint32_t tbut = 0; tbut < 3; tbut++) {
if (tbstate[tbut] & 1) {
// released
tbstate[tbut] &= 0xfe;
Touch_MQTT(tbut, "BIB", tbstate[tbut] & 1);
//AddLog(LOG_LEVEL_INFO, PSTR("tbut: %d released"), tbut);
}
}
#endif // USE_M5STACK_CORE2
#ifdef USE_TOUCH_BUTTONS
CheckTouchButtons(touched, touch_xp, touch_yp);
#endif // USE_TOUCH_BUTTONS
}
}
#endif
#ifdef USE_TOUCH_BUTTONS
void Touch_MQTT(uint8_t index, const char *cp, uint32_t val) {
#ifdef USE_FT5206
if (FT5206_found) ResponseTime_P(PSTR(",\"FT5206\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
#endif
#ifdef USE_XPT2046
if (XPT2046_found) ResponseTime_P(PSTR(",\"XPT2046\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
#endif // USE_XPT2046
MqttPublishTeleSensor();
}
void Touch_RDW_BUTT(uint32_t count, uint32_t pwr) {
buttons[count]->xdrawButton(pwr);
if (pwr) buttons[count]->vpower.on_off = 1;
else buttons[count]->vpower.on_off = 0;
}
void CheckTouchButtons(bool touched, int16_t touch_x, int16_t touch_y) {
uint16_t temp;
uint8_t rbutt=0;
uint8_t vbutt=0;
if (!renderer) return;
if (touched) {
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("touch after convert %d - %d"), pLoc.x, pLoc.y);
// now must compare with defined buttons
for (uint8_t count = 0; count < MAX_TOUCH_BUTTONS; count++) {
if (buttons[count]) {
if (!buttons[count]->vpower.slider) {
if (!buttons[count]->vpower.disable) {
if (buttons[count]->contains(pLoc.x, pLoc.y)) {
if (buttons[count]->contains(touch_x, touch_y)) {
// did hit
buttons[count]->press(true);
if (buttons[count]->justPressed()) {
@ -2749,26 +2888,16 @@ void Touch_Check(void(*rotconvert)(int16_t *x, int16_t *y)) {
}
} else {
// slider
if (buttons[count]->didhit(pLoc.x, pLoc.y)) {
uint16_t value = buttons[count]->UpdateSlider(pLoc.x, pLoc.y);
if (buttons[count]->didhit(touch_x, touch_y)) {
uint16_t value = buttons[count]->UpdateSlider(touch_x, touch_y);
Touch_MQTT(count, "SLD", value);
}
}
}
}
}
} else {
// no hit
#ifdef USE_M5STACK_CORE2
for (uint32_t tbut = 0; tbut < 3; tbut++) {
if (tbstate[tbut] & 1) {
// released
tbstate[tbut] &= 0xfe;
Touch_MQTT(tbut, "BIB", tbstate[tbut] & 1);
//AddLog(LOG_LEVEL_INFO, PSTR("tbut: %d released"), tbut);
}
}
#endif // USE_M5STACK_CORE2
for (uint8_t count = 0; count < MAX_TOUCH_BUTTONS; count++) {
if (buttons[count]) {
if (!buttons[count]->vpower.slider) {
@ -2795,13 +2924,12 @@ void Touch_Check(void(*rotconvert)(int16_t *x, int16_t *y)) {
}
}
}
pLoc.x = 0;
pLoc.y = 0;
touch_xp = 0;
touch_yp = 0;
}
}
#endif // USE_TOUCH_BUTTONS
#endif // USE_FT5206 || USE_XPT2046
/*********************************************************************************************\
* Interface

View File

@ -71,11 +71,6 @@ void SSD1306InitDriver(void) {
Settings.display_height = 64;
}
// allocate screen buffer
if (buffer) { free(buffer); }
buffer = (unsigned char*)calloc((Settings.display_width * Settings.display_height) / 8,1);
if (!buffer) { return; }
// init renderer
// oled1306 = new Adafruit_SSD1306(SSD1306_LCDWIDTH,SSD1306_LCDHEIGHT);
oled1306 = new Adafruit_SSD1306(Settings.display_width, Settings.display_height, &Wire, Pin(GPIO_OLED_RESET));
@ -93,6 +88,7 @@ void SSD1306InitDriver(void) {
renderer->DisplayOnff(1);
#endif
AddLog(LOG_LEVEL_INFO, PSTR("DSP: SD1306"));
}
}

View File

@ -27,7 +27,6 @@ enum IliModes { ILIMODE_9341 = 1, ILIMODE_9342, ILIMODE_MAX };
#include <ILI9341_2.h>
extern uint8_t *buffer;
extern uint8_t color_type;
ILI9341_2 *ili9341_2;
@ -62,9 +61,6 @@ void ILI9341_InitDriver()
Settings.display_height = ILI9341_TFTHEIGHT;
}
// disable screen buffer
buffer = NULL;
if (!Settings.display_options.type || (Settings.display_options.type >= ILIMODE_MAX)) {
Settings.display_options.type = ILIMODE_9341;
}
@ -122,12 +118,12 @@ void ILI9341_InitDriver()
#undef SCL_2
#define SCL_2 22
Wire1.begin(SDA_2, SCL_2, 400000);
Touch_Init(Wire1);
FT5206_Touch_Init(Wire1);
#endif // USE_FT5206
#endif // ESP32
#ifdef USE_XPT2046
Touch_Init(Pin(GPIO_XPT2046_CS));
XPT2046_Touch_Init(Pin(GPIO_XPT2046_CS));
#endif
tft_init_done = true;
@ -154,8 +150,8 @@ void ili9342_dimm(uint8_t dim) {
#if defined(USE_FT5206) || defined(USE_XPT2046)
#ifdef USE_TOUCH_BUTTONS
#if defined(USE_FT5206)
void TS_RotConvert(int16_t *x, int16_t *y) {
#ifdef USE_FT5206
void FT5206_TS_RotConvert(int16_t *x, int16_t *y) {
int16_t temp;
if (renderer) {
@ -180,8 +176,10 @@ int16_t temp;
}
}
}
#elif defined(USE_XPT2046)
void TS_RotConvert(int16_t *x, int16_t *y) {
#endif // USE_FT5206
#ifdef USE_XPT2046
void XPT2046_TS_RotConvert(int16_t *x, int16_t *y) {
int16_t temp;
if (renderer) {
@ -219,7 +217,12 @@ ili9342_ctouch_counter++;
if (2 == ili9342_ctouch_counter) {
// every 100 ms should be enough
ili9342_ctouch_counter = 0;
Touch_Check(TS_RotConvert);
if (FT5206_found) {
Touch_Check(FT5206_TS_RotConvert);
}
if (XPT2046_found) {
Touch_Check(XPT2046_TS_RotConvert);
}
}
}
#endif // USE_TOUCH_BUTTONS

View File

@ -37,7 +37,6 @@
#include <epdpaint.h>
//unsigned char image[(EPD_HEIGHT * EPD_WIDTH) / 8];
extern uint8_t *buffer;
uint16_t epd_scroll;
bool epd_init_done = false;
@ -58,11 +57,6 @@ void EpdInitDriver29(void) {
Settings.display_height = EPD_HEIGHT;
}
// allocate screen buffer
if (buffer) free(buffer);
buffer=(unsigned char*)calloc((EPD_WIDTH * EPD_HEIGHT) / 8,1);
if (!buffer) return;
// init renderer
epd = new Epd(EPD_WIDTH, EPD_HEIGHT);
@ -75,6 +69,7 @@ void EpdInitDriver29(void) {
}
renderer = epd;
epd->Init(DISPLAY_INIT_FULL);
epd->Init(DISPLAY_INIT_PARTIAL);
renderer->DisplayInit(DISPLAY_INIT_MODE,Settings.display_size,Settings.display_rotate,Settings.display_font);

View File

@ -34,7 +34,6 @@
#include <epd4in2.h>
#include <epdpaint.h>
extern uint8_t *buffer;
bool epd42_init_done = false;
Epd42 *epd42;
@ -55,11 +54,6 @@ void EpdInitDriver42() {
Settings.display_height = EPD_HEIGHT42;
}
// allocate screen buffer
if (buffer) free(buffer);
buffer=(unsigned char*)calloc((EPD_WIDTH42 * EPD_HEIGHT42) / 8,1);
if (!buffer) return;
// init renderer
epd42 = new Epd42(EPD_WIDTH42, EPD_HEIGHT42);

View File

@ -25,7 +25,6 @@
#define SPRINT(A) char str[32];sprintf(str,"val: %d ",A);Serial.println((char*)str);
extern uint8_t *buffer;
#define XDSP_07 7
#define XI2C_06 6 // See I2CDEVICES.md
@ -71,12 +70,6 @@ void SH1106InitDriver() {
if (Settings.display_height != SH1106_LCDHEIGHT) {
Settings.display_height = SH1106_LCDHEIGHT;
}
// allocate screen buffer
if (buffer) free(buffer);
buffer=(unsigned char*)calloc((SH1106_LCDWIDTH * SH1106_LCDHEIGHT) / 8,1);
if (!buffer) return;
// init renderer
oled1106 = new Adafruit_SH1106(SH1106_LCDWIDTH,SH1106_LCDHEIGHT);
renderer = oled1106;
@ -93,6 +86,8 @@ void SH1106InitDriver() {
renderer->DisplayOnff(1);
#endif
}
AddLog(LOG_LEVEL_INFO, PSTR("DSP: SH1106"));
}

View File

@ -39,7 +39,6 @@ bool ili9488_init_done = false;
// currently fixed
#define BACKPLANE_PIN 2
extern uint8_t *buffer;
extern uint8_t color_type;
ILI9488 *ili9488;
extern const uint16_t picture[];
@ -58,9 +57,6 @@ void ILI9488_InitDriver(void) {
Settings.display_height = ILI9488_TFTHEIGHT;
}
// disable screen buffer
buffer = NULL;
// default colors
fg_color = ILI9488_WHITE;
bg_color = ILI9488_BLACK;
@ -91,7 +87,7 @@ void ILI9488_InitDriver(void) {
color_type = COLOR_COLOR;
// start digitizer
#ifdef USE_FT5206
Touch_Init(Wire);
FT5206_Touch_Init(Wire);
#endif
ili9488_init_done = true;

View File

@ -34,7 +34,6 @@
#include <SSD1351.h>
bool ssd1351_init_done = false;
extern uint8_t *buffer;
extern uint8_t color_type;
SSD1351 *ssd1351;
@ -53,8 +52,6 @@ void SSD1351_InitDriver() {
Settings.display_height = SSD1351_HEIGHT;
}
buffer = 0;
// default colors
fg_color = SSD1351_WHITE;
bg_color = SSD1351_BLACK;

View File

@ -35,7 +35,6 @@
bool ra8876_init_done = false;
uint8_t ra8876_ctouch_counter = 0;
extern uint8_t *buffer;
extern uint8_t color_type;
RA8876 *ra8876;
@ -52,8 +51,6 @@ void RA8876_InitDriver(void) {
Settings.display_height = RA8876_TFTHEIGHT;
}
buffer = 0;
// default colors
fg_color = RA8876_WHITE;
bg_color = RA8876_BLACK;
@ -78,7 +75,7 @@ void RA8876_InitDriver(void) {
color_type = COLOR_COLOR;
#ifdef USE_FT5206
Touch_Init(Wire);
FT5206_Touch_Init(Wire);
#endif
ra8876_init_done = true;

View File

@ -50,7 +50,6 @@
#define BACKPLANE_PIN 5
#endif // USE_LANBON_L8
extern uint8_t *buffer;
extern uint8_t color_type;
Arduino_ST7789 *st7789;
@ -74,9 +73,6 @@ void ST7789_InitDriver(void) {
Settings.display_height = 240;
}
// disable screen buffer
buffer = NULL;
// default colors
fg_color = ST7789_WHITE;
bg_color = ST7789_BLACK;
@ -112,6 +108,8 @@ void ST7789_InitDriver(void) {
#ifdef ESP32
#ifdef USE_FT5206
// start digitizer with fixed adress and pins for esp32
#undef SDA_2
#undef SCL_2
#define SDA_2 23
#define SCL_2 32
#ifdef USE_LANBON_L8
@ -121,7 +119,7 @@ void ST7789_InitDriver(void) {
#define SCL_2 0
#endif // USE_LANBON_L8
Wire1.begin(SDA_2, SCL_2, 400000);
Touch_Init(Wire1);
FT5206_Touch_Init(Wire1);
#endif // USE_FT5206
#endif // ESP32

View File

@ -25,7 +25,6 @@
#include <uDisplay.h>
uDisplay *udisp;
bool udisp_init_done = false;
uint8_t ctouch_counter;
extern uint8_t color_type;
@ -41,15 +40,12 @@ extern FS *ffsp;
//#define DSP_ROM_DESC
/*********************************************************************************************/
#ifdef DSP_ROM_DESC
//#ifdef DSP_ROM_DESC
#if 1
/* sample descriptor */
const char DSP_SAMPLE_DESC[] PROGMEM =
// name,xs,ys,bpp,interface, (HEX) address, scl,sda,reset
// '*' means take pin number from tasmota
":H,SH1106,128,64,1,I2C,3c,*,*,*\n"
// splash settings, font, size, fgcol, bgcol, x,y
":S,0,1,1,0,40,20\n"
// init register settings, must be in HEX
":I\n"
"AE\n"
"D5,80\n"
@ -67,9 +63,7 @@ const char DSP_SAMPLE_DESC[] PROGMEM =
"A4\n"
"A6\n"
"AF\n"
// switch display off
":o,AE\n"
// switch display on
":O,AF\n"
":A,00,10,40,00,02\n"
":i,A6,A7\n"
@ -77,21 +71,26 @@ const char DSP_SAMPLE_DESC[] PROGMEM =
#endif // DSP_ROM_DESC
/*********************************************************************************************/
void Init_uDisp(void) {
Renderer *Init_uDisplay(const char *desc) {
char *ddesc = 0;
char *fbuff;
uDisplay *udisp;
if (TasmotaGlobal.gpio_optiona.udisplay_driver) {
Settings.display_model = XDSP_17;
color_type = COLOR_BW;
fbuff = (char*)calloc(DISPDESC_SIZE, 1);
if (!fbuff) return;
if (!fbuff) return 0;
if (desc) {
memcpy(fbuff, desc, DISPDESC_SIZE - 1);
ddesc = fbuff;
AddLog(LOG_LEVEL_INFO, PSTR("DSP: const char descriptor used"));
}
#ifdef USE_UFILESYS
if (ffsp && !TasmotaGlobal.no_autoexec) {
if (ffsp && !TasmotaGlobal.no_autoexec && !ddesc) {
File fp;
fp = ffsp->open("/dispdesc.txt", "r");
if (fp > 0) {
@ -148,24 +147,44 @@ char *fbuff;
if (!ddesc) {
AddLog(LOG_LEVEL_INFO, PSTR("DSP: No valid descriptor found"));
if (fbuff) free(fbuff);
return;
return 0;
}
// now replace tasmota vars before passing to driver
char *cp = strstr(ddesc, "I2C,");
char *cp = strstr(ddesc, "I2C");
if (cp) {
cp += 4;
cp += 3;
uint8_t wire_n = 1;
if (*cp == '1' || *cp == '2') {
wire_n = *cp & 3;
cp += 2;
} else {
cp++;
}
//,3c,22,21,-1
uint8_t i2caddr = strtol(cp, &cp, 16);
int8_t scl, sda;
scl = replacepin(&cp, Pin(GPIO_I2C_SCL));
sda = replacepin(&cp, Pin(GPIO_I2C_SDA));
scl = replacepin(&cp, Pin(GPIO_I2C_SCL, wire_n - 1));
sda = replacepin(&cp, Pin(GPIO_I2C_SDA, wire_n - 1));
replacepin(&cp, Pin(GPIO_OLED_RESET));
if (wire_n == 1) {
Wire.begin(sda, scl);
}
#ifdef ESP32
if (wire_n == 2) {
Wire1.begin(sda, scl);
}
if (I2cSetDevice(i2caddr, wire_n - 1)) {
I2cSetActiveFound(i2caddr, "DSP-I2C", wire_n - 1);
}
#endif // ESP32
#ifdef ESP8266
if (I2cSetDevice(i2caddr)) {
I2cSetActiveFound(i2caddr, "DSP-I2C");
}
#endif // ESP8266
//AddLog(LOG_LEVEL_INFO, PSTR("DSP: i2c %x, %d, %d, %d!"), i2caddr, wire_n, scl, sda);
}
cp = strstr(ddesc, "SPI,");
@ -212,7 +231,10 @@ char *fbuff;
*/
// init renderer
if (udisp) delete udisp;
if (renderer) {
delete renderer;
AddLog(LOG_LEVEL_INFO, PSTR("DSP: reinit"));
}
udisp = new uDisplay(ddesc);
// checck for touch option TI1 or TI2
@ -226,29 +248,33 @@ char *fbuff;
uint8_t i2caddr = strtol(cp, &cp, 16);
int8_t scl, sda;
scl = replacepin(&cp, Pin(GPIO_I2C_SCL, wire_n));
sda = replacepin(&cp, Pin(GPIO_I2C_SDA, wire_n));
if (wire_n == 0) {
scl = replacepin(&cp, Pin(GPIO_I2C_SCL));
sda = replacepin(&cp, Pin(GPIO_I2C_SDA));
Wire.begin(sda, scl);
}
#ifdef ESP32
if (wire_n == 1) {
scl = replacepin(&cp, Pin(GPIO_I2C_SCL, 1));
sda = replacepin(&cp, Pin(GPIO_I2C_SDA, 1));
Wire1.begin(sda, scl, 400000);
}
#endif
//AddLog(LOG_LEVEL_INFO, PSTR("DSP: touch %x, %d, %d, %d!"), i2caddr, wire_n, scl, sda);
if (I2cSetDevice(i2caddr, wire_n)) {
I2cSetActiveFound(i2caddr, "FT5206", wire_n);
}
#endif // ESP32
#ifdef ESP8266
//AddLog(LOG_LEVEL_INFO, PSTR("DSP: touch %x, %d, %d, %d!"), i2caddr, wire_n, scl, sda);
if (I2cSetDevice(i2caddr)) {
I2cSetActiveFound(i2caddr, "FT5206");
}
#endif // ESP8266
// start digitizer
#ifdef ESP32
if (!wire_n) Touch_Init(Wire);
else Touch_Init(Wire1);
if (!wire_n) FT5206_Touch_Init(Wire);
else FT5206_Touch_Init(Wire1);
#else
if (!wire_n) Touch_Init(Wire);
if (!wire_n) FT5206_Touch_Init(Wire);
#endif
}
#endif
@ -258,7 +284,7 @@ char *fbuff;
if (cp) {
cp+=4;
uint8_t touch_cs = replacepin(&cp, Pin(GPIO_XPT2046_CS));
Touch_Init(touch_cs);
XPT2046_Touch_Init(touch_cs);
}
#endif
@ -266,12 +292,13 @@ char *fbuff;
if (fbuff) free(fbuff);
renderer = udisp->Init();
if (!renderer) return;
if (!renderer) return 0;
Settings.display_width = renderer->width();
Settings.display_height = renderer->height();
fg_color = udisp->fgcol();
bg_color = udisp->bgcol();
color_type = udisp->color_type();
renderer->DisplayInit(DISPLAY_INIT_MODE, Settings.display_size, Settings.display_rotate, Settings.display_font);
renderer->dim(Settings.display_dimmer);
@ -282,10 +309,11 @@ char *fbuff;
udisp_init_done = true;
AddLog(LOG_LEVEL_INFO, PSTR("DSP: %s!"), udisp->devname());
return renderer;
}
return 0;
}
/*********************************************************************************************/
@ -305,7 +333,7 @@ void udisp_dimm(uint8_t dim) {
}
void TS_RotConvert(int16_t *x, int16_t *y) {
if (udisp) udisp->TS_RotConvert(x, y);
if (renderer) renderer->TS_RotConvert(x, y);
}
#if defined(USE_FT5206) || defined(USE_XPT2046)
@ -415,7 +443,7 @@ bool Xdsp17(uint8_t function)
bool result = false;
if (FUNC_DISPLAY_INIT_DRIVER == function) {
Init_uDisp();
Init_uDisplay(0);
}
else if (udisp_init_done && (XDSP_17 == Settings.display_model)) {
switch (function) {
@ -430,17 +458,11 @@ bool Xdsp17(uint8_t function)
#endif // USE_DISPLAY_MODES1TO5
#if defined(USE_FT5206) || defined(USE_XPT2046)
#ifdef USE_TOUCH_BUTTONS
case FUNC_DISPLAY_EVERY_50_MSECOND:
#if defined(USE_FT5206)
if (FT5206_found) {
#elif defined(USE_XPT2046)
if (XPT2046_found) {
#endif
if (FT5206_found || XPT2046_found) {
udisp_CheckTouch();
}
break;
#endif // USE_TOUCH_BUTTONS
#endif // USE_FT5206
}