Feature update

Add ILI9225 support
Add viewport feature to Sprites
Rationalise common TFT_eSPI and Sprite functions and variables to use inherited functions width(), height(), rotation(), write(), pivot, cursor, swapBytes.
This commit is contained in:
Bodmer 2020-12-01 20:06:32 +00:00
parent 27216f89cc
commit 42e6fc87ff
16 changed files with 843 additions and 921 deletions

View File

@ -68,7 +68,7 @@ void TFT_eSPI_Button::drawButton(bool inverted, String long_name) {
uint8_t tempdatum = _gfx->getTextDatum();
_gfx->setTextDatum(_textdatum);
uint16_t tempPadding = _gfx->padX;
uint16_t tempPadding = _gfx->getTextPadding();
_gfx->setTextPadding(0);
if (long_name == "")

View File

@ -373,7 +373,7 @@ void TFT_eSPI::drawGlyph(uint16_t code)
if (code == '\n') {
cursor_x = 0;
cursor_y += gFont.yAdvance;
if (cursor_y >= _height) cursor_y = 0;
if (textwrapY && (cursor_y >= height())) cursor_y = 0;
return;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -85,9 +85,6 @@ class TFT_eSprite : public TFT_eSPI {
// Fill a rectangular area with a color (aka draw a filled rectangle)
fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
// Set the sprite text cursor position for print class (does not change the TFT screen cursor)
//setCursor(int16_t x, int16_t y); // Not needed, so uses TFT class function
// Set the coordinate rotation of the Sprite (for 1bpp Sprites only)
// Note: this uses coordinate rotation and is primarily for ePaper which does not support
// CGRAM rotation (like TFT drivers do) within the displays internal hardware
@ -99,11 +96,6 @@ class TFT_eSprite : public TFT_eSPI {
// Push a rotated copy of Sprite to another different Sprite with optional transparent colour
bool pushRotated(TFT_eSprite *spr, int16_t angle, int32_t transp = -1); // Using fixed point maths
// Set and get the pivot point for this Sprite
void setPivot(int16_t x, int16_t y);
int16_t getPivotX(void),
getPivotY(void);
// Get the TFT bounding box for a rotated copy of this Sprite
bool getRotatedBounds(int16_t angle, int16_t *min_x, int16_t *min_y, int16_t *max_x, int16_t *max_y);
// Get the destination Sprite bounding box for a rotated copy of this Sprite
@ -121,13 +113,9 @@ class TFT_eSprite : public TFT_eSPI {
uint16_t readPixelValue(int32_t x, int32_t y);
// Write an image (colour bitmap) to the sprite.
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data, uint8_t sbpp = 0);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, const uint16_t *data);
// Swap the byte order for pushImage() - corrects different image endianness
void setSwapBytes(bool swap);
bool getSwapBytes(void);
// Push the sprite to the TFT screen, this fn calls pushImage() in the TFT class.
// Optionally a "transparent" colour can be defined, pixels of that colour will not be rendered
void pushSprite(int32_t x, int32_t y);
@ -148,9 +136,6 @@ class TFT_eSprite : public TFT_eSPI {
int16_t width(void),
height(void);
// Used by print class to print text to cursor position
size_t write(uint8_t);
// Functions associated with anti-aliased fonts
void drawGlyph(uint16_t code);
void printToSprite(String string);
@ -175,23 +160,17 @@ class TFT_eSprite : public TFT_eSPI {
uint16_t *_colorMap; // color map: 16 entries, used with 4 bit color map.
int16_t _xPivot; // x pivot point coordinate
int16_t _yPivot; // y pivot point coordinate
int32_t _sinra;
int32_t _cosra;
bool _created; // A Sprite has been created and memory reserved
bool _gFont = false;
// int32_t _icursor_x, _icursor_y;
uint8_t _rotation = 0;
int32_t _xs, _ys, _xe, _ye, _xptr, _yptr; // for setWindow
int32_t _sx, _sy; // x,y for scroll zone
uint32_t _sw, _sh; // w,h for scroll zone
uint32_t _scolor; // gap fill colour for scroll zone
bool _iswapBytes; // Swap the byte order for Sprite pushImage()
int32_t _iwidth, _iheight; // Sprite memory image bit width and height (swapped during rotations)
int32_t _dwidth, _dheight; // Real display width and height (for <8bpp Sprites)
int32_t _bitwidth; // Sprite image bit width for drawPixel (for <8bpp Sprites, not swapped)

View File

@ -1,37 +1,53 @@
# Sprite class change
The Sprite class has been updated to remove an inconsistency for the setSwapBytes() function. Although all the examples are unchanged, user sketches may be affected. If the colors of the sprite change when loading this new version 2.2.16 then it may be necessary to change the swap bytes setting, e.g. for a sprite instance "spr" use either: spr.setSwapBytes(true) or spr.setSwapBytes(false) to correct the colour.
# News
1. The library now provides a "viewport" capability. See "Viewport_Demo" and "Viewport_graphicstest" examples. When a viewport is defined graphics will only appear within that window. The coordinate datum by default moves to the top left corner of the viewport, but can optionally remain at top left corner of TFT. The GUIslice library will make use of this feature to speed up the rendering of GUI objects ([see #769](https://github.com/Bodmer/TFT_eSPI/issues/769)).
1. Viewports can now be applied to sprites e.g. spr.setViewport(5, 5, 20, 20); so graphics can be restricted to a particular area of the sprite. This operates in the same way as the TFT viewports, see 2. below.
2. The library now supports SSD1963 based screen, this has been tested on a [480x800 screen](https://www.buydisplay.com/7-tft-screen-touch-lcd-display-module-w-ssd1963-controller-board-mcu) with an ESP32. The interface is 8 bit parallel only as that controller does not support a SPI interface.
2. The library now provides a "viewport" capability. See "Viewport_Demo" and "Viewport_graphicstest" examples. When a viewport is defined graphics will only appear within that window. The coordinate datum by default moves to the top left corner of the viewport, but can optionally remain at top left corner of TFT. The GUIslice library will make use of this feature to speed up the rendering of GUI objects ([see #769](https://github.com/Bodmer/TFT_eSPI/issues/769)).
3. A companion library [U8g2_for_TFT_eSPI](https://github.com/Bodmer/U8g2_for_TFT_eSPI) has been created to allow U8g2 library fonts to be used with TFT_eSPI.
3. The library now supports SSD1963 based screen, this has been tested on a [480x800 screen](https://www.buydisplay.com/7-tft-screen-touch-lcd-display-module-w-ssd1963-controller-board-mcu) with an ESP32. The interface is 8 bit parallel only as that controller does not support a SPI interface.
4. The library now supports SPI DMA transfers for both ESP32 and STM32 processors. The DMA Test examples now work on the ESP32 for SPI displays (excluding RPi type and ILI9488).
4. A companion library [U8g2_for_TFT_eSPI](https://github.com/Bodmer/U8g2_for_TFT_eSPI) has been created to allow U8g2 library fonts to be used with TFT_eSPI.
5. A new option has been added for STM32 processors to optimise performance where Port A (or B) pins 0-7 are used for the 8 bit parallel interface data pins 0-7 to the TFT. This gives a dramatic 8 times better rendering performance for the lower clock rate STM32 processors such as the STM32F103 "Blue Pill" or STM411 "Black Pill" since no time consuming data bit manipulation is required. See setup file "User_Setups/Setup35_ILI9341_STM32_Port_Bus.h".
5. The library now supports SPI DMA transfers for both ESP32 and STM32 processors. The DMA Test examples now work on the ESP32 for SPI displays (excluding RPi type and ILI9488).
6. A new "Animated_dial" example has been added to show how dials can be created using a rotated Sprite for the needle. To run this example the TFT must support reading from the screen RAM. The dial rim and scale is a jpeg image, created using a paint program.
6. A new option has been added for STM32 processors to optimise performance where Port A (or B) pins 0-7 are used for the 8 bit parallel interface data pins 0-7 to the TFT. This gives a dramatic 8 times better rendering performance for the lower clock rate STM32 processors such as the STM32F103 "Blue Pill" or STM411 "Black Pill" since no time consuming data bit manipulation is required. See setup file "User_Setups/Setup35_ILI9341_STM32_Port_Bus.h".
7. A new "Animated_dial" example has been added to show how dials can be created using a rotated Sprite for the needle. To run this example the TFT must support reading from the screen RAM. The dial rim and scale is a jpeg image, created using a paint program.
![Animated_dial](https://i.imgur.com/S736Rg6.png)
7. Anti-aliased (smooth) fonts can now be stored as arrays in FLASH (program) memory. This means that processors such as STM32 that do not have SPIFFS support can use the fonts. The processor must have sufficient FLASH memory to store the fonts used.
8. The Sprite class now supports 4 bits per pixel with a 16 color palette. Three new examples have been added.
8. Anti-aliased (smooth) fonts can now be stored as arrays in FLASH (program) memory. This means that processors such as STM32 that do not have SPIFFS support can use the fonts. The processor must have sufficient FLASH memory to store the fonts used.
# TFT_eSPI
An Arduino IDE compatible graphics and fonts library for 32 bit processors. The library is targetted at 32 bit processors, it has been performance optimised for STM32, ESP8266 and ESP32 types. The library includes drivers for ILI9341, ILI9163, ST7735, S6D02A1, ILI9481, ILI9486, ILI9488, HX8357D, ST7789 and ST7796 based TFT displays that support SPI or 8 bit parallel (parallel not supported on ESP8266). The library can be loaded using the Arduino IDE's Library Manager.
An Arduino IDE compatible graphics and fonts library for 32 bit processors. The library is targetted at 32 bit processors, it has been performance optimised for STM32, ESP8266 and ESP32 types. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32 and STM32 processors to improve rendering performance.
8 bit parallel interface TFTs (e.g. UNO format mcufriend shields) can used with the STM32 Nucleo 64/144 range or the UNO format ESP32 (see below for ESP32).
"Four wire" SPI and 8 bit parallel interfaces are supported. Due to lack of GPIO pins the 8 bit parallel interface is NOT supported on the ESP8266. 8 bit parallel interface TFTs (e.g. UNO format mcufriend shields) can used with the STM32 Nucleo 64/144 range or the UNO format ESP32 (see below for ESP32).
The library supports TFT displays designed for the Raspberry Pi (RPi) that are based on a ILI9486 or ST7796 driver chip with a 480 x 320 pixel screen. The ILI9486 RPi display must be of the Waveshare design and use a 16 bit serial interface based on the 74HC04, 74HC4040 and 2 x 74HC4094 logic chips. A modification to these displays is possible (see mod image in Tools folder) to make many graphics functions much faster (e.g. 23ms to clear the screen, 1.2ms to draw a 72 pixel high numeral). The RPi ST7796 display is supported and is superior to the Waveshare design, it must be of the MHS-4.0 inch Display-B type.
Displays using the following controllers are supported:
Some displays permit the internal TFT screen RAM to be read. The library supports reading from ILI9341, ST7789 and ILI9488 SPI and other supported 8 bit parallel displays. The TFT_Screen_Capture example allows full screens to be captured and sent to a PC, this is handy to create program documentation.
* ILI9163
* ILI9225
* ILI9341
* ILI9481
* ILI9486
* ILI9488
* HX8357D
* S6D02A1
* SSD1963
* ST7735
* ST7789
* ST7796
Support has been added recently for Waveshare 2 and 3 colour ePaper displays using full frame buffers. This addition is currently relatively immature and thus only one example has been provided.
ILI9341 and ST7796 SPI based displays are recommended as starting point for experimenting with this library.
The library supports some TFT displays designed for the Raspberry Pi (RPi) that are based on a ILI9486 or ST7796 driver chip with a 480 x 320 pixel screen. The ILI9486 RPi display must be of the Waveshare design and use a 16 bit serial interface based on the 74HC04, 74HC4040 and 2 x 74HC4094 logic chips. Note that due to design variations between these displays not all RPi displays will work with this library, so purchaing a RPi display of these types soley for use with this library is not recommended.
The "good" RPi displays are the [MHS-4.0 inch Display-B type ST7796](http://www.lcdwiki.com/MHS-4.0inch_Display-B) and [Waveshare 3.5 inch ILI9486 Type C](https://www.waveshare.com/wiki/3.5inch_RPi_LCD_(C)) displays are supported and provides good performance. These have a dedicated controller and can be clocked at up to 80MHz with the ESP32 (55MHz with STM32 and 40MHz with ESP8266).
Some displays permit the internal TFT screen RAM to be read, some of the examples use this feature. The TFT_Screen_Capture example allows full screens to be captured and sent to a PC, this is handy to create program documentation.
The library supports Waveshare 2 and 3 colour ePaper displays using full frame buffers. This addition is relatively immature and thus only one example has been provided.
The library includes a "Sprite" class, this enables flicker free updates of complex graphics. Direct writes to the TFT with graphics functions are still available, so existing sketches do not need to be changed.

View File

@ -3,50 +3,82 @@
#define TFT_WIDTH 176
#define TFT_HEIGHT 220
/* ILI9225 LCD Registers */
#define ILI9225_DRIVER_OUTPUT_CTRL (0x01u) // Driver Output Control
#define ILI9225_LCD_AC_DRIVING_CTRL (0x02u) // LCD AC Driving Control
#define ILI9225_ENTRY_MODE (0x03u) // Entry Mode
#define ILI9225_DISP_CTRL1 (0x07u) // Display Control 1
#define ILI9225_BLANK_PERIOD_CTRL1 (0x08u) // Blank Period Control
#define ILI9225_FRAME_CYCLE_CTRL (0x0Bu) // Frame Cycle Control
#define ILI9225_INTERFACE_CTRL (0x0Cu) // Interface Control
#define ILI9225_OSC_CTRL (0x0Fu) // Osc Control
#define ILI9225_POWER_CTRL1 (0x10u) // Power Control 1
#define ILI9225_POWER_CTRL2 (0x11u) // Power Control 2
#define ILI9225_POWER_CTRL3 (0x12u) // Power Control 3
#define ILI9225_POWER_CTRL4 (0x13u) // Power Control 4
#define ILI9225_POWER_CTRL5 (0x14u) // Power Control 5
#define ILI9225_VCI_RECYCLING (0x15u) // VCI Recycling
#define ILI9225_RAM_ADDR_SET1 (0x20u) // Horizontal GRAM Address Set
#define ILI9225_RAM_ADDR_SET2 (0x21u) // Vertical GRAM Address Set
#define ILI9225_GRAM_DATA_REG (0x22u) // GRAM Data Register
#define ILI9225_GATE_SCAN_CTRL (0x30u) // Gate Scan Control Register
#define ILI9225_VERTICAL_SCROLL_CTRL1 (0x31u) // Vertical Scroll Control 1 Register
#define ILI9225_VERTICAL_SCROLL_CTRL2 (0x32u) // Vertical Scroll Control 2 Register
#define ILI9225_VERTICAL_SCROLL_CTRL3 (0x33u) // Vertical Scroll Control 3 Register
#define ILI9225_PARTIAL_DRIVING_POS1 (0x34u) // Partial Driving Position 1 Register
#define ILI9225_PARTIAL_DRIVING_POS2 (0x35u) // Partial Driving Position 2 Register
#define ILI9225_HORIZONTAL_WINDOW_ADDR1 (0x36u) // Horizontal Address Start Position
#define ILI9225_HORIZONTAL_WINDOW_ADDR2 (0x37u) // Horizontal Address End Position
#define ILI9225_VERTICAL_WINDOW_ADDR1 (0x38u) // Vertical Address Start Position
#define ILI9225_VERTICAL_WINDOW_ADDR2 (0x39u) // Vertical Address End Position
#define ILI9225_GAMMA_CTRL1 (0x50u) // Gamma Control 1
#define ILI9225_GAMMA_CTRL2 (0x51u) // Gamma Control 2
#define ILI9225_GAMMA_CTRL3 (0x52u) // Gamma Control 3
#define ILI9225_GAMMA_CTRL4 (0x53u) // Gamma Control 4
#define ILI9225_GAMMA_CTRL5 (0x54u) // Gamma Control 5
#define ILI9225_GAMMA_CTRL6 (0x55u) // Gamma Control 6
#define ILI9225_GAMMA_CTRL7 (0x56u) // Gamma Control 7
#define ILI9225_GAMMA_CTRL8 (0x57u) // Gamma Control 8
#define ILI9225_GAMMA_CTRL9 (0x58u) // Gamma Control 9
#define ILI9225_GAMMA_CTRL10 (0x59u) // Gamma Control 10
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21
// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP 0x00
#define TFT_SWRST 0x28
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked
#define TFT_CASET 0
#define TFT_PASET 0
#define TFT_CASET1 ILI9225_HORIZONTAL_WINDOW_ADDR2
#define TFT_CASET2 ILI9225_HORIZONTAL_WINDOW_ADDR1
#define TFT_PASET1 ILI9225_VERTICAL_WINDOW_ADDR2
#define TFT_PASET2 ILI9225_VERTICAL_WINDOW_ADDR1
#define TFT_RAM_ADDR1 ILI9225_RAM_ADDR_SET1
#define TFT_RAM_ADDR2 ILI9225_RAM_ADDR_SET2
#define TFT_RAMWR ILI9225_GRAM_DATA_REG
#define TFT_MAD_BGR 0x10
#define TFT_MAD_RGB 0x00
#ifdef TFT_RGB_ORDER
#if (TFT_RGB_ORDER == 1)
#define TFT_MAD_COLOR_ORDER TFT_MAD_RGB
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
#else
#define TFT_MAD_COLOR_ORDER TFT_MAD_BGR
#endif
// Not used
#define TFT_INVOFF 0x00
#define TFT_INVON 0x00
#define TFT_RAMRD 0x00
#define TFT_IDXRD 0x00
/* ILI9225 Registers */
#define ILI9225_DRIVER_OUTPUT_CTRL 0x01 // Driver Output Control
#define ILI9225_LCD_AC_DRIVING_CTRL 0x02 // LCD AC Driving Control
#define ILI9225_ENTRY_MODE 0x03 // Entry Mode
#define ILI9225_DISP_CTRL1 0x07 // Display Control 1
#define ILI9225_BLANK_PERIOD_CTRL1 0x08 // Blank Period Control
#define ILI9225_FRAME_CYCLE_CTRL 0x0B // Frame Cycle Control
#define ILI9225_INTERFACE_CTRL 0x0C // Interface Control
#define ILI9225_OSC_CTRL 0x0F // Osc Control
#define ILI9225_POWER_CTRL1 0x10 // Power Control 1
#define ILI9225_POWER_CTRL2 0x11 // Power Control 2
#define ILI9225_POWER_CTRL3 0x12 // Power Control 3
#define ILI9225_POWER_CTRL4 0x13 // Power Control 4
#define ILI9225_POWER_CTRL5 0x14 // Power Control 5
#define ILI9225_VCI_RECYCLING 0x15 // VCI Recycling
#define ILI9225_RAM_ADDR_SET1 0x20 // Horizontal GRAM Address Set
#define ILI9225_RAM_ADDR_SET2 0x21 // Vertical GRAM Address Set
#define ILI9225_GRAM_DATA_REG 0x22 // GRAM Data Register
#define ILI9225_GATE_SCAN_CTRL 0x30 // Gate Scan Control Register
#define ILI9225_VERTICAL_SCROLL_CTRL1 0x31 // Vertical Scroll Control 1 Register
#define ILI9225_VERTICAL_SCROLL_CTRL2 0x32 // Vertical Scroll Control 2 Register
#define ILI9225_VERTICAL_SCROLL_CTRL3 0x33 // Vertical Scroll Control 3 Register
#define ILI9225_PARTIAL_DRIVING_POS1 0x34 // Partial Driving Position 1 Register
#define ILI9225_PARTIAL_DRIVING_POS2 0x35 // Partial Driving Position 2 Register
#define ILI9225_HORIZONTAL_WINDOW_ADDR1 0x36 // Horizontal Address Start Position
#define ILI9225_HORIZONTAL_WINDOW_ADDR2 0x37 // Horizontal Address End Position
#define ILI9225_VERTICAL_WINDOW_ADDR1 0x38 // Vertical Address Start Position
#define ILI9225_VERTICAL_WINDOW_ADDR2 0x39 // Vertical Address End Position
#define ILI9225_GAMMA_CTRL1 0x50 // Gamma Control 1
#define ILI9225_GAMMA_CTRL2 0x51 // Gamma Control 2
#define ILI9225_GAMMA_CTRL3 0x52 // Gamma Control 3
#define ILI9225_GAMMA_CTRL4 0x53 // Gamma Control 4
#define ILI9225_GAMMA_CTRL5 0x54 // Gamma Control 5
#define ILI9225_GAMMA_CTRL6 0x55 // Gamma Control 6
#define ILI9225_GAMMA_CTRL7 0x56 // Gamma Control 7
#define ILI9225_GAMMA_CTRL8 0x57 // Gamma Control 8
#define ILI9225_GAMMA_CTRL9 0x58 // Gamma Control 9
#define ILI9225_GAMMA_CTRL10 0x59 // Gamma Control 10
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x00 // Not used unless commandlist invoked
#define TFT_MAD_BGR 0x10

View File

@ -1,65 +1,56 @@
// This is the command sequence that initialises the ILI9225 driver
{
/* Start Initial Sequence */
//LCD Init For 2.2inch LCD Panel with ILI9225.
writecommand(ILI9225_POWER_CTRL1);
writedata(0x00);writedata(0x00); // Set SAP,DSTB,STB
writedata(0x00);writedata(0x00);
writecommand(ILI9225_POWER_CTRL2);
writedata(0x00);writedata(0x00); // Set APON,PON,AON,VCI1EN,VC
writedata(0x00);writedata(0x00);
writecommand(ILI9225_POWER_CTRL3);
writedata(0x00);writedata(0x00); // Set BT,DC1,DC2,DC3
writedata(0x00);writedata(0x00);
writecommand(ILI9225_POWER_CTRL4);
writedata(0x00);writedata(0x00); // Set GVDD
writedata(0x00);writedata(0x00);
writecommand(ILI9225_POWER_CTRL5);
writedata(0x00);writedata(0x00); // Set VCOMH/VCOML voltage
spi_end();
writedata(0x00);writedata(0x00);
delay(40);
spi_begin();
// Power-on sequence
writecommand(ILI9225_POWER_CTRL2);
writedata(0x00);writedata(0x18); // Set APON,PON,AON,VCI1EN,VC
writedata(0x00);writedata(0x18);
writecommand(ILI9225_POWER_CTRL3);
writedata(0x61);writedata(0x21); // Set BT,DC1,DC2,DC3
writedata(0x61);writedata(0x21);
writecommand(ILI9225_POWER_CTRL4);
writedata(0x00);writedata(0x6F); // Set GVDD /*007F 0088 */
writedata(0x00);writedata(0x6F);
writecommand(ILI9225_POWER_CTRL5);
writedata(0x49);writedata(0x5F); // Set VCOMH/VCOML voltage
writedata(0x49);writedata(0x5F);
writecommand(ILI9225_POWER_CTRL1);
writedata(0x08);writedata(0x00); // Set SAP,DSTB,STB
spi_end();
writedata(0x08);writedata(0x00);
delay(10);
spi_begin();
writecommand(ILI9225_POWER_CTRL2);
writedata(0x10);writedata(0x3B); // Set APON,PON,AON,VCI1EN,VC
spi_end();
writedata(0x10);writedata(0x3B);
delay(50);
spi_begin();
writecommand(ILI9225_LCD_AC_DRIVING_CTRL);
writedata(0x01);writedata(0x00); // set 1 line inversion
writedata(0x01);writedata(0x00);
writecommand(ILI9225_DISP_CTRL1);
writedata(0x00);writedata(0x00); // Display off
writedata(0x00);writedata(0x00);
writecommand(ILI9225_BLANK_PERIOD_CTRL1);
writedata(0x08);writedata(0x08); // set the back porch and front porch
writedata(0x08);writedata(0x08);
writecommand(ILI9225_FRAME_CYCLE_CTRL);
writedata(0x11);writedata(0x00); // set the clocks number per line
writedata(0x11);writedata(0x00);
writecommand(ILI9225_INTERFACE_CTRL);
writedata(0x00);writedata(0x00); // CPU interface
writedata(0x00);writedata(0x00);
writecommand(ILI9225_OSC_CTRL);
writedata(0x0D);writedata(0x01); // Set Osc /*0e01*/
writedata(0x0D);writedata(0x01);
writecommand(ILI9225_VCI_RECYCLING);
writedata(0x00);writedata(0x20); // Set VCI recycling
writedata(0x00);writedata(0x20);
writecommand(ILI9225_RAM_ADDR_SET1);
writedata(0x00);writedata(0x00); // RAM Address
writedata(0x00);writedata(0x00);
writecommand(ILI9225_RAM_ADDR_SET2);
writedata(0x00);writedata(0x00); // RAM Address
writedata(0x00);writedata(0x00);
/* Set GRAM area */
writecommand(ILI9225_GATE_SCAN_CTRL);
writedata(0x00);writedata(0x00);
writecommand(ILI9225_VERTICAL_SCROLL_CTRL1);
@ -106,9 +97,9 @@
writecommand(ILI9225_DISP_CTRL1);
writedata(0x00);writedata(0x12);
spi_end();
delay(50);
spi_begin();
writecommand(ILI9225_DISP_CTRL1);
writedata(0x10);writedata(0x17);
}

View File

@ -8,7 +8,7 @@
writecommand(ILI9225_DRIVER_OUTPUT_CTRL);
writedata(0x01);writedata(0x1C);
writecommand(ILI9225_ENTRY_MODE);
writedata(TFT_MAD_BGR);writedata(0x30);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x30);
_width = _init_width;
_height = _init_height;
break;
@ -16,7 +16,7 @@
writecommand(ILI9225_DRIVER_OUTPUT_CTRL);
writedata(0x00);writedata(0x1C);
writecommand(ILI9225_ENTRY_MODE);
writedata(TFT_MAD_BGR);writedata(0x38);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x38);
_width = _init_height;
_height = _init_width;
break;
@ -24,7 +24,7 @@
writecommand(ILI9225_DRIVER_OUTPUT_CTRL);
writedata(0x02);writedata(0x1C);
writecommand(ILI9225_ENTRY_MODE);
writedata(TFT_MAD_BGR);writedata(0x30);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x30);
_width = _init_width;
_height = _init_height;
break;
@ -32,7 +32,7 @@
writecommand(ILI9225_DRIVER_OUTPUT_CTRL);
writedata(0x03);writedata(0x1C);
writecommand(ILI9225_ENTRY_MODE);
writedata(TFT_MAD_BGR);writedata(0x38);
writedata(TFT_MAD_COLOR_ORDER);writedata(0x38);
_width = _init_height;
_height = _init_width;
break;

View File

@ -57,11 +57,13 @@ inline void TFT_eSPI::begin_tft_write(void){
locked = false;
spi.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, TFT_SPI_MODE));
CS_L;
SET_BUS_WRITE_MODE
}
#else
CS_L;
#endif
SET_BUS_WRITE_MODE;
#endif
}
/***************************************************************************************
@ -76,10 +78,10 @@ inline void TFT_eSPI::end_tft_write(void){
CS_H;
spi.endTransaction();
}
SET_BUS_READ_MODE;
}
SET_BUS_READ_MODE;
#else
if(!inTransaction) {CS_H;}
if(!inTransaction) {CS_H; SET_BUS_READ_MODE;}
#endif
}
@ -111,26 +113,25 @@ inline void TFT_eSPI::begin_tft_read(void){
***************************************************************************************/
void TFT_eSPI::setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDatum)
{
// Viewport
// Viewport metrics (not clipped)
_xDatum = x; // Datum x position in screen coordinates
_yDatum = y; // Datum y position in screen coordinates
_xWidth = w; // Viewport width
_yHeight = h; // Viewport height
// Clipped viewport
_vpX = 0; // Viewport top left corner x coordinate
_vpY = 0; // Viewport top left corner y coordinate
_vpW = _width; // Equivalent of TFT width (Nb: viewport right edge coord + 1)
_vpH = _height; // Equivalent of TFT height (Nb: viewport bottom edge coord + 1)
// Full size default viewport
_vpDatum = false; // Datum is at top left corner of screen (true = top left of viewport)
_vpOoB = false; // Out of Bounds flag (true is all of viewport is off screen)
_vpOoB = false; // Out of Bounds flag (true is all of viewport is off screen)
_vpX = 0; // Viewport top left corner x coordinate
_vpY = 0; // Viewport top left corner y coordinate
_vpW = width(); // Equivalent of TFT width (Nb: viewport right edge coord + 1)
_vpH = height(); // Equivalent of TFT height (Nb: viewport bottom edge coord + 1)
// Clip viewport to screen area
if (x<0) { w += x; x = 0; }
if (y<0) { h += y; y = 0; }
if ((x + w) > _width ) { w = _width - x; }
if ((y + h) > _height) { h = _height - y; }
if ((x + w) > width() ) { w = width() - x; }
if ((y + h) > height() ) { h = height() - y; }
//Serial.print(" x=");Serial.print( x);Serial.print(", y=");Serial.print( y);
//Serial.print(", w=");Serial.print(w);Serial.print(", h=");Serial.println(h);
@ -141,21 +142,21 @@ void TFT_eSPI::setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDa
// Set default values and Out of Bounds flag in case of error
_xDatum = 0;
_yDatum = 0;
_xWidth = _width;
_yHeight = _height;
_xWidth = width();
_yHeight = height();
_vpOoB = true; // Set Out of Bounds flag to inhibit all drawing
return;
}
if (!vpDatum)
{
_xDatum = 0; // Reset to top left of screen if not useing a viewport datum
_xDatum = 0; // Reset to top left of screen if not using a viewport datum
_yDatum = 0;
_xWidth = _width;
_yHeight = _height;
_xWidth = width();
_yHeight = height();
}
// Store the on screen viewport metrics and datum position
// Store the clipped screen viewport metrics and datum position
_vpX = x;
_vpY = y;
_vpW = x + w;
@ -205,23 +206,22 @@ bool TFT_eSPI::checkViewport(int32_t x, int32_t y, int32_t w, int32_t h)
***************************************************************************************/
void TFT_eSPI::resetViewport(void)
{
// Reset viewport to the whole screen
// Reset viewport to the whole screen (or sprite) area
_vpDatum = false;
_vpOoB = false;
_xDatum = 0;
_yDatum = 0;
_vpX = 0;
_vpY = 0;
_vpW = _width;
_vpH = _height;
_xWidth = _width;
_yHeight = _height;
_vpDatum = false;
_vpOoB = false;
_vpW = width();
_vpH = height();
_xWidth = width();
_yHeight = height();
}
/***************************************************************************************
** Function name: getViewportX
** Description: Get x position of the viewport
** Description: Get x position of the viewport datum
***************************************************************************************/
int32_t TFT_eSPI::getViewportX(void)
{
@ -230,7 +230,7 @@ int32_t TFT_eSPI::getViewportX(void)
/***************************************************************************************
** Function name: getViewportY
** Description: Get y position of the viewport
** Description: Get y position of the viewport datum
***************************************************************************************/
int32_t TFT_eSPI::getViewportY(void)
{
@ -243,7 +243,7 @@ int32_t TFT_eSPI::getViewportY(void)
***************************************************************************************/
int32_t TFT_eSPI::getViewportWidth(void)
{
return _vpW - _vpX;
return _xWidth;
}
/***************************************************************************************
@ -252,12 +252,12 @@ int32_t TFT_eSPI::getViewportWidth(void)
***************************************************************************************/
int32_t TFT_eSPI::getViewportHeight(void)
{
return _vpH - _vpY;
return _yHeight;
}
/***************************************************************************************
** Function name: getViewportDatum
** Description: Get datum of the viewport (true = viewport corner)
** Description: Get datum flag of the viewport (true = viewport corner)
***************************************************************************************/
bool TFT_eSPI::getViewportDatum(void)
{
@ -270,37 +270,52 @@ bool TFT_eSPI::getViewportDatum(void)
***************************************************************************************/
void TFT_eSPI::frameViewport(uint16_t color, int32_t w)
{
// Save datum position
bool _dT = _vpDatum;
// If w is positive the frame is drawn inside the viewport
// a large positive width will clear the screen inside the viewport
if (w>0)
{
fillRect(_vpX, _vpY, _vpW - _vpX, w, color);
fillRect(_vpX, _vpY + w, w, _vpH - _vpY - w - w, color);
fillRect(_vpW - w, _vpY + w, w, _vpH - _vpY - w - w, color);
fillRect(_vpX, _vpH - w, _vpW - _vpX, w, color);
// Set vpDatum true to simplify coordinate derivation
_vpDatum = true;
fillRect(0, 0, _vpW - _vpX, w, color); // Top
fillRect(0, w, w, _vpH - _vpY - w - w, color); // Left
fillRect(_xWidth - w, w, w, _yHeight - w - w, color); // Right
fillRect(0, _yHeight - w, _xWidth, w, color); // Bottom
}
else
// If w is negative the frame is drawn outside the viewport
// a large negative width will clear the screen outside the viewport
{
w = -w;
int32_t _xTemp = _vpX; _vpX = 0;
int32_t _yTemp = _vpY; _vpY = 0;
int32_t _wTemp = _vpW; _vpW = _width;
int32_t _hTemp = _vpH; _vpH = _height;
bool _dTemp = _vpDatum; _vpDatum = false;
// Save old values
int32_t _xT = _vpX; _vpX = 0;
int32_t _yT = _vpY; _vpY = 0;
int32_t _wT = _vpW;
int32_t _hT = _vpH;
fillRect(_xTemp - _xDatum, _yTemp - w - _yDatum, _wTemp - _xTemp + w + w, w, color);
fillRect(_xTemp - w - _xDatum, _yTemp - _yDatum, w, _hTemp - _yTemp, color);
fillRect(_wTemp - _xDatum, _yTemp - _yDatum, w, _hTemp - _yTemp, color);
fillRect(_xTemp - w - _xDatum, _hTemp - _yDatum, _wTemp - _xTemp + w + w, w, color);
// Set vpDatum false so frame can be drawn outside window
_vpDatum = false; // When false the full width and height is accessed
_vpH = height();
_vpW = width();
_vpX = _xTemp;
_vpY = _yTemp;
_vpW = _wTemp;
_vpH = _hTemp;
_vpDatum = _dTemp;
// Draw frame
fillRect(_xT - w - _xDatum, _yT - w - _yDatum, _wT - _xT + w + w, w, color); // Top
fillRect(_xT - w - _xDatum, _yT - _yDatum, w, _hT - _yT, color); // Left
fillRect(_wT - _xDatum, _yT - _yDatum, w, _hT - _yT, color); // Right
fillRect(_xT - w - _xDatum, _hT - _yDatum, _wT - _xT + w + w, w, color); // Bottom
// Restore old values
_vpX = _xT;
_vpY = _yT;
_vpW = _wT;
_vpH = _hT;
}
// Restore vpDatum
_vpDatum = _dT;
}
/***************************************************************************************
@ -438,8 +453,8 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
addr_row = 0xFFFF;
addr_col = 0xFFFF;
_xpivot = 0;
_ypivot = 0;
_xPivot = 0;
_yPivot = 0;
cspinmask = 0;
dcpinmask = 0;
@ -1365,6 +1380,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
begin_tft_write();
inTransaction = true;
bool swap = _swapBytes;
setWindow(x, y, x + dw - 1, y + dh - 1); // Sets CS low and sent RAMWR
@ -1373,7 +1389,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
if (bpp8)
{
bool swap = _swapBytes; _swapBytes = false;
_swapBytes = false;
uint8_t blue[] = {0, 11, 21, 31}; // blue 2 to 5 bit colour lookup table
@ -1413,7 +1429,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
}
else if (cmap != nullptr) // Must be 4bpp
{
bool swap = _swapBytes; _swapBytes = true;
_swapBytes = true;
w = (w+1) & 0xFFFE; // if this is a sprite, w will already be even; this does no harm.
bool splitFirst = (dx & 0x01) != 0; // split first means we have to push a single px from the left of the sprite / image
@ -1464,35 +1480,24 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
}
else // Must be 1bpp
{
bool swap = _swapBytes; _swapBytes = false;
while (dh--) {
w = (w+7) & 0xFFF8;
_swapBytes = false;
int32_t len = dw;
uint8_t* ptr = data;
uint32_t ww = (w+7)>>3; // Width of source image line in bytes
for (int32_t yp = dy; yp < dy + dh; yp++)
{
uint8_t* linePtr = (uint8_t*)lineBuf;
uint8_t bits = 8;
while(len>0) {
if (len < 8) bits = len;
uint32_t xp = dx;
for (uint16_t i = 0; i < bits; i++) {
uint8_t col = (ptr[(xp + dy * w)>>3] << (xp & 0x7)) & 0x80;
if (col) {*linePtr++ = bitmap_fg>>8; *linePtr++ = (uint8_t) bitmap_fg;}
else {*linePtr++ = bitmap_bg>>8; *linePtr++ = (uint8_t) bitmap_bg;}
//if (col) drawPixel((dw-len)+xp,h-dh,bitmap_fg);
//else drawPixel((dw-len)+xp,h-dh,bitmap_bg);
xp++;
}
ptr++;
len -= 8;
for (int32_t xp = dx; xp < dx + dw; xp++)
{
uint16_t col = (data[(xp>>3)] & (0x80 >> (xp & 0x7)) );
if (col) {*linePtr++ = bitmap_fg>>8; *linePtr++ = (uint8_t) bitmap_fg;}
else {*linePtr++ = bitmap_bg>>8; *linePtr++ = (uint8_t) bitmap_bg;}
}
data += ww;
pushPixels(lineBuf, dw);
dy++;
}
_swapBytes = swap; // Restore old value
}
_swapBytes = swap; // Restore old value
inTransaction = false;
end_tft_write();
}
@ -1508,6 +1513,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
begin_tft_write();
inTransaction = true;
bool swap = _swapBytes;
int32_t xe = x + dw - 1, ye = y + dh - 1;
@ -1515,7 +1521,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
uint16_t lineBuf[dw];
if (bpp8) { // 8 bits per pixel
bool swap = _swapBytes; _swapBytes = false;
_swapBytes = false;
data += dx + dy * w;
@ -1527,8 +1533,6 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
uint8_t msbColor = 0;
uint8_t lsbColor = 0;
//int32_t spx = x, spy = y;
while (dh--) {
int32_t len = dw;
uint8_t* ptr = data;
@ -1571,11 +1575,10 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
y++;
data += w;
}
_swapBytes = swap; // Restore old value
}
else if (cmap != nullptr) // 4bpp with color map
{
bool swap = _swapBytes; _swapBytes = true;
_swapBytes = true;
w = (w+1) & 0xFFFE; // here we try to recreate iwidth from dwidth.
bool splitFirst = ((dx & 0x01) != 0);
@ -1662,52 +1665,41 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
data += (w>>1);
y++;
}
_swapBytes = swap; // Restore old value
}
else { // 1 bit per pixel
bool swap = _swapBytes; _swapBytes = false;
w = (w+7) & 0xFFF8;
while (dh--) {
_swapBytes = false;
uint32_t ww = (w+7)>>3; // Width of source image line in bytes
uint16_t np = 0;
for (int32_t yp = dy; yp < dy + dh; yp++)
{
int32_t px = x;
bool move = true;
uint16_t np = 0;
int32_t len = dw;
uint8_t* ptr = data;
uint8_t bits = 8;
while(len>0) {
if (len < 8) bits = len;
uint32_t xp = dx;
uint32_t yp = (dy * w)>>3;
for (uint16_t i = 0; i < bits; i++) {
//uint8_t col = (ptr[(xp + dy * w)>>3] << (xp & 0x7)) & 0x80;
if ((ptr[(xp>>3) + yp] << (xp & 0x7)) & 0x80) {
if (move) {
move = false;
setWindow(px, y, xe, ye);
}
np++;
for (int32_t xp = dx; xp < dx + dw; xp++)
{
if (data[(xp>>3)] & (0x80 >> (xp & 0x7))) {
if (move) {
move = false;
setWindow(px, y, xe, ye);
}
else {
if (np) {
pushBlock(bitmap_fg, np);
np = 0;
move = true;
}
}
px++;
xp++;
np++;
}
ptr++;
len -= 8;
else {
if (np) {
pushBlock(bitmap_fg, np);
np = 0;
move = true;
}
}
px++;
}
if (np) pushBlock(bitmap_fg, np);
y++;
dy++;
data += ww;
if (np) { pushBlock(bitmap_fg, np); np = 0; }
}
_swapBytes = swap; // Restore old value
}
_swapBytes = swap; // Restore old value
inTransaction = false;
end_tft_write();
}
@ -2427,8 +2419,8 @@ void TFT_eSPI::setTextColor(uint16_t c, uint16_t b)
*************************************************************************************x*/
void TFT_eSPI::setPivot(int16_t x, int16_t y)
{
_xpivot = x;
_ypivot = y;
_xPivot = x;
_yPivot = y;
}
@ -2438,7 +2430,7 @@ void TFT_eSPI::setPivot(int16_t x, int16_t y)
***************************************************************************************/
int16_t TFT_eSPI::getPivotX(void)
{
return _xpivot;
return _xPivot;
}
@ -2448,7 +2440,7 @@ int16_t TFT_eSPI::getPivotX(void)
***************************************************************************************/
int16_t TFT_eSPI::getPivotY(void)
{
return _ypivot;
return _yPivot;
}
@ -2529,7 +2521,8 @@ uint8_t TFT_eSPI::getTextDatum(void)
// Return the size of the display (per current rotation)
int16_t TFT_eSPI::width(void)
{
return _xWidth;
if (_vpDatum) return _xWidth;
return _width;
}
@ -2539,7 +2532,8 @@ int16_t TFT_eSPI::width(void)
***************************************************************************************/
int16_t TFT_eSPI::height(void)
{
return _yHeight;
if (_vpDatum) return _yHeight;
return _height;
}
@ -2846,6 +2840,32 @@ void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t w, int32_t h)
void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{
//begin_tft_write(); // Must be called before setWindow
#if defined (ILI9225_DRIVER)
if (rotation & 0x01) { swap_coord(x0, y0); swap_coord(x1, y1); }
addr_row = 0xFFFF;
addr_col = 0xFFFF;
DC_C; tft_Write_8(TFT_CASET1);
DC_D; tft_Write_16(x0);
DC_C; tft_Write_8(TFT_CASET2);
DC_D; tft_Write_16(x1);
DC_C; tft_Write_8(TFT_PASET1);
DC_D; tft_Write_16(y0);
DC_C; tft_Write_8(TFT_PASET2);
DC_D; tft_Write_16(y1);
DC_C; tft_Write_8(TFT_RAM_ADDR1);
DC_D; tft_Write_16(x0);
DC_C; tft_Write_8(TFT_RAM_ADDR2);
DC_D; tft_Write_16(y0);
// write to RAM
DC_C; tft_Write_8(TFT_RAMWR);
DC_D;
#else
#if defined (SSD1963_DRIVER)
if ((rotation & 0x1) == 0) { swap_coord(x0, y0); swap_coord(x1, y1); }
@ -2869,6 +2889,7 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
DC_D;
//end_tft_write(); // Must be called after setWindow
#endif
}
@ -2925,7 +2946,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
x+= _xDatum;
y+= _yDatum;
// Range checking
// Range checking
if ((x < _vpX) || (y < _vpY) ||(x >= _vpW) || (y >= _vpH)) return;
#ifdef CGRAM_OFFSET
@ -2933,12 +2954,42 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
y+=rowstart;
#endif
begin_tft_write();
#if defined (ILI9225_DRIVER)
if (rotation & 0x01) { swap_coord(x, y); }
// Set window to full screen to optimise sequential pixel rendering
if (addr_row != 0x9225) {
addr_row = 0x9225; // addr_row used for flag
DC_C; tft_Write_8(TFT_CASET1);
DC_D; tft_Write_16(0);
DC_C; tft_Write_8(TFT_CASET2);
DC_D; tft_Write_16(175);
DC_C; tft_Write_8(TFT_PASET1);
DC_D; tft_Write_16(0);
DC_C; tft_Write_8(TFT_PASET2);
DC_D; tft_Write_16(219);
}
// Define pixel coordinate
DC_C; tft_Write_8(TFT_RAM_ADDR1);
DC_D; tft_Write_16(x);
DC_C; tft_Write_8(TFT_RAM_ADDR2);
DC_D; tft_Write_16(y);
// write to RAM
DC_C; tft_Write_8(TFT_RAMWR);
DC_D; tft_Write_16(color);
#else
#if defined (SSD1963_DRIVER)
if ((rotation & 0x1) == 0) { swap_coord(x, y); }
#endif
begin_tft_write();
#ifdef MULTI_TFT_SUPPORT
// No optimisation
DC_C; tft_Write_8(TFT_CASET);
@ -2960,9 +3011,9 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
addr_row = (y<<16 | y);
}
#endif
DC_C; tft_Write_8(TFT_RAMWR);
DC_D; tft_Write_16(color);
#endif
end_tft_write();
}
@ -3064,9 +3115,14 @@ void TFT_eSPI::pushColors(uint16_t *data, uint32_t len, bool swap)
// an efficient FastH/V Line draw routine for line segments of 2 pixels or more
void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color)
{
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
if (_vpOoB) return;
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
//x+= _xDatum; // Not added here, added by drawPixel & drawFastXLine
//y+= _yDatum;
bool steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
swap_coord(x0, y0);
@ -3507,30 +3563,20 @@ uint32_t TFT_eSPI::alphaBlend24(uint8_t alpha, uint32_t fgc, uint32_t bgc, uint8
***************************************************************************************/
size_t TFT_eSPI::write(uint8_t utf8)
{
if (_vpOoB) return 1;
uint16_t uniCode = decodeUTF8(utf8);
if (!uniCode) return 1;
if (utf8 == '\r') return 1;
uint16_t uniCode = utf8;
if (_utf8) uniCode = decodeUTF8(utf8);
if (uniCode == 0) return 1;
#ifdef SMOOTH_FONT
if(fontLoaded) {
//Serial.print("UniCode="); Serial.println(uniCode);
//Serial.print("UTF8 ="); Serial.println(utf8);
//fontFile = SPIFFS.open( _gFontFilename, "r" );
//if(!fontFile)
//{
// fontLoaded = false;
// return 1;
//}
if (uniCode < 32 && utf8 != '\n') return 1;
drawGlyph(uniCode);
//fontFile.close();
return 1;
}
#endif
@ -3538,8 +3584,8 @@ size_t TFT_eSPI::write(uint8_t utf8)
if (uniCode == '\n') uniCode+=22; // Make it a valid space character to stop errors
else if (uniCode < 32) return 1;
uint16_t width = 0;
uint16_t height = 0;
uint16_t cwidth = 0;
uint16_t cheight = 0;
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv DEBUG vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//Serial.print((uint8_t) uniCode); // Debug line sends all printed TFT text to serial port
@ -3557,11 +3603,11 @@ size_t TFT_eSPI::write(uint8_t utf8)
if (textfont == 2) {
if (uniCode > 127) return 1;
width = pgm_read_byte(widtbl_f16 + uniCode-32);
height = chr_hgt_f16;
cwidth = pgm_read_byte(widtbl_f16 + uniCode-32);
cheight = chr_hgt_f16;
// Font 2 is rendered in whole byte widths so we must allow for this
width = (width + 6) / 8; // Width in whole bytes for font 2, should be + 7 but must allow for font width change
width = width * 8; // Width converted back to pixels
cwidth = (cwidth + 6) / 8; // Width in whole bytes for font 2, should be + 7 but must allow for font width change
cwidth = cwidth * 8; // Width converted back to pixels
}
#ifdef LOAD_RLE
else
@ -3573,33 +3619,33 @@ size_t TFT_eSPI::write(uint8_t utf8)
if ((textfont>2) && (textfont<9)) {
if (uniCode > 127) return 1;
// Uses the fontinfo struct array to avoid lots of 'if' or 'switch' statements
width = pgm_read_byte( (uint8_t *)pgm_read_dword( &(fontdata[textfont].widthtbl ) ) + uniCode-32 );
height= pgm_read_byte( &fontdata[textfont].height );
cwidth = pgm_read_byte( (uint8_t *)pgm_read_dword( &(fontdata[textfont].widthtbl ) ) + uniCode-32 );
cheight= pgm_read_byte( &fontdata[textfont].height );
}
}
#endif
#ifdef LOAD_GLCD
if (textfont==1) {
width = 6;
height = 8;
cwidth = 6;
cheight = 8;
}
#else
if (textfont==1) return 1;
#endif
height = height * textsize;
cheight = cheight * textsize;
if (utf8 == '\n') {
cursor_y += height;
cursor_y += cheight;
cursor_x = 0;
}
else {
if (textwrapX && (cursor_x + width * textsize > this->width())) {
cursor_y += height;
if (textwrapX && (cursor_x + cwidth * textsize > width())) {
cursor_y += cheight;
cursor_x = 0;
}
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
if (textwrapY && (cursor_y >= (int32_t) height())) cursor_y = 0;
cursor_x += drawChar(uniCode, cursor_x, cursor_y, textfont);
}
@ -3609,10 +3655,8 @@ size_t TFT_eSPI::write(uint8_t utf8)
else {
if(utf8 == '\n') {
cursor_x = 0;
cursor_y += (int16_t)textsize *
(uint8_t)pgm_read_byte(&gfxFont->yAdvance);
}
else {
cursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
} else {
if (uniCode > pgm_read_word(&gfxFont->last )) return 1;
if (uniCode < pgm_read_word(&gfxFont->first)) return 1;
@ -3622,13 +3666,12 @@ size_t TFT_eSPI::write(uint8_t utf8)
h = pgm_read_byte(&glyph->height);
if((w > 0) && (h > 0)) { // Is there an associated bitmap?
int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset);
if(textwrapX && ((cursor_x + textsize * (xo + w)) > this->width())) {
if(textwrapX && ((cursor_x + textsize * (xo + w)) > width())) {
// Drawing character would go off right edge; wrap to new line
cursor_x = 0;
cursor_y += (int16_t)textsize *
(uint8_t)pgm_read_byte(&gfxFont->yAdvance);
cursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
}
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
if (textwrapY && (cursor_y >= (int32_t) height())) cursor_y = 0;
drawChar(cursor_x, cursor_y, uniCode, textcolor, textbgcolor, textsize);
}
cursor_x += pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize;
@ -3645,6 +3688,7 @@ size_t TFT_eSPI::write(uint8_t utf8)
** Function name: drawChar
** Description: draw a Unicode glyph onto the screen
***************************************************************************************/
// TODO: Rationalise with TFT_eSprite
// Any UTF-8 decoding must be done before calling drawChar()
int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y)
{
@ -4087,11 +4131,11 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
/*
// The above only works for a single text line, not if the text is going to wrap...
// So need to use code like this in a while loop to fix it:
if (textwrapX && (cursor_x + width * textsize > this->width())) {
if (textwrapX && (cursor_x + width * textsize > width())) {
cursor_y += height;
cursor_x = 0;
}
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
if (textwrapY && (cursor_y >= (int32_t)height())) cursor_y = 0;
cursor_x += drawChar(uniCode, cursor_x, cursor_y, textfont);
*/
setCursor(poX, poY);

View File

@ -9,14 +9,14 @@
The built-in fonts 4, 6, 7 and 8 are Run Length
Encoded (RLE) to reduce the FLASH footprint.
Last review/edit by Bodmer: 26/01/20
Last review/edit by Bodmer: 01/12/20
****************************************************/
// Stop fonts etc being loaded multiple times
#ifndef _TFT_eSPIH_
#define _TFT_eSPIH_
#define TFT_ESPI_VERSION "2.3.42"
#define TFT_ESPI_VERSION "2.3.5"
// Bit level feature flags
// Bit 0 set: viewport capability
@ -360,7 +360,7 @@ swap_coord(T& a, T& b) { T t = a; a = b; b = t; }
typedef uint16_t (*getColorCallback)(uint16_t x, uint16_t y);
// Class functions and variables
class TFT_eSPI : public Print {
class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has access to protected members
//--------------------------------------- public ------------------------------------//
public:
@ -662,7 +662,6 @@ class TFT_eSPI : public Print {
// Global variables
static SPIClass& getSPIinstance(void); // Get SPI class handle
int32_t cursor_x, cursor_y, padX; // Text cursor x,y and padding setting
uint32_t textcolor, textbgcolor; // Text foreground and background colours
uint32_t bitmap_fg, bitmap_bg; // Bitmap foreground (bit=1) and background (bit=0) colours
@ -672,9 +671,6 @@ class TFT_eSPI : public Print {
textdatum, // Text reference datum
rotation; // Display rotation (0-3)
int16_t _xpivot; // TFT x pivot point coordinate for rotated Sprites
int16_t _ypivot; // TFT x pivot point coordinate for rotated Sprites
uint8_t decoderState = 0; // UTF8 decoder state - not for user access
uint16_t decoderBuffer; // Unicode code-point buffer - not for user access
@ -743,6 +739,9 @@ class TFT_eSPI : public Print {
int32_t _width, _height; // Display w/h as modified by current rotation
int32_t addr_row, addr_col; // Window position - used to minimise window commands
int16_t _xPivot; // TFT x pivot point coordinate for rotated Sprites
int16_t _yPivot; // TFT x pivot point coordinate for rotated Sprites
// Viewport variables
int32_t _vpX, _vpY, _vpW, _vpH; // Note: x start, y start, x end + 1, y end + 1
int32_t _xDatum;
@ -752,6 +751,8 @@ class TFT_eSPI : public Print {
bool _vpDatum;
bool _vpOoB;
int32_t cursor_x, cursor_y, padX; // Text cursor x,y and padding setting
uint32_t fontsloaded; // Bit field of fonts loaded
uint8_t glyph_ab, // Smooth font glyph delta Y (height) above baseline

View File

@ -50,9 +50,10 @@
//#define R61581_DRIVER
//#define RM68140_DRIVER
//#define ST7796_DRIVER
//#define SSD1963_480_DRIVER // Untested
//#define SSD1963_800_DRIVER // Untested
//#define SSD1963_800ALT_DRIVER // Untested
//#define SSD1963_480_DRIVER
//#define SSD1963_800_DRIVER
//#define SSD1963_800ALT_DRIVER
//#define ILI9225_DRIVER
// Some displays support SPI reads via the MISO pin, other displays have a single
// bi-directional SDA pin and the library will try to read this via the MOSI line.

View File

@ -1,7 +1,8 @@
// For ESP8266
// See SetupX_Template.h for all options available
#define RPI_DISPLAY_TYPE
#define ILI9486_DRIVER // 20MHz maximum SPI
#define ILI9486_DRIVER
// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation
#define TFT_CS PIN_D2 // Chip select control pin D2
@ -23,7 +24,7 @@
#define SMOOTH_FONT
#define SPI_FREQUENCY 16000000
#define SPI_FREQUENCY 16000000 // Some displays will operate at higher frequencies
#define SPI_TOUCH_FREQUENCY 2500000

View File

@ -1,6 +1,7 @@
// For ESP32
// See SetupX_Template.h for all options available
#define RPI_DISPLAY_TYPE
#define ILI9486_DRIVER // 20MHz maximum SPI
#define ILI9486_DRIVER
#define TFT_MISO 19
#define TFT_MOSI 23
@ -24,6 +25,6 @@
#define SMOOTH_FONT
#define SPI_FREQUENCY 20000000
#define SPI_FREQUENCY 20000000 // Some displays will operate at higher frequencies
#define SPI_TOUCH_FREQUENCY 2500000

View File

@ -6,21 +6,6 @@
In a 1 bit Sprite any colour except TFT_BLACK turns a pixel "ON"
TFT_BLACK turns a pixel "OFF".
The 1 bpp Sprite has a unique property that other bit depth Sprites
do not have, you can set the rotation of the coordinate frame e.g.:
spr.setRotation(1);
This is similar to screen rotations, so for example text can
be drawn rotated:
Rotation 0: Normal orientation
Rotation 1: Coordinate frame rotated clockwise 90 degrees
Rotation 2: Coordinate frame rotated clockwise 180 degrees (upside down)
Rotation 3: Coordinate frame rotated clockwise 270 degrees
When pushSprite is used the sprite is drawn with the width and height
staying as created, so the created Sprite itself is not rotated during
rendering. See stext2 sprite example below at line 83.
ON and OFF pixels can be set to any two colours before
rendering to the screen with pushSprite, for example:
tft.setBitmapColor(ON_COLOR, OFF_COLOR);
@ -83,8 +68,7 @@ void setup() {
// Create a sprite for Hello World
stext2.setColorDepth(1);
stext2.createSprite(16, 80); // Narrow and tall
stext2.setRotation(1); // Plot with 90 deg. clockwise rotation
stext2.createSprite(80, 16);
stext2.fillSprite(TFT_BLACK);
stext2.setScrollRect(0, 0, 40, 16, TFT_BLACK); // Scroll the "Hello" in the first 40 pixels
stext2.setTextColor(TFT_WHITE); // White text, no background

View File

@ -1,6 +1,6 @@
{
"name": "TFT_eSPI",
"version": "2.3.42",
"version": "2.3.5",
"keywords": "Arduino, tft, ePaper, display, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140",
"description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32",
"repository":

View File

@ -1,5 +1,5 @@
name=TFT_eSPI
version=2.3.42
version=2.3.5
author=Bodmer
maintainer=Bodmer
sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32