Add mirror option on setRotation for ST7789

This commit is contained in:
Gozi 2021-08-12 00:34:23 +08:00
parent 58f457ba97
commit f21e66ae15
4 changed files with 103 additions and 37 deletions

View File

@ -1,5 +1,4 @@
// This is the command sequence that rotates the ST7789 driver coordinate frame // This is the command sequence that rotates the ST7789 driver coordinate frame
writecommand(TFT_MADCTL); writecommand(TFT_MADCTL);
rotation = m % 4; rotation = m % 4;
switch (rotation) { switch (rotation) {
@ -16,7 +15,11 @@
rowstart = 0; rowstart = 0;
} }
#endif #endif
writedata(TFT_MAD_COLOR_ORDER); if (mirror) {
writedata(TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_COLOR_ORDER);
}
_width = _init_width; _width = _init_width;
_height = _init_height; _height = _init_height;
@ -26,22 +29,32 @@
#ifdef CGRAM_OFFSET #ifdef CGRAM_OFFSET
if (_init_width == 135) if (_init_width == 135)
{ {
// TODO: Fix offset after mirror
colstart = 40; colstart = 40;
rowstart = 53; rowstart = 53;
} }
else else
{ {
colstart = 0; if (mirror) {
rowstart = 0; colstart = 80;
rowstart = 0;
} else {
colstart = 0;
rowstart = 0;
}
} }
#endif #endif
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER); if (mirror) {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
}
_width = _init_height; _width = _init_height;
_height = _init_width; _height = _init_width;
break; break;
case 2: // Inverter portrait case 2: // Inverter portrait
#ifdef CGRAM_OFFSET #ifdef CGRAM_OFFSET
if (_init_width == 135) if (_init_width == 135)
{ {
@ -54,7 +67,11 @@
rowstart = 80; rowstart = 80;
} }
#endif #endif
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER); if (mirror) {
writedata(TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
}
_width = _init_width; _width = _init_width;
_height = _init_height; _height = _init_height;
@ -63,16 +80,26 @@
#ifdef CGRAM_OFFSET #ifdef CGRAM_OFFSET
if (_init_width == 135) if (_init_width == 135)
{ {
// TODO: Fix offset after mirror
colstart = 40; colstart = 40;
rowstart = 52; rowstart = 52;
} }
else else
{ {
colstart = 80; if (mirror) {
rowstart = 0; colstart = 0;
rowstart = 0;
} else {
colstart = 80;
rowstart = 0;
}
} }
#endif #endif
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER); if (mirror) {
writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
}
_width = _init_height; _width = _init_height;
_height = _init_width; _height = _init_width;

View File

@ -1,5 +1,4 @@
// This is the command sequence that rotates the ST7789 driver coordinate frame // This is the command sequence that rotates the ST7789 driver coordinate frame
writecommand(TFT_MADCTL); writecommand(TFT_MADCTL);
rotation = m % 4; rotation = m % 4;
switch (rotation) { switch (rotation) {
@ -16,7 +15,11 @@
rowstart = 0; rowstart = 0;
} }
#endif #endif
writedata(TFT_MAD_COLOR_ORDER); if (mirror) {
writedata(TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_COLOR_ORDER);
}
_width = _init_width; _width = _init_width;
_height = _init_height; _height = _init_height;
@ -26,16 +29,26 @@
#ifdef CGRAM_OFFSET #ifdef CGRAM_OFFSET
if (_init_width == 135) if (_init_width == 135)
{ {
// TODO: Fix offset after mirror
colstart = 40; colstart = 40;
rowstart = 53; rowstart = 53;
} }
else else
{ {
colstart = 0; if (mirror) {
rowstart = 0; colstart = 80;
rowstart = 0;
} else {
colstart = 0;
rowstart = 0;
}
} }
#endif #endif
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER); if (mirror) {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
}
_width = _init_height; _width = _init_height;
_height = _init_width; _height = _init_width;
@ -54,7 +67,11 @@
rowstart = 80; rowstart = 80;
} }
#endif #endif
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER); if (mirror) {
writedata(TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
}
_width = _init_width; _width = _init_width;
_height = _init_height; _height = _init_height;
@ -63,16 +80,26 @@
#ifdef CGRAM_OFFSET #ifdef CGRAM_OFFSET
if (_init_width == 135) if (_init_width == 135)
{ {
// TODO: Fix offset after mirror
colstart = 40; colstart = 40;
rowstart = 52; rowstart = 52;
} }
else else
{ {
colstart = 80; if (mirror) {
rowstart = 0; colstart = 0;
rowstart = 0;
} else {
colstart = 80;
rowstart = 0;
}
} }
#endif #endif
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER); if (mirror) {
writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
}
_width = _init_height; _width = _init_height;
_height = _init_width; _height = _init_width;

