From 07f21b51206f1d94a5828594023d5fd343d7d211 Mon Sep 17 00:00:00 2001 From: Gozi Date: Tue, 10 Aug 2021 15:00:00 +0800 Subject: [PATCH] Add screen mirror function for ST7789 --- TFT_Drivers/ST7789_2_Rotation.h | 47 ++++++++++++++++++++++++++------- TFT_Drivers/ST7789_Rotation.h | 46 +++++++++++++++++++++++++------- TFT_eSPI.h | 32 +++++++++++++--------- 3 files changed, 94 insertions(+), 31 deletions(-) diff --git a/TFT_Drivers/ST7789_2_Rotation.h b/TFT_Drivers/ST7789_2_Rotation.h index 44a363e..32672e7 100644 --- a/TFT_Drivers/ST7789_2_Rotation.h +++ b/TFT_Drivers/ST7789_2_Rotation.h @@ -1,5 +1,4 @@ // This is the command sequence that rotates the ST7789 driver coordinate frame - writecommand(TFT_MADCTL); rotation = m % 4; switch (rotation) { @@ -16,7 +15,11 @@ rowstart = 0; } #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; _height = _init_height; @@ -24,6 +27,7 @@ case 1: // Landscape (Portrait + 90) #ifdef CGRAM_OFFSET + // TODO: Fix offset after mirror if (_init_width == 135) { colstart = 40; @@ -31,17 +35,26 @@ } else { - colstart = 0; - rowstart = 0; + if (mirror) { + colstart = 80; + rowstart = 0; + } else { + colstart = 0; + rowstart = 0; + } } #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; _height = _init_width; break; - case 2: // Inverter portrait + case 2: // Inverter portrait #ifdef CGRAM_OFFSET if (_init_width == 135) { @@ -54,13 +67,18 @@ rowstart = 80; } #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; _height = _init_height; break; case 3: // Inverted landscape #ifdef CGRAM_OFFSET + // TODO: Fix offset after mirror if (_init_width == 135) { colstart = 40; @@ -68,11 +86,20 @@ } else { - colstart = 80; - rowstart = 0; + if (mirror) { + colstart = 0; + rowstart = 0; + } else { + colstart = 80; + rowstart = 0; + } } #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; _height = _init_width; diff --git a/TFT_Drivers/ST7789_Rotation.h b/TFT_Drivers/ST7789_Rotation.h index 707c775..0d49f20 100644 --- a/TFT_Drivers/ST7789_Rotation.h +++ b/TFT_Drivers/ST7789_Rotation.h @@ -1,6 +1,6 @@ // This is the command sequence that rotates the ST7789 driver coordinate frame - writecommand(TFT_MADCTL); + uint8_t writedata(0); rotation = m % 4; switch (rotation) { case 0: // Portrait @@ -16,7 +16,11 @@ rowstart = 0; } #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; _height = _init_height; @@ -24,6 +28,7 @@ case 1: // Landscape (Portrait + 90) #ifdef CGRAM_OFFSET + // TODO: Fix offset after mirror if (_init_width == 135) { colstart = 40; @@ -31,11 +36,20 @@ } else { - colstart = 0; - rowstart = 0; + if (mirror) { + colstart = 80; + rowstart = 0; + } else { + colstart = 0; + rowstart = 0; + } } #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; _height = _init_width; @@ -54,13 +68,18 @@ rowstart = 80; } #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; _height = _init_height; break; case 3: // Inverted landscape #ifdef CGRAM_OFFSET + // TODO: Fix offset after mirror if (_init_width == 135) { colstart = 40; @@ -68,11 +87,20 @@ } else { - colstart = 80; - rowstart = 0; + if (mirror) { + colstart = 0; + rowstart = 0; + } else { + colstart = 80; + rowstart = 0; + } } #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; _height = _init_width; diff --git a/TFT_eSPI.h b/TFT_eSPI.h index 78a7f5b..5966304 100644 --- a/TFT_eSPI.h +++ b/TFT_eSPI.h @@ -270,7 +270,7 @@ const PROGMEM fontinfo fontdata [] = { #define TFT_WHITE 0xFFFF /* 255, 255, 255 */ #define TFT_ORANGE 0xFDA0 /* 255, 180, 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_GOLD 0xFEA0 /* 255, 215, 0 */ #define TFT_SILVER 0xC618 /* 192, 192, 192 */ @@ -303,7 +303,15 @@ static const uint16_t default_4bit_palette[] PROGMEM = { }; /*************************************************************************************** -** Section 7: Diagnostic support +** Section 7: Screen rotation enumeration +***************************************************************************************/ +#define TFT_PORTRAIT 0 +#define TFT_LANDSCAPE 1 +#define TFT_PORTRAIT_INVERT 2 +#define TFT_LANDSCAPE_INVERT 3 + +/*************************************************************************************** +** Section 8: Diagnostic support ***************************************************************************************/ // #define TFT_eSPI_DEBUG // Switch on debug support serial messages (not used yet) // #define TFT_eSPI_FNx_DEBUG // Switch on debug support for function "x" (not used yet) @@ -369,7 +377,7 @@ int16_t tch_spi_freq;// Touch controller read/write SPI frequency } setup_t; /*************************************************************************************** -** Section 8: Class member and support functions +** Section 9: Class member and support functions ***************************************************************************************/ // Swap any type template static inline void @@ -436,7 +444,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 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); // Support for half duplex (bi-directional SDA) SPI bus where MOSI must be switched to input @@ -513,7 +521,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 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 - + // Decimal is the number of decimal places to render // 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 @@ -537,14 +545,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()) getCursorY(void); // Read current cursor y position - + 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 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 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); void setTextPadding(uint16_t x_width); // Set text padding (background blanking/over-write) width in pixels @@ -571,7 +579,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 size_t write(uint8_t); - + // Used by Smooth font class to fetch a pixel colour for the anti-aliasing void setCallback(getColorCallback getCol); @@ -642,7 +650,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) // 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 - + // 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 // If swapping colour bytes is defined, and the double buffer option is NOT used, then the bytes @@ -786,7 +794,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 _booted; // init() or begin() has already run once - + // User sketch manages these via set/getAttribute() 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) @@ -799,7 +807,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac #endif /*************************************************************************************** -** Section 9: TFT_eSPI class conditional extensions +** Section 10: TFT_eSPI class conditional extensions ***************************************************************************************/ // Load the Touch extension #ifdef TOUCH_CS @@ -814,7 +822,7 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac }; // End of class TFT_eSPI /*************************************************************************************** -** Section 10: Additional extension classes +** Section 11: Additional extension classes ***************************************************************************************/ // Load the Button Class #include "Extensions/Button.h"