From 16e397dbd74ee1007ee2b91781f1d5b71ee90307 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 11 Apr 2021 12:30:50 +0200 Subject: [PATCH] udisplay lib --- .../Adafruit_GFX.cpp | 10 + .../Adafruit_GFX.h | 4 + lib/lib_display/UDisplay/keywords.txt | 30 + lib/lib_display/UDisplay/library.properties | 9 + lib/lib_display/UDisplay/uDisplay.cpp | 607 ++++++++++++++++++ lib/lib_display/UDisplay/uDisplay.h | 114 ++++ 6 files changed, 774 insertions(+) create mode 100644 lib/lib_display/UDisplay/keywords.txt create mode 100644 lib/lib_display/UDisplay/library.properties create mode 100644 lib/lib_display/UDisplay/uDisplay.cpp create mode 100644 lib/lib_display/UDisplay/uDisplay.h diff --git a/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.cpp b/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.cpp index dbfd00e2d..5e88150cc 100644 --- a/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.cpp +++ b/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.cpp @@ -1243,6 +1243,16 @@ void Adafruit_GFX::setTextSize(uint8_t s_x, uint8_t s_y) { textsize_y = (s_y > 0) ? s_y : 1; } +void Adafruit_GFX::setwidth(uint16_t w) { + WIDTH = w; + _width = w; +} + +void Adafruit_GFX::setheight(uint16_t h) { + HEIGHT = h; + _height = h; +} + /**************************************************************************/ /*! @brief Set rotation setting for display diff --git a/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.h b/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.h index dc970b26d..8af31324e 100644 --- a/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.h +++ b/lib/lib_display/Adafruit-GFX-Library-1.5.6-gemu-1.0/Adafruit_GFX.h @@ -187,6 +187,10 @@ virtual void /************************************************************************/ int16_t height(void) const { return _height; } + void setwidth(uint16_t w); + + void setheight(uint16_t h); + /************************************************************************/ /*! @brief Get rotation setting for display diff --git a/lib/lib_display/UDisplay/keywords.txt b/lib/lib_display/UDisplay/keywords.txt new file mode 100644 index 000000000..bb1efcdcc --- /dev/null +++ b/lib/lib_display/UDisplay/keywords.txt @@ -0,0 +1,30 @@ +####################################### +# Syntax Coloring Map +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +ST7789 KEYWORD1 + + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +setRotation KEYWORD2 +setAddrWindow KEYWORD2 +pushColor KEYWORD2 +drawPixel KEYWORD2 +drawFastVLine KEYWORD2 +drawFastHLine KEYWORD2 +fillRect KEYWORD2 +setRotation KEYWORD2 +setRotation KEYWORD2 +height KEYWORD2 +width KEYWORD2 +invertDisplay KEYWORD2 +drawImage KEYWORD2 +setScrollArea KEYWORD2 +scroll KEYWORD2 diff --git a/lib/lib_display/UDisplay/library.properties b/lib/lib_display/UDisplay/library.properties new file mode 100644 index 000000000..c7dd23a3a --- /dev/null +++ b/lib/lib_display/UDisplay/library.properties @@ -0,0 +1,9 @@ +name=universal display Library +version=0.1 +author=Gerhard Mutz +maintainer=Gerhard Mutz +sentence=This is a library a couple of displays. +paragraph=This is a library a couple of displays. +category=Display +url=https://github.com/arendst/Tasmota +architectures=* diff --git a/lib/lib_display/UDisplay/uDisplay.cpp b/lib/lib_display/UDisplay/uDisplay.cpp new file mode 100644 index 000000000..0c15c8712 --- /dev/null +++ b/lib/lib_display/UDisplay/uDisplay.cpp @@ -0,0 +1,607 @@ +/* + uDisplay.cpp - universal display driver support for Tasmota + + Copyright (C) 2021 Gerhard Mutz and Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include "uDisplay.h" + + +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,\ +UDISP_LIGHTGREY,UDISP_DARKGREY,UDISP_ORANGE,UDISP_GREENYELLOW,UDISP_PINK}; + +uint16_t uDisplay::GetColorFromIndex(uint8_t index) { + if (index >= sizeof(udisp_colors) / 2) index = 0; + return udisp_colors[index]; +} + +extern uint8_t *buffer; + +uDisplay::uDisplay(char *lp) : Renderer(800, 600) { + // analyse decriptor + uint8_t section = 0; + dsp_ncmds = 0; + char linebuff[128]; + while (*lp) { + + uint16_t llen = strlen_ln(lp); + strncpy(linebuff, lp, llen); + linebuff[llen] = 0; + lp += llen; + char *lp1 = linebuff; + + if (*lp1 == '#') break; + if (*lp1 == '\n') lp1++; + while (*lp1 == ' ') lp1++; + //Serial.printf(">> %s\n",lp1); + if (*lp1 != ';') { + // check ids: + if (*lp1 == ':') { + // id line + lp1++; + section = *lp1++; + } else { + switch (section) { + case 'H': + // header line + // SD1306,128,64,1,I2C,5a,*,*,* + str2c(&lp1, dname, sizeof(dname)); + char ibuff[16]; + gxs = next_val(&lp1); + setwidth(gxs); + gys = next_val(&lp1); + setheight(gys); + bpp = next_val(&lp1); + str2c(&lp1, ibuff, sizeof(ibuff)); + if (!strncmp(ibuff, "I2C", 3)) { + interface = _UDSP_I2C; + i2caddr = next_hex(&lp1); + i2c_scl = next_val(&lp1); + i2c_sda = next_val(&lp1); + reset = next_val(&lp1); + section = 0; + } else if (!strncmp(ibuff, "SPI", 3)) { + interface = _UDSP_SPI; + spi_nr = next_val(&lp1); + spi_cs = next_val(&lp1); + spi_clk = next_val(&lp1); + spi_mosi = next_val(&lp1); + spi_dc = next_val(&lp1); + bpanel = next_val(&lp1); + reset = next_val(&lp1); + spi_miso = next_val(&lp1); + spi_speed = next_val(&lp1); + + section = 0; + Serial.printf("%d %d %d %d %d %d %d %d\n", spi_cs, spi_clk, spi_mosi, spi_dc, bpanel, reset, spi_miso, spi_speed); + } + break; + case 'S': + splash_font = next_val(&lp1); + splash_size = next_val(&lp1); + fg_col = next_val(&lp1); + if (bpp == 16) { + fg_col = GetColorFromIndex(fg_col); + } + bg_col = next_val(&lp1); + if (bpp == 16) { + bg_col = GetColorFromIndex(bg_col); + } + splash_xp = next_val(&lp1); + splash_yp = next_val(&lp1); + break; + case 'I': + // init data + if (interface == _UDSP_I2C) { + dsp_cmds[dsp_ncmds++] = next_hex(&lp1); + if (!str2c(&lp1, ibuff, sizeof(ibuff))) { + dsp_cmds[dsp_ncmds++] = strtol(ibuff, 0, 16); + } + } else { + while (1) { + if (!str2c(&lp1, ibuff, sizeof(ibuff))) { + dsp_cmds[dsp_ncmds++] = strtol(ibuff, 0, 16); + } else { + break; + } + if (dsp_ncmds >= sizeof(dsp_cmds)) break; + + } + } + break; + case 'o': + str2c(&lp1, ibuff, sizeof(ibuff)); + dsp_off = strtol(ibuff, 0, 16); + break; + case 'O': + str2c(&lp1, ibuff, sizeof(ibuff)); + dsp_on = strtol(ibuff, 0, 16); + break; + case '0': + rot_0 = next_hex(&lp1); + break; + case '1': + rot_1 = next_hex(&lp1); + break; + case '2': + rot_2 = next_hex(&lp1); + break; + case '3': + rot_3 = next_hex(&lp1); + break; + case 'A': + saw_1 = next_hex(&lp1); + saw_2 = next_hex(&lp1); + saw_3 = next_hex(&lp1); + break; + } + } + } + if (*lp == '\n') { + lp++; + } else { + lp = strchr(lp, '\n'); + if (!lp) break; + lp++; + } + } +} + + +Renderer *uDisplay::Init(void) { + + + if (reset >= 0) { + pinMode(reset, OUTPUT); + digitalWrite(reset, HIGH); + delay(50); + digitalWrite(reset, LOW); + delay(50); + digitalWrite(reset, HIGH); + delay(200); + } + + if (interface == _UDSP_I2C) { + Wire.begin(i2c_sda, i2c_scl); + if (bpp < 16) { + if (buffer) free(buffer); + buffer = (uint8_t*)calloc((width()*height()*bpp)/8, 1); + + for (uint32_t cnt = 0; cnt < dsp_ncmds; cnt++) { + i2c_command(dsp_cmds[cnt]); + } + } + } + if (interface == _UDSP_SPI) { + if (bpanel >= 0) { +#ifdef ESP32 + ledcSetup(ESP32_PWM_CHANNEL, 4000, 8); + ledcAttachPin(bpanel, ESP32_PWM_CHANNEL); + ledcWrite(ESP32_PWM_CHANNEL, 128); +#else + pinMode(bpanel, OUTPUT); + digitalWrite(bpanel, HIGH); +#endif // ESP32 + } + if (spi_dc >= 0) { + pinMode(spi_dc, OUTPUT); + digitalWrite(spi_dc, HIGH); + } + if (spi_cs >= 0) { + pinMode(spi_cs, OUTPUT); + digitalWrite(spi_cs, HIGH); + } + + spiSettings = SPISettings(spi_speed, MSBFIRST, SPI_MODE3); + +#ifdef ESP8266 + SPI.begin(); + uspi = &SPI; +#else + if (spi_nr != 1) { + uspi = new SPIClass(HSPI); + } else { + uspi = &SPI; + } + uspi->begin(spi_clk, spi_miso, spi_mosi, -1); +#endif + + uint16_t index = 0; + + SPI_BEGIN_TRANSACTION + while (1) { + uint8_t iob; + SPI_CS_LOW + SPI_DC_LOW + iob = dsp_cmds[index++]; + uspi->write(iob); + SPI_DC_HIGH + uint8_t args = dsp_cmds[index++]; + //Serial.printf("cmd, args %x, %d ", iob, args&0x7f); + for (uint32_t cnt = 0; cnt < (args & 0x7f); cnt++) { + iob = dsp_cmds[index++]; + //Serial.printf("%02x ", iob ); + uspi->write(iob); + } + SPI_CS_HIGH + //Serial.printf("\n"); + if (args & 0x80) delay(120); + if (index >= dsp_ncmds) break; + } + SPI_END_TRANSACTION + + } + return this; +} + +void uDisplay::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { + setRotation(rot); + invertDisplay(false); + setTextWrap(false); + cp437(true); + setTextFont(font); + setTextSize(size); + setTextColor(fg_col, bg_col); + setCursor(0,0); + fillScreen(bg_col); + Updateframe(); +} + +void uDisplay::spi_command(uint8_t val) { + SPI_BEGIN_TRANSACTION + SPI_DC_LOW + SPI_CS_LOW + uspi->write(val); + SPI_CS_HIGH + SPI_DC_HIGH + SPI_END_TRANSACTION +} + +void uDisplay::i2c_command(uint8_t val) { + //Serial.printf("%02x\n",val ); + Wire.beginTransmission(i2caddr); + Wire.write(0); + Wire.write(val); + Wire.endTransmission(); +} + +#define SH1106_SETLOWCOLUMN 0 +#define SH1106_SETHIGHCOLUMN 0x10 +#define SH1106_SETSTARTLINE 0x40 + + +void uDisplay::Updateframe(void) { + + if (interface == _UDSP_I2C) { + i2c_command(SH1106_SETLOWCOLUMN | 0x0); // low col = 0 + i2c_command(SH1106_SETHIGHCOLUMN | 0x0); // hi col = 0 + i2c_command(SH1106_SETSTARTLINE | 0x0); // line #0 + + uint8_t ys = gys >> 3; + uint8_t xs = gxs >> 3; + //uint8_t xs = 132 >> 3; + uint8_t m_row = 0; + uint8_t m_col = 2; + + uint16_t p = 0; + + uint8_t i, j, k = 0; + + for ( i = 0; i < ys; i++) { + // send a bunch of data in one xmission + i2c_command(0xB0 + i + m_row);//set page address + i2c_command(m_col & 0xf);//set lower column address + i2c_command(0x10 | (m_col >> 4));//set higher column address + + for( j = 0; j < 8; j++){ + Wire.beginTransmission(i2caddr); + Wire.write(0x40); + for ( k = 0; k < xs; k++, p++) { + Wire.write(buffer[p]); + } + Wire.endTransmission(); + } + } + } +} + +void uDisplay::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { + + if (interface != _UDSP_SPI) { + Renderer::drawFastVLine(x, y, h, color); + return; + } + // Rudimentary clipping + if ((x >= _width) || (y >= _height)) return; + if ((y + h - 1) >= _height) h = _height - y; + + SPI_BEGIN_TRANSACTION + + SPI_CS_LOW + + setAddrWindow_int(x, y, 1, h); + + while (h--) { + uspi->write16(color); + } + + SPI_CS_HIGH + + SPI_END_TRANSACTION +} + +void uDisplay::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { + + if (interface != _UDSP_SPI) { + Renderer::drawFastHLine(x, y, w, color); + return; + } + + // Rudimentary clipping + if((x >= _width) || (y >= _height)) return; + if((x+w-1) >= _width) w = _width-x; + + + SPI_BEGIN_TRANSACTION + + SPI_CS_LOW + + setAddrWindow_int(x, y, w, 1); + + + while (w--) { + uspi->write16(color); + } + + SPI_CS_HIGH + + SPI_END_TRANSACTION +} + +void uDisplay::fillScreen(uint16_t color) { + fillRect(0, 0, gxs, gys, color); +} + +// fill a rectangle +void uDisplay::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { + + if (interface != _UDSP_SPI) { + Renderer::fillRect(x, y, w, h, color); + return; + } + + // rudimentary clipping (drawChar w/big text requires this) + if((x >= gxs) || (y >= gys)) return; + if((x + w - 1) >= gxs) w = gxs - x; + if((y + h - 1) >= gys) h = gys - y; + + + SPI_BEGIN_TRANSACTION + SPI_CS_LOW + + setAddrWindow_int(x, y, w, h); + + for (y = h; y > 0; y--) { + for (x = w; x > 0; x--) { + uspi->write16(color); + } + } + SPI_CS_HIGH + SPI_END_TRANSACTION +} + + +void uDisplay::Splash(void) { + setTextFont(splash_font); + setTextSize(splash_size); + DrawStringAt(splash_xp, splash_yp, dname, fg_col, 0); + Updateframe(); +} + +void uDisplay::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { + + if (!x0 && !y0 && !x1 && !y1) { + SPI_CS_HIGH + SPI_END_TRANSACTION + } else { + SPI_CS_LOW + SPI_BEGIN_TRANSACTION + setAddrWindow_int(x0, y0, x1 - x0, y1 - y0 ); + } +} + +void uDisplay::setAddrWindow_int(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { + uint32_t xa = ((uint32_t)x << 16) | (x+w-1); + uint32_t ya = ((uint32_t)y << 16) | (y+h-1); + + SPI_DC_LOW + uspi->write(saw_1); + SPI_DC_HIGH + + uspi->write32(xa); + + SPI_DC_LOW + uspi->write(saw_2); + SPI_DC_HIGH + + uspi->write32(ya); + + SPI_DC_LOW + uspi->write(saw_3); // write to RAM + SPI_DC_HIGH + +} + +void uDisplay::pushColors(uint16_t *data, uint16_t len, boolean first) { + uint16_t color; + + while (len--) { + color = *data++; + uspi->write16(color); + } + +} + +void uDisplay::drawPixel(int16_t x, int16_t y, uint16_t color) { + + if (interface != _UDSP_SPI) { + Renderer::drawPixel(x, y, color); + return; + } + + if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; + + + SPI_BEGIN_TRANSACTION + + SPI_CS_LOW + + setAddrWindow_int(x, y, 1, 1); + + uspi->write16(color); + + SPI_CS_HIGH + + SPI_END_TRANSACTION +} + +void uDisplay::setRotation(uint8_t m) { + if (interface != _UDSP_SPI) { + Renderer::setRotation(m); + return; + } + switch (rotation) { + case 0: + if (interface == _UDSP_SPI) spi_command(rot_0); + _width = gxs; + _height = gys; + break; + case 1: + if (interface == _UDSP_SPI) spi_command(rot_1); + _width = gys; + _height = gxs; + break; + case 2: + if (interface == _UDSP_SPI) spi_command(rot_2); + _width = gxs; + _height = gys; + break; + case 3: + if (interface == _UDSP_SPI) spi_command(rot_3); + _width = gys; + _height = gxs; + break; + } +} + +void uDisplay::DisplayOnff(int8_t on) { + + if (interface == _UDSP_I2C) { + if (on) { + i2c_command(dsp_on); + } else { + i2c_command(dsp_off); + } + } else { + if (on) { + spi_command(dsp_on); + if (bpanel >= 0) { +#ifdef ESP32 + ledcWrite(ESP32_PWM_CHANNEL, dimmer); +#else + digitalWrite(bpanel, HIGH); +#endif + } + + } else { + spi_command(dsp_off); + if (bpanel >= 0) { +#ifdef ESP32 + ledcWrite(ESP32_PWM_CHANNEL, 0); +#else + digitalWrite(bpanel, LOW); +#endif + } + } + } +} + +void uDisplay::dim(uint8_t dim) { + dimmer = dim; + if (dimmer > 15) dimmer = 15; + dimmer = ((float)dimmer / 15.0) * 255.0; +#ifdef ESP32 + ledcWrite(ESP32_PWM_CHANNEL, dimmer); +#endif +} + + + +uint8_t uDisplay::strlen_ln(char *str) { + for (uint32_t cnt = 0; cnt < 256; cnt++) { + if (!str[cnt] || str[cnt] == '\n') return cnt; + } + return 0; +} + +char *uDisplay::devname(void) { + return dname; +} + +uint32_t uDisplay::str2c(char **sp, char *vp, uint32_t len) { + char *lp = *sp; + if (len) len--; + char *cp = strchr(lp, ','); + if (cp) { + while (1) { + if (*lp == ',') { + *vp = 0; + *sp = lp + 1; + return 0; + } + if (len) { + *vp++ = *lp++; + len--; + } else { + lp++; + } + } + } else { + uint8_t slen = strlen(lp); + if (slen) { + strlcpy(vp, *sp, len); + *sp = lp + slen; + return 0; + } + } + return 1; +} + +int32_t uDisplay::next_val(char **sp) { + char ibuff[16]; + str2c(sp, ibuff, sizeof(ibuff)); + return atoi(ibuff); +} + +uint32_t uDisplay::next_hex(char **sp) { + char ibuff[16]; + str2c(sp, ibuff, sizeof(ibuff)); + return strtol(ibuff, 0, 16); +} diff --git a/lib/lib_display/UDisplay/uDisplay.h b/lib/lib_display/UDisplay/uDisplay.h new file mode 100644 index 000000000..f5f3c789d --- /dev/null +++ b/lib/lib_display/UDisplay/uDisplay.h @@ -0,0 +1,114 @@ +#ifndef _UDISP_ +#define _UDISP_ + +#include +#include + +#define _UDSP_I2C 1 +#define _UDSP_SPI 2 + +#define UDISP1_WHITE 1 +#define UDISP1_BLACK 0 + + +// Color definitions +#define UDISP_BLACK 0x0000 /* 0, 0, 0 */ +#define UDISP_NAVY 0x000F /* 0, 0, 128 */ +#define UDISP_DARKGREEN 0x03E0 /* 0, 128, 0 */ +#define UDISP_DARKCYAN 0x03EF /* 0, 128, 128 */ +#define UDISP_MAROON 0x7800 /* 128, 0, 0 */ +#define UDISP_PURPLE 0x780F /* 128, 0, 128 */ +#define UDISP_OLIVE 0x7BE0 /* 128, 128, 0 */ +#define UDISP_LIGHTGREY 0xC618 /* 192, 192, 192 */ +#define UDISP_DARKGREY 0x7BEF /* 128, 128, 128 */ +#define UDISP_BLUE 0x001F /* 0, 0, 255 */ +#define UDISP_GREEN 0x07E0 /* 0, 255, 0 */ +#define UDISP_CYAN 0x07FF /* 0, 255, 255 */ +#define UDISP_RED 0xF800 /* 255, 0, 0 */ +#define UDISP_MAGENTA 0xF81F /* 255, 0, 255 */ +#define UDISP_YELLOW 0xFFE0 /* 255, 255, 0 */ +#define UDISP_WHITE 0xFFFF /* 255, 255, 255 */ +#define UDISP_ORANGE 0xFD20 /* 255, 165, 0 */ +#define UDISP_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ +#define UDISP_PINK 0xF81F + +#define SPI_BEGIN_TRANSACTION uspi->beginTransaction(spiSettings); +#define SPI_END_TRANSACTION uspi->endTransaction(); +#define SPI_CS_LOW if (spi_cs >= 0) digitalWrite(spi_cs, LOW); +#define SPI_CS_HIGH if (spi_cs >= 0) digitalWrite(spi_cs, HIGH); +#define SPI_DC_LOW if (spi_dc >= 0) digitalWrite(spi_dc, LOW); +#define SPI_DC_HIGH if (spi_dc >= 0) digitalWrite(spi_dc, HIGH); + +#define ESP32_PWM_CHANNEL 1 + +class uDisplay : public Renderer { + public: + uDisplay(char *); + Renderer *Init(void); + void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); + void Updateframe(); + void DisplayOnff(int8_t on); + void Splash(void); + char *devname(void); + uint16_t fgcol(void) const { return fg_col; }; + uint16_t bgcol(void) const { return bg_col; }; + void dim(uint8_t dim); + uint16_t GetColorFromIndex(uint8_t index); + void setRotation(uint8_t m); + void fillScreen(uint16_t color); + void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + void pushColors(uint16_t *data, uint16_t len, boolean first); + + private: + void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + void drawPixel(int16_t x, int16_t y, uint16_t color); + void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); + void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); + uint32_t str2c(char **sp, char *vp, uint32_t len); + void i2c_command(uint8_t val); + void spi_command(uint8_t val); + uint8_t strlen_ln(char *str); + int32_t next_val(char **sp); + uint32_t next_hex(char **sp); + void setAddrWindow_int(uint16_t x, uint16_t y, uint16_t w, uint16_t h); + char dname[16]; + int8_t bpp; + uint8_t interface; + uint8_t i2caddr; + int8_t i2c_scl; + int8_t i2c_sda; + int8_t reset; + uint8_t dsp_cmds[128]; + uint8_t dsp_ncmds; + uint8_t dsp_on; + uint8_t dsp_off; + uint16_t splash_font; + uint16_t splash_size; + uint16_t splash_xp; + uint16_t splash_yp; + uint16_t fg_col; + uint16_t bg_col; + uint16_t gxs; + uint16_t gys; + int8_t spi_cs; + int8_t spi_clk; + int8_t spi_mosi; + int8_t spi_dc; + int8_t bpanel; + int8_t spi_miso; + uint8_t dimmer; + SPIClass *uspi; + SPISettings spiSettings; + uint32_t spi_speed; + uint8_t spi_nr = 1; + uint8_t rot_0; + uint8_t rot_1; + uint8_t rot_2; + uint8_t rot_3; + uint8_t saw_1; + uint8_t saw_2; + uint8_t saw_3; + uint8_t flags; +}; + +#endif // _UDISP_