View File

@ -189,7 +189,7 @@ bool TFT_eSPI::checkViewport(int32_t x, int32_t y, int32_t w, int32_t h)
x+= _xDatum; x+= _xDatum;
y+= _yDatum; y+= _yDatum;
if ((x >= _vpW) || (y >= _vpH)) return false; if ((x >= _vpW) || (y >= _vpH)) return false;
int32_t dx = 0; int32_t dx = 0;
int32_t dy = 0; int32_t dy = 0;
@ -296,7 +296,7 @@ void TFT_eSPI::frameViewport(uint16_t color, int32_t w)
// a large negative width will clear the screen outside the viewport // a large negative width will clear the screen outside the viewport
{ {
w = -w; w = -w;
// Save old values // Save old values
int32_t _xT = _vpX; _vpX = 0; int32_t _xT = _vpX; _vpX = 0;
int32_t _yT = _vpY; _vpY = 0; int32_t _yT = _vpY; _vpY = 0;
@ -691,7 +691,13 @@ void TFT_eSPI::init(uint8_t tc)
** Function name: setRotation ** Function name: setRotation
** Description: rotate the screen orientation m = 0-3 or 4-7 for BMP drawing ** Description: rotate the screen orientation m = 0-3 or 4-7 for BMP drawing
***************************************************************************************/ ***************************************************************************************/
void TFT_eSPI::setRotation(uint8_t m) void TFT_eSPI::setRotation(uint8_t m)
{
setRotation(m, false);
}
void TFT_eSPI::setRotation(uint8_t m, bool mirror)
{ {
begin_tft_write(); begin_tft_write();
@ -1894,7 +1900,7 @@ void TFT_eSPI::readRectRGB(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_
uint8_t* buf565 = data + len; uint8_t* buf565 = data + len;
readRect(x0, y0, w, h, (uint16_t*)buf565); readRect(x0, y0, w, h, (uint16_t*)buf565);
while (len--) { while (len--) {
uint16_t pixel565 = (*buf565++)<<8; uint16_t pixel565 = (*buf565++)<<8;
pixel565 |= *buf565++; pixel565 |= *buf565++;
@ -1973,7 +1979,7 @@ void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color)
int32_t xs = -1; int32_t xs = -1;
int32_t xe = 0; int32_t xe = 0;
int32_t len = 0; int32_t len = 0;
bool first = true; bool first = true;
do { do {
while (f < 0) { while (f < 0) {
@ -3231,7 +3237,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
x+= _xDatum; x+= _xDatum;
y+= _yDatum; y+= _yDatum;
// Range checking // Range checking
if ((x < _vpX) || (y < _vpY) ||(x >= _vpW) || (y >= _vpH)) return; if ((x < _vpX) || (y < _vpY) ||(x >= _vpW) || (y >= _vpH)) return;
#ifdef CGRAM_OFFSET #ifdef CGRAM_OFFSET
@ -3254,7 +3260,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
DC_D; tft_Write_16(0); DC_D; tft_Write_16(0);
DC_C; tft_Write_8(TFT_CASET2); DC_C; tft_Write_8(TFT_CASET2);
DC_D; tft_Write_16(175); DC_D; tft_Write_16(175);
DC_C; tft_Write_8(TFT_PASET1); DC_C; tft_Write_8(TFT_PASET1);
DC_D; tft_Write_16(0); DC_D; tft_Write_16(0);
DC_C; tft_Write_8(TFT_PASET2); DC_C; tft_Write_8(TFT_PASET2);
@ -3342,7 +3348,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
#else #else
#if defined (SSD1351_DRIVER) || defined (SSD1963_DRIVER) #if defined (SSD1351_DRIVER) || defined (SSD1963_DRIVER)
if ((rotation & 0x1) == 0) { swap_coord(x, y); } if ((rotation & 0x1) == 0) { swap_coord(x, y); }
#endif #endif
@ -3384,7 +3390,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
} }
#endif #endif
DC_C; tft_Write_8(TFT_RAMWR); DC_C; tft_Write_8(TFT_RAMWR);
#if defined(TFT_PARALLEL_8_BIT) || !defined(ESP32) #if defined(TFT_PARALLEL_8_BIT) || !defined(ESP32)
DC_D; tft_Write_16(color); DC_D; tft_Write_16(color);
#else #else
@ -3899,7 +3905,7 @@ uint16_t TFT_eSPI::alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc, uint8_t
if (alphaDither < 0) alpha = 0; if (alphaDither < 0) alpha = 0;
if (alphaDither >255) alpha = 255; if (alphaDither >255) alpha = 255;
} }
return alphaBlend(alpha, fgc, bgc); return alphaBlend(alpha, fgc, bgc);
} }
@ -4235,7 +4241,7 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
w *= height; // Now w is total number of pixels in the character w *= height; // Now w is total number of pixels in the character
if (textcolor == textbgcolor && !clip) { if (textcolor == textbgcolor && !clip) {
int32_t px = 0, py = pY; // To hold character block start and end column and row values int32_t px = 0, py = pY; // To hold character block start and end column and row values
int32_t pc = 0; // Pixel count int32_t pc = 0; // Pixel count
uint8_t np = textsize * textsize; // Number of pixels in a drawn pixel uint8_t np = textsize * textsize; // Number of pixels in a drawn pixel

View File

@ -270,13 +270,18 @@ const PROGMEM fontinfo fontdata [] = {
#define TFT_WHITE 0xFFFF /* 255, 255, 255 */ #define TFT_WHITE 0xFFFF /* 255, 255, 255 */
#define TFT_ORANGE 0xFDA0 /* 255, 180, 0 */ #define TFT_ORANGE 0xFDA0 /* 255, 180, 0 */
#define TFT_GREENYELLOW 0xB7E0 /* 180, 255, 0 */ #define TFT_GREENYELLOW 0xB7E0 /* 180, 255, 0 */
#define TFT_PINK 0xFE19 /* 255, 192, 203 */ //Lighter pink, was 0xFC9F #define TFT_PINK 0xFE19 /* 255, 192, 203 */ //Lighter pink, was 0xFC9F
#define TFT_BROWN 0x9A60 /* 150, 75, 0 */ #define TFT_BROWN 0x9A60 /* 150, 75, 0 */
#define TFT_GOLD 0xFEA0 /* 255, 215, 0 */ #define TFT_GOLD 0xFEA0 /* 255, 215, 0 */
#define TFT_SILVER 0xC618 /* 192, 192, 192 */ #define TFT_SILVER 0xC618 /* 192, 192, 192 */
#define TFT_SKYBLUE 0x867D /* 135, 206, 235 */ #define TFT_SKYBLUE 0x867D /* 135, 206, 235 */
#define TFT_VIOLET 0x915C /* 180, 46, 226 */ #define TFT_VIOLET 0x915C /* 180, 46, 226 */
#define TFT_PORTRAIT 0
#define TFT_LANDSCAPE 1
#define TFT_PORTRAIT_INVERT 2
#define TFT_LANDSCAPE_INVERT 3
// Next is a special 16 bit colour value that encodes to 8 bits // Next is a special 16 bit colour value that encodes to 8 bits
// and will then decode back to the same 16 bit value. // and will then decode back to the same 16 bit value.
// Convenient for 8 bit and 16 bit transparent sprites. // Convenient for 8 bit and 16 bit transparent sprites.
@ -404,6 +409,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
width(void); width(void);
void setRotation(uint8_t r); // Set the display image orientation to 0, 1, 2 or 3 void setRotation(uint8_t r); // Set the display image orientation to 0, 1, 2 or 3
void setRotation(uint8_t r, bool mirror); // Set the display image orientation with mirro flag
uint8_t getRotation(void); // Read the current rotation uint8_t getRotation(void); // Read the current rotation
void invertDisplay(bool i); // Tell TFT to invert all displayed colours void invertDisplay(bool i); // Tell TFT to invert all displayed colours
@ -436,7 +442,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Write a set of pixels stored in memory, use setSwapBytes(true/false) function to correct endianess // Write a set of pixels stored in memory, use setSwapBytes(true/false) function to correct endianess
void pushPixels(const void * data_in, uint32_t len); void pushPixels(const void * data_in, uint32_t len);
// Read the colour of a pixel at x,y and return value in 565 format // Read the colour of a pixel at x,y and return value in 565 format
uint16_t readPixel(int32_t x, int32_t y); uint16_t readPixel(int32_t x, int32_t y);
// Support for half duplex (bi-directional SDA) SPI bus where MOSI must be switched to input // Support for half duplex (bi-directional SDA) SPI bus where MOSI must be switched to input
@ -513,7 +519,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Text rendering - value returned is the pixel width of the rendered text // Text rendering - value returned is the pixel width of the rendered text
int16_t drawNumber(long intNumber, int32_t x, int32_t y, uint8_t font), // Draw integer using specified font number int16_t drawNumber(long intNumber, int32_t x, int32_t y, uint8_t font), // Draw integer using specified font number
drawNumber(long intNumber, int32_t x, int32_t y), // Draw integer using current font drawNumber(long intNumber, int32_t x, int32_t y), // Draw integer using current font
// Decimal is the number of decimal places to render // Decimal is the number of decimal places to render
// Use with setTextDatum() to position values on TFT, and setTextPadding() to blank old displayed values // Use with setTextDatum() to position values on TFT, and setTextPadding() to blank old displayed values
drawFloat(float floatNumber, uint8_t decimal, int32_t x, int32_t y, uint8_t font), // Draw float using specified font number drawFloat(float floatNumber, uint8_t decimal, int32_t x, int32_t y, uint8_t font), // Draw float using specified font number
@ -537,14 +543,14 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
int16_t getCursorX(void), // Read current cursor x position (moves with tft.print()) int16_t getCursorX(void), // Read current cursor x position (moves with tft.print())
getCursorY(void); // Read current cursor y position getCursorY(void); // Read current cursor y position
void setTextColor(uint16_t color), // Set character (glyph) color only (background not over-written) void setTextColor(uint16_t color), // Set character (glyph) color only (background not over-written)
setTextColor(uint16_t fgcolor, uint16_t bgcolor),// Set character (glyph) foreground and backgorund colour setTextColor(uint16_t fgcolor, uint16_t bgcolor),// Set character (glyph) foreground and backgorund colour
setTextSize(uint8_t size); // Set character size multiplier (this increases pixel size) setTextSize(uint8_t size); // Set character size multiplier (this increases pixel size)
void setTextWrap(bool wrapX, bool wrapY = false); // Turn on/off wrapping of text in TFT width and/or height void setTextWrap(bool wrapX, bool wrapY = false); // Turn on/off wrapping of text in TFT width and/or height
void setTextDatum(uint8_t datum); // Set text datum position (default is top left), see Section 6 above void setTextDatum(uint8_t datum); // Set text datum position (default is top left), see Section 6 above
uint8_t getTextDatum(void); uint8_t getTextDatum(void);
void setTextPadding(uint16_t x_width); // Set text padding (background blanking/over-write) width in pixels void setTextPadding(uint16_t x_width); // Set text padding (background blanking/over-write) width in pixels
@ -571,7 +577,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Support function to UTF8 decode and draw characters piped through print stream // Support function to UTF8 decode and draw characters piped through print stream
size_t write(uint8_t); size_t write(uint8_t);
// Used by Smooth font class to fetch a pixel colour for the anti-aliasing // Used by Smooth font class to fetch a pixel colour for the anti-aliasing
void setCallback(getColorCallback getCol); void setCallback(getColorCallback getCol);
@ -642,7 +648,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
// Parameter "true" enables DMA engine control of TFT chip select (ESP32 only) // Parameter "true" enables DMA engine control of TFT chip select (ESP32 only)
// For ESP32 only, TFT reads will not work if parameter is true // For ESP32 only, TFT reads will not work if parameter is true
void deInitDMA(void); // De-initialise the DMA engine and detach from SPI bus - typically not used void deInitDMA(void); // De-initialise the DMA engine and detach from SPI bus - typically not used
// Push an image to the TFT using DMA, buffer is optional and grabs (double buffers) a copy of the image // Push an image to the TFT using DMA, buffer is optional and grabs (double buffers) a copy of the image
// Use the buffer if the image data will get over-written or destroyed while DMA is in progress // Use the buffer if the image data will get over-written or destroyed while DMA is in progress
// If swapping colour bytes is defined, and the double buffer option is NOT used, then the bytes // If swapping colour bytes is defined, and the double buffer option is NOT used, then the bytes
@ -786,7 +792,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
bool locked, inTransaction, lockTransaction; // SPI transaction and mutex lock flags bool locked, inTransaction, lockTransaction; // SPI transaction and mutex lock flags
bool _booted; // init() or begin() has already run once bool _booted; // init() or begin() has already run once
// User sketch manages these via set/getAttribute() // User sketch manages these via set/getAttribute()
bool _cp437; // If set, use correct CP437 charset (default is ON) bool _cp437; // If set, use correct CP437 charset (default is ON)
bool _utf8; // If set, use UTF-8 decoder in print stream 'write()' function (default ON) bool _utf8; // If set, use UTF-8 decoder in print stream 'write()' function (default ON)