diff --git a/Extensions/Smooth_font.cpp b/Extensions/Smooth_font.cpp index dc41edb..b5559e1 100644 --- a/Extensions/Smooth_font.cpp +++ b/Extensions/Smooth_font.cpp @@ -338,6 +338,8 @@ uint16_t TFT_eSPI::alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc) uint16_t b = (((fgB * alpha) + (bgB * (255 - alpha))) >> 9); // Combine RGB565 colours into 16 bits + //return ((r&0x18) << 11) | ((g&0x30) << 5) | ((b&0x18) << 0); // 2 bit greyscale + //return ((r&0x1E) << 11) | ((g&0x3C) << 5) | ((b&0x1E) << 0); // 4 bit greyscale return (r << 11) | (g << 5) | (b << 0); } @@ -419,7 +421,10 @@ void TFT_eSPI::drawGlyph(uint16_t code) uint8_t pbuffer[gWidth[gNum]]; uint16_t xs = 0; - uint16_t dl = 0; + uint32_t dl = 0; + + int16_t cy = cursor_y + gFont.maxAscent - gdY[gNum]; + int16_t cx = cursor_x + gdX[gNum]; for (int y = 0; y < gHeight[gNum]; y++) { @@ -431,24 +436,27 @@ void TFT_eSPI::drawGlyph(uint16_t code) { if (pixel != 0xFF) { - if (dl) { drawFastHLine( xs, y + cursor_y + gFont.maxAscent - gdY[gNum], dl, fg); dl = 0; } - drawPixel(x + cursor_x + gdX[gNum], y + cursor_y + gFont.maxAscent - gdY[gNum], alphaBlend(pixel, fg, bg)); + if (dl) { + if (dl==1) drawPixel(xs, y + cy, fg); + else drawFastHLine( xs, y + cy, dl, fg); + dl = 0; + } + drawPixel(x + cx, y + cy, alphaBlend(pixel, fg, bg)); } else { - if (dl==0) xs = x + cursor_x + gdX[gNum]; + if (dl==0) xs = x + cx; dl++; } } else { - if (dl) { drawFastHLine( xs, y + cursor_y + gFont.maxAscent - gdY[gNum], dl, fg); dl = 0; } + if (dl) { drawFastHLine( xs, y + cy, dl, fg); dl = 0; } } } - if (dl) { drawFastHLine( xs, y + cursor_y + gFont.maxAscent - gdY[gNum], dl, fg); dl = 0; } + if (dl) { drawFastHLine( xs, y + cy, dl, fg); dl = 0; } } - cursor_x += gxAdvance[gNum]; } else diff --git a/Fonts/Font72x53rle.c b/Fonts/Font72x53rle.c new file mode 100644 index 0000000..bcce9cb --- /dev/null +++ b/Fonts/Font72x53rle.c @@ -0,0 +1,247 @@ +// Font 8 +// +// This font has been 8 bit Run Length Encoded to save FLASH space +// +// It is a Arial 75 pixel height font intended to display large numbers +// Width for numerals reduced from 55 to 53 (to fit in 160 pixel screens) +// This font only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : - . +// All other characters print as a space + +#include + + +PROGMEM const unsigned char widtbl_f72[96] = // character width table +{ + 29, 29, 29, 29, 29, 29, 29, 29, // char 32 - 39 + 29, 29, 29, 29, 29, 29, 29, 29, // char 40 - 47 + 53, 53, 53, 53, 53, 53, 53, 53, // char 48 - 55 + 53, 53, 29, 29, 29, 29, 29, 29, // char 56 - 63 + 29, 29, 29, 29, 29, 29, 29, 29, // char 64 - 71 + 29, 29, 29, 29, 29, 29, 29, 29, // char 72 - 79 + 29, 29, 29, 29, 29, 29, 29, 29, // char 80 - 87 + 29, 29, 29, 29, 29, 29, 29, 29, // char 88 - 95 + 29, 29, 29, 29, 29, 29, 29, 29, // char 96 - 103 + 29, 29, 29, 29, 29, 29, 29, 29, // char 104 - 111 + 29, 29, 29, 29, 29, 29, 29, 29, // char 112 - 119 + 29, 29, 29, 29, 29, 29, 29, 29 // char 120 - 127 +}; + +// Row format, MSB left + +PROGMEM const unsigned char chr_f72_20[] = +{ +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +0x7E +}; + +PROGMEM const unsigned char chr_f72_2D[] = +{ +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +0x36, 0x91, 0x0A, 0x91, 0x0A, 0x91, 0x0A, 0x91, +0x0A, 0x91, 0x0A, 0x91, 0x0A, 0x91, 0x7F, 0x7F, +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x07 +}; + +PROGMEM const unsigned char chr_f72_2E[] = +{ +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x48, 0x88, +0x13, 0x88, 0x13, 0x88, 0x13, 0x88, 0x13, 0x88, +0x13, 0x88, 0x13, 0x88, 0x13, 0x88, 0x13, 0x88, +0x44 +}; + +PROGMEM const unsigned char chr_f72_30[] = +{ +0x7F, 0x68, 0x8A, 0x26, 0x90, 0x21, 0x94, 0x1D, 0x98, 0x1A, 0x9A, 0x18, 0x9C, 0x16, 0x9E, 0x14, +0xA0, 0x13, 0x8C, 0x06, 0x8C, 0x12, 0x8B, 0x0A, 0x8B, 0x10, 0x8A, 0x0E, 0x89, 0x10, 0x89, 0x10, +0x89, 0x0F, 0x88, 0x12, 0x88, 0x0E, 0x89, 0x12, 0x89, 0x0D, 0x88, 0x14, 0x88, 0x0C, 0x89, 0x14, +0x88, 0x0C, 0x88, 0x16, 0x88, 0x0B, 0x88, 0x16, 0x88, 0x0B, 0x88, 0x16, 0x88, 0x0A, 0x88, 0x18, +0x88, 0x09, 0x88, 0x18, 0x88, 0x09, 0x88, 0x18, 0x88, 0x09, 0x88, 0x18, 0x88, 0x09, 0x88, 0x18, +0x88, 0x09, 0x88, 0x18, 0x88, 0x08, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, +0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, +0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, +0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, +0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, +0x88, 0x07, 0x88, 0x1A, 0x88, 0x08, 0x88, 0x18, 0x88, 0x09, 0x88, 0x18, 0x88, 0x09, 0x88, 0x18, +0x88, 0x09, 0x88, 0x18, 0x88, 0x09, 0x88, 0x18, 0x88, 0x09, 0x88, 0x18, 0x88, 0x0A, 0x88, 0x16, +0x88, 0x0B, 0x88, 0x16, 0x88, 0x0B, 0x88, 0x16, 0x88, 0x0B, 0x89, 0x14, 0x89, 0x0C, 0x88, 0x14, +0x88, 0x0D, 0x89, 0x12, 0x89, 0x0E, 0x88, 0x12, 0x88, 0x0F, 0x89, 0x10, 0x89, 0x0F, 0x8A, 0x0E, +0x8A, 0x10, 0x8B, 0x0A, 0x8B, 0x12, 0x8C, 0x06, 0x8C, 0x13, 0xA0, 0x14, 0x9E, 0x16, 0x9C, 0x18, +0x9A, 0x1A, 0x98, 0x1D, 0x94, 0x21, 0x90, 0x26, 0x8A, 0x49 +}; + +PROGMEM const unsigned char chr_f72_31[] = +{ +0x7F, 0x70, 0x85, 0x2D, 0x86, 0x2D, 0x86, 0x2C, 0x87, 0x2B, 0x88, 0x2B, 0x88, 0x2A, 0x89, 0x29, +0x8A, 0x28, 0x8B, 0x27, 0x8C, 0x25, 0x8E, 0x24, 0x8F, 0x23, 0x90, 0x22, 0x91, 0x20, 0x93, 0x1E, +0x95, 0x1C, 0x8D, 0x00, 0x88, 0x1B, 0x8C, 0x02, 0x88, 0x1B, 0x8B, 0x03, 0x88, 0x1B, 0x8A, 0x04, +0x88, 0x1B, 0x88, 0x06, 0x88, 0x1B, 0x87, 0x07, 0x88, 0x1B, 0x85, 0x09, 0x88, 0x1B, 0x83, 0x0B, +0x88, 0x1B, 0x81, 0x0D, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, +0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, +0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, +0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, +0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, +0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x7B +}; + +PROGMEM const unsigned char chr_f72_32[] = +{ +0x7F, 0x67, 0x8A, 0x25, 0x92, 0x1F, 0x96, 0x1B, 0x9A, 0x18, 0x9C, 0x16, 0x9E, 0x14, 0xA0, 0x12, +0xA2, 0x10, 0x8E, 0x07, 0x8D, 0x0F, 0x8B, 0x0C, 0x8C, 0x0D, 0x8A, 0x10, 0x8A, 0x0D, 0x89, 0x12, +0x8A, 0x0B, 0x89, 0x14, 0x89, 0x0B, 0x89, 0x14, 0x89, 0x0B, 0x88, 0x16, 0x89, 0x0A, 0x88, 0x16, +0x89, 0x09, 0x88, 0x18, 0x88, 0x09, 0x88, 0x18, 0x88, 0x09, 0x88, 0x18, 0x88, 0x0D, 0x84, 0x18, +0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2A, 0x89, 0x2A, 0x88, 0x2A, 0x89, 0x2A, 0x89, 0x29, +0x89, 0x2A, 0x89, 0x29, 0x89, 0x29, 0x8A, 0x28, 0x8A, 0x28, 0x8B, 0x27, 0x8B, 0x27, 0x8B, 0x27, +0x8B, 0x27, 0x8B, 0x27, 0x8C, 0x26, 0x8C, 0x26, 0x8C, 0x26, 0x8C, 0x26, 0x8C, 0x25, 0x8C, 0x26, +0x8C, 0x26, 0x8C, 0x26, 0x8C, 0x26, 0x8C, 0x25, 0x8D, 0x25, 0x8D, 0x25, 0x8C, 0x26, 0x8C, 0x26, +0x8C, 0x27, 0x8B, 0x27, 0x8B, 0x27, 0x8A, 0x28, 0x8A, 0x29, 0x89, 0x29, 0x8A, 0x29, 0x89, 0x29, +0x89, 0x2A, 0xAA, 0x08, 0xAB, 0x08, 0xAB, 0x08, 0xAB, 0x07, 0xAC, 0x07, 0xAC, 0x07, 0xAC, 0x07, +0xAC, 0x07, 0xAC, 0x6E +}; + +PROGMEM const unsigned char chr_f72_33[] = +{ +0x7F, 0x67, 0x89, 0x27, 0x90, 0x21, 0x94, 0x1D, 0x97, 0x1B, 0x9A, 0x18, 0x9C, 0x16, 0x9E, 0x14, +0xA0, 0x13, 0x8C, 0x06, 0x8C, 0x12, 0x8B, 0x0A, 0x8B, 0x10, 0x8A, 0x0E, 0x89, 0x10, 0x89, 0x10, +0x89, 0x0F, 0x88, 0x12, 0x88, 0x0E, 0x89, 0x12, 0x89, 0x0D, 0x88, 0x14, 0x88, 0x0D, 0x88, 0x14, +0x88, 0x0C, 0x89, 0x14, 0x88, 0x0C, 0x88, 0x15, 0x88, 0x10, 0x84, 0x15, 0x88, 0x2B, 0x88, 0x2B, +0x88, 0x2A, 0x88, 0x2B, 0x88, 0x2A, 0x89, 0x29, 0x89, 0x29, 0x89, 0x28, 0x8B, 0x26, 0x8C, 0x21, +0x91, 0x22, 0x8F, 0x24, 0x8D, 0x26, 0x8F, 0x23, 0x92, 0x21, 0x94, 0x1F, 0x95, 0x1E, 0x81, 0x07, +0x8C, 0x29, 0x8B, 0x2A, 0x8A, 0x2A, 0x89, 0x2B, 0x89, 0x2B, 0x89, 0x2A, 0x89, 0x2B, 0x88, 0x2B, +0x89, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x0B, 0x84, 0x1A, +0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x89, 0x18, 0x89, 0x07, 0x89, 0x18, 0x88, 0x09, 0x88, 0x18, +0x88, 0x09, 0x89, 0x16, 0x89, 0x09, 0x89, 0x15, 0x89, 0x0B, 0x89, 0x14, 0x89, 0x0B, 0x8A, 0x12, +0x89, 0x0D, 0x8A, 0x10, 0x8A, 0x0D, 0x8B, 0x0D, 0x8B, 0x0F, 0x8D, 0x07, 0x8D, 0x11, 0xA2, 0x12, +0xA0, 0x14, 0x9D, 0x17, 0x9B, 0x19, 0x99, 0x1C, 0x95, 0x20, 0x91, 0x26, 0x89, 0x4A +}; + +PROGMEM const unsigned char chr_f72_34[] = +{ +0x7F, 0x7F, 0x2A, 0x86, 0x2C, 0x87, 0x2B, 0x88, 0x2A, 0x89, 0x2A, 0x89, 0x29, 0x8A, 0x28, 0x8B, +0x27, 0x8C, 0x26, 0x8D, 0x26, 0x8D, 0x25, 0x8E, 0x24, 0x8F, 0x23, 0x90, 0x23, 0x90, 0x22, 0x91, +0x21, 0x92, 0x20, 0x93, 0x20, 0x93, 0x1F, 0x8A, 0x00, 0x88, 0x1E, 0x8A, 0x01, 0x88, 0x1D, 0x8A, +0x02, 0x88, 0x1C, 0x8B, 0x02, 0x88, 0x1C, 0x8A, 0x03, 0x88, 0x1B, 0x8A, 0x04, 0x88, 0x1A, 0x8A, +0x05, 0x88, 0x19, 0x8A, 0x06, 0x88, 0x19, 0x8A, 0x06, 0x88, 0x18, 0x8A, 0x07, 0x88, 0x17, 0x8A, +0x08, 0x88, 0x16, 0x8A, 0x09, 0x88, 0x16, 0x8A, 0x09, 0x88, 0x15, 0x8A, 0x0A, 0x88, 0x14, 0x8A, +0x0B, 0x88, 0x13, 0x8A, 0x0C, 0x88, 0x13, 0x8A, 0x0C, 0x88, 0x12, 0x8A, 0x0D, 0x88, 0x11, 0x8A, +0x0E, 0x88, 0x10, 0x8A, 0x0F, 0x88, 0x0F, 0x8B, 0x0F, 0x88, 0x0F, 0x8A, 0x10, 0x88, 0x0E, 0x8A, +0x11, 0x88, 0x0D, 0x8A, 0x12, 0x88, 0x0C, 0x8A, 0x13, 0x88, 0x0C, 0xAF, 0x04, 0xAF, 0x04, 0xAF, +0x04, 0xAF, 0x04, 0xAF, 0x04, 0xAF, 0x04, 0xAF, 0x04, 0xAF, 0x04, 0xAF, 0x23, 0x88, 0x2B, 0x88, +0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, +0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x75 +}; + +PROGMEM const unsigned char chr_f72_35[] = +{ +0x7F, 0x7F, 0x14, 0xA0, 0x13, 0xA0, 0x12, 0xA1, 0x12, 0xA1, 0x12, 0xA1, 0x12, 0xA1, 0x12, 0xA1, +0x11, 0xA2, 0x11, 0xA2, 0x11, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2A, 0x89, 0x2A, 0x88, 0x2B, 0x88, +0x2B, 0x88, 0x2B, 0x88, 0x2A, 0x89, 0x2A, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2A, 0x89, +0x06, 0x88, 0x1A, 0x89, 0x03, 0x8E, 0x17, 0x88, 0x02, 0x92, 0x15, 0x88, 0x00, 0x96, 0x13, 0xA1, +0x11, 0xA3, 0x10, 0xA4, 0x0F, 0xA5, 0x0E, 0x8F, 0x07, 0x8E, 0x0D, 0x8C, 0x0D, 0x8C, 0x0B, 0x8B, +0x11, 0x8A, 0x0B, 0x8A, 0x13, 0x8A, 0x0A, 0x89, 0x15, 0x89, 0x0E, 0x84, 0x17, 0x89, 0x2A, 0x89, +0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x89, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, +0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x0B, 0x84, 0x1A, 0x88, 0x07, 0x88, 0x19, 0x88, +0x08, 0x89, 0x18, 0x88, 0x08, 0x89, 0x18, 0x88, 0x09, 0x88, 0x17, 0x89, 0x09, 0x89, 0x16, 0x88, +0x0A, 0x89, 0x15, 0x89, 0x0B, 0x89, 0x13, 0x89, 0x0C, 0x8A, 0x11, 0x8A, 0x0C, 0x8B, 0x0F, 0x8A, +0x0E, 0x8B, 0x0D, 0x8A, 0x10, 0x8D, 0x07, 0x8D, 0x10, 0xA2, 0x12, 0xA0, 0x14, 0x9E, 0x17, 0x9B, +0x19, 0x98, 0x1D, 0x95, 0x20, 0x90, 0x26, 0x8A, 0x4A +}; + +PROGMEM const unsigned char chr_f72_36[] = +{ +0x7F, 0x6A, 0x89, 0x26, 0x90, 0x21, 0x95, 0x1C, 0x98, 0x1A, 0x9A, 0x18, 0x9C, 0x16, 0x9E, 0x14, +0xA0, 0x12, 0x8D, 0x06, 0x8D, 0x10, 0x8B, 0x0B, 0x8B, 0x10, 0x8A, 0x0E, 0x8A, 0x0E, 0x89, 0x11, +0x89, 0x0D, 0x8A, 0x12, 0x89, 0x0C, 0x89, 0x13, 0x89, 0x0C, 0x88, 0x15, 0x88, 0x0B, 0x89, 0x15, +0x89, 0x0A, 0x88, 0x16, 0x89, 0x09, 0x89, 0x17, 0x88, 0x09, 0x88, 0x18, 0x84, 0x0D, 0x88, 0x2B, +0x87, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x0A, 0x88, 0x17, 0x87, 0x08, 0x8E, 0x14, +0x87, 0x06, 0x92, 0x11, 0x88, 0x04, 0x96, 0x0F, 0x88, 0x03, 0x98, 0x0E, 0x88, 0x02, 0x9A, 0x0D, +0x88, 0x01, 0x9C, 0x0C, 0x88, 0x00, 0x9E, 0x0B, 0x92, 0x07, 0x8E, 0x0A, 0x90, 0x0C, 0x8C, 0x09, +0x8E, 0x10, 0x8A, 0x09, 0x8D, 0x12, 0x8A, 0x08, 0x8C, 0x14, 0x89, 0x08, 0x8B, 0x16, 0x89, 0x07, +0x8A, 0x17, 0x89, 0x07, 0x89, 0x19, 0x88, 0x07, 0x89, 0x19, 0x88, 0x07, 0x89, 0x19, 0x89, 0x06, +0x88, 0x1B, 0x88, 0x06, 0x88, 0x1B, 0x88, 0x06, 0x88, 0x1B, 0x88, 0x06, 0x88, 0x1B, 0x88, 0x07, +0x87, 0x1B, 0x88, 0x07, 0x87, 0x1B, 0x88, 0x07, 0x87, 0x1B, 0x88, 0x07, 0x87, 0x1B, 0x88, 0x07, +0x88, 0x1A, 0x88, 0x08, 0x87, 0x19, 0x89, 0x08, 0x87, 0x19, 0x88, 0x09, 0x88, 0x18, 0x88, 0x09, +0x88, 0x17, 0x89, 0x0A, 0x88, 0x16, 0x88, 0x0B, 0x88, 0x15, 0x89, 0x0C, 0x88, 0x14, 0x89, 0x0C, +0x89, 0x12, 0x89, 0x0E, 0x89, 0x10, 0x8A, 0x0E, 0x8B, 0x0C, 0x8B, 0x10, 0x8C, 0x07, 0x8D, 0x12, +0xA1, 0x13, 0x9F, 0x15, 0x9D, 0x17, 0x9B, 0x1A, 0x97, 0x1D, 0x95, 0x21, 0x8F, 0x27, 0x89, 0x49 + +}; + +PROGMEM const unsigned char chr_f72_37[] = +{ +0x7F, 0x7F, 0x0D, 0xAB, 0x08, 0xAB, 0x08, 0xAB, 0x08, 0xAB, 0x08, 0xAB, 0x08, 0xAB, 0x08, 0xAB, +0x08, 0xAB, 0x08, 0xAA, 0x2C, 0x86, 0x2C, 0x86, 0x2C, 0x87, 0x2B, 0x87, 0x2B, 0x87, 0x2B, 0x87, +0x2C, 0x87, 0x2B, 0x87, 0x2B, 0x87, 0x2C, 0x87, 0x2B, 0x87, 0x2B, 0x88, 0x2B, 0x87, 0x2B, 0x87, +0x2B, 0x88, 0x2B, 0x87, 0x2B, 0x88, 0x2B, 0x87, 0x2B, 0x88, 0x2A, 0x88, 0x2B, 0x88, 0x2A, 0x88, +0x2B, 0x88, 0x2A, 0x88, 0x2B, 0x88, 0x2A, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2A, 0x88, 0x2B, 0x88, +0x2A, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2A, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2A, 0x88, 0x2B, 0x88, +0x2B, 0x88, 0x2A, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2A, 0x88, 0x2B, 0x88, 0x2B, 0x88, +0x2B, 0x88, 0x2A, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2A, 0x89, +0x2A, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x7F, 0x06 +}; + +PROGMEM const unsigned char chr_f72_38[] = +{ +0x7F, 0x68, 0x89, 0x26, 0x91, 0x20, 0x95, 0x1C, 0x99, 0x19, 0x9B, 0x17, 0x9D, 0x15, 0x9F, 0x13, +0xA1, 0x11, 0x8D, 0x07, 0x8C, 0x11, 0x8B, 0x0B, 0x8B, 0x0F, 0x8A, 0x0F, 0x8A, 0x0E, 0x89, 0x11, +0x89, 0x0E, 0x88, 0x13, 0x88, 0x0D, 0x89, 0x13, 0x89, 0x0C, 0x88, 0x15, 0x88, 0x0C, 0x88, 0x15, +0x88, 0x0C, 0x88, 0x15, 0x88, 0x0C, 0x88, 0x15, 0x88, 0x0C, 0x88, 0x15, 0x88, 0x0C, 0x88, 0x15, +0x88, 0x0C, 0x88, 0x15, 0x88, 0x0D, 0x88, 0x13, 0x88, 0x0E, 0x88, 0x13, 0x88, 0x0E, 0x89, 0x11, +0x89, 0x0F, 0x89, 0x0F, 0x89, 0x11, 0x89, 0x0D, 0x89, 0x13, 0x8B, 0x07, 0x8C, 0x14, 0x9D, 0x17, +0x9B, 0x1A, 0x97, 0x1E, 0x93, 0x1E, 0x96, 0x1B, 0x9A, 0x18, 0x9D, 0x15, 0x9F, 0x13, 0x8C, 0x07, +0x8C, 0x11, 0x8A, 0x0C, 0x8B, 0x0F, 0x8A, 0x0F, 0x8A, 0x0D, 0x8A, 0x11, 0x89, 0x0D, 0x89, 0x13, +0x89, 0x0B, 0x89, 0x15, 0x88, 0x0B, 0x89, 0x15, 0x89, 0x0A, 0x88, 0x17, 0x88, 0x0A, 0x88, 0x17, +0x88, 0x09, 0x88, 0x19, 0x88, 0x08, 0x88, 0x19, 0x88, 0x08, 0x88, 0x19, 0x88, 0x08, 0x88, 0x19, +0x88, 0x08, 0x88, 0x19, 0x88, 0x08, 0x88, 0x19, 0x88, 0x08, 0x88, 0x19, 0x88, 0x08, 0x88, 0x19, +0x88, 0x08, 0x88, 0x19, 0x88, 0x08, 0x89, 0x17, 0x89, 0x09, 0x88, 0x17, 0x88, 0x0A, 0x89, 0x15, +0x89, 0x0A, 0x89, 0x15, 0x89, 0x0B, 0x89, 0x13, 0x89, 0x0C, 0x8A, 0x11, 0x8A, 0x0D, 0x8A, 0x0F, +0x8A, 0x0E, 0x8C, 0x0C, 0x8B, 0x0F, 0x8D, 0x07, 0x8D, 0x11, 0xA1, 0x13, 0x9F, 0x15, 0x9D, 0x17, +0x9B, 0x19, 0x99, 0x1C, 0x95, 0x20, 0x91, 0x26, 0x89, 0x4A +}; + +PROGMEM const unsigned char chr_f72_39[] = +{ +0x7F, 0x68, 0x88, 0x27, 0x90, 0x21, 0x94, 0x1E, 0x97, 0x1A, 0x9A, 0x18, 0x9C, 0x16, 0x9E, 0x14, +0xA0, 0x12, 0x8E, 0x07, 0x8B, 0x11, 0x8C, 0x0B, 0x8A, 0x0F, 0x8B, 0x0F, 0x88, 0x0F, 0x8A, 0x11, +0x88, 0x0D, 0x8A, 0x13, 0x88, 0x0C, 0x89, 0x14, 0x88, 0x0B, 0x89, 0x16, 0x87, 0x0B, 0x89, 0x17, +0x87, 0x0A, 0x88, 0x18, 0x87, 0x0A, 0x88, 0x18, 0x87, 0x09, 0x89, 0x19, 0x87, 0x08, 0x88, 0x1A, +0x87, 0x08, 0x88, 0x1A, 0x87, 0x08, 0x88, 0x1A, 0x87, 0x08, 0x88, 0x1A, 0x87, 0x08, 0x88, 0x1A, +0x87, 0x08, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, 0x88, 0x07, 0x88, 0x1A, +0x88, 0x07, 0x89, 0x18, 0x89, 0x08, 0x88, 0x18, 0x89, 0x08, 0x88, 0x18, 0x89, 0x08, 0x89, 0x16, +0x8A, 0x08, 0x89, 0x16, 0x8A, 0x09, 0x89, 0x14, 0x8B, 0x09, 0x8A, 0x12, 0x8C, 0x0A, 0x8A, 0x10, +0x8D, 0x0A, 0x8C, 0x0C, 0x8F, 0x0B, 0x8E, 0x07, 0x91, 0x0C, 0x9D, 0x00, 0x88, 0x0D, 0x9B, 0x01, +0x88, 0x0E, 0x99, 0x02, 0x88, 0x0F, 0x97, 0x03, 0x88, 0x10, 0x95, 0x04, 0x88, 0x11, 0x92, 0x06, +0x87, 0x14, 0x8E, 0x08, 0x87, 0x17, 0x88, 0x0A, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, 0x88, 0x2B, +0x87, 0x2B, 0x88, 0x0E, 0x84, 0x17, 0x88, 0x0A, 0x88, 0x17, 0x88, 0x0A, 0x89, 0x15, 0x88, 0x0B, +0x89, 0x15, 0x88, 0x0C, 0x88, 0x14, 0x89, 0x0C, 0x89, 0x13, 0x88, 0x0D, 0x89, 0x12, 0x89, 0x0E, +0x89, 0x10, 0x89, 0x0F, 0x8A, 0x0E, 0x8A, 0x0F, 0x8B, 0x0B, 0x8B, 0x11, 0x8C, 0x07, 0x8C, 0x13, +0x9F, 0x14, 0x9E, 0x16, 0x9C, 0x18, 0x9A, 0x1B, 0x97, 0x1D, 0x94, 0x21, 0x90, 0x26, 0x89, 0x4C +}; + +PROGMEM const unsigned char chr_f72_3A[] = +{ +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x23, 0x88, 0x13, +0x88, 0x13, 0x88, 0x13, 0x88, 0x13, 0x88, 0x13, +0x88, 0x13, 0x88, 0x13, 0x88, 0x13, 0x88, 0x7F, +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x33, 0x88, +0x13, 0x88, 0x13, 0x88, 0x13, 0x88, 0x13, 0x88, +0x13, 0x88, 0x13, 0x88, 0x13, 0x88, 0x13, 0x88, +0x44 +}; +PROGMEM const unsigned char * const chrtbl_f72[96] = // character pointer table +{ + chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, + chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_2D, chr_f72_2E, chr_f72_20, + chr_f72_30, chr_f72_31, chr_f72_32, chr_f72_33, chr_f72_34, chr_f72_35, chr_f72_36, chr_f72_37, + chr_f72_38, chr_f72_39, chr_f72_3A, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, + chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, + chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, + chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, + chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, + chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, + chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, + chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, + chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20, chr_f72_20 +}; diff --git a/Fonts/Font72x53rle.h b/Fonts/Font72x53rle.h new file mode 100644 index 0000000..b7ce1c9 --- /dev/null +++ b/Fonts/Font72x53rle.h @@ -0,0 +1,10 @@ +#include + +#define nr_chrs_f72 96 +#define chr_hgt_f72 75 +#define baseline_f72 73 +#define data_size_f72 8 +#define firstchr_f72 32 + +extern const unsigned char widtbl_f72[96]; +extern const unsigned char* const chrtbl_f72[96]; diff --git a/README.md b/README.md index 9727a82..c11fd2d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # TFT_eSPI +Update 10th March 2018: Added support for 8 bit parallel interface TFTs when used with ESP32. Update 24th February 2018: Added new smooth (antialiased) fonts. See Smooth Font examples and Tools folder for the font generator. @@ -36,7 +37,7 @@ Configuration of the library font selections, pins used to interface with the TF I have made some changes that will be uploaded soon that improves sprite and image rendering performance by up to 3x faster on the ESP8266. These updates are currently being tested/debugged. -**2. Anti-aliased fonts** +**2. Anti-aliased fonts - done 24/2/18** I have been experimenting with anti-aliased font files in "vlw" format generated by the free [Processing IDE](https://processing.org/). This IDE can be used to generate font files from your computer's font set and include **any** Unicode characters. This means Greek, Japanese and any other UTF-16 glyphs can be used. @@ -51,3 +52,20 @@ Here is another screenshot, showing the anti-aliased Hiragana character Unicode ![Hiragana glyphs](https://i.imgur.com/jeXf2st.png) Currently these are generated from a sketch, but when I have the Alpha blending sorted for colour backgrounds the plan is to build the rendering code into the TFT_eSPI library. Watch this space " " for updates! + +**3. Add support 4 8 bit "UNO" style TFTs with ESP32 - done 10/3/18** + +The ESP32 board I have been using for testing has the following pinout: + +![Example](https://i.imgur.com/bvM6leE.jpg) + +UNO style boards with a Wemos R32(ESP32) label are also available at low cost with the same pin-out. + +Unfortunately the typical UNO/mcufriend TFT display board maps LCD_RD, LCD_CS and LCD_RST signals to the ESP32 pins 35, 34 and 36 which are input only. To solve this I linked in the 3 spare pins IO15, IO33 and IO32 by adding wires to the bottom of the board as follows: + +IO15 wired to IO35 +IO33 wired to IO34 +IO32 wired to IO36 + +![Example](https://i.imgur.com/pUZn6lF.jpg) + diff --git a/TFT_Drivers/HX8357D_Defines.h b/TFT_Drivers/HX8357D_Defines.h new file mode 100644 index 0000000..7dcbdad --- /dev/null +++ b/TFT_Drivers/HX8357D_Defines.h @@ -0,0 +1,86 @@ +// Change the width and height if required (defined in portrait mode) +// or use the constructor to over-ride defaults +#define TFT_WIDTH 320 +#define TFT_HEIGHT 480 + + +// Delay between some initialisation commands +#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked + + +// Generic commands used by TFT_eSPar.cpp +#define TFT_NOP 0x00 +#define TFT_SWRST 0x01 + +#define TFT_SLPIN 0x10 +#define TFT_SLPOUT 0x11 + +#define TFT_INVOFF 0x20 +#define TFT_INVON 0x21 + +#define TFT_DISPOFF 0x28 +#define TFT_DISPON 0x29 + +#define TFT_CASET 0x2A +#define TFT_PASET 0x2B +#define TFT_RAMWR 0x2C + +#define TFT_RAMRD 0x2E + +#define TFT_MADCTL 0x36 + +#define TFT_MAD_MY 0x80 +#define TFT_MAD_MX 0x40 +#define TFT_MAD_MV 0x20 +#define TFT_MAD_ML 0x10 +#define TFT_MAD_RGB 0x00 +#define TFT_MAD_BGR 0x08 +#define TFT_MAD_MH 0x04 +#define TFT_MAD_SS 0x02 +#define TFT_MAD_GS 0x01 + +#define TFT_IDXRD 0x00 // ILI9341 only, indexed control register read + + +#define HX8357_NOP 0x00 +#define HX8357_SWRESET 0x01 +#define HX8357_RDDID 0x04 +#define HX8357_RDDST 0x09 + +#define HX8357_RDPOWMODE 0x0A +#define HX8357_RDMADCTL 0x0B +#define HX8357_RDCOLMOD 0x0C +#define HX8357_RDDIM 0x0D +#define HX8357_RDDSDR 0x0F + +#define HX8357_SLPIN 0x10 +#define HX8357_SLPOUT 0x11 + +#define HX8357_INVOFF 0x20 +#define HX8357_INVON 0x21 +#define HX8357_DISPOFF 0x28 +#define HX8357_DISPON 0x29 + +#define HX8357_CASET 0x2A +#define HX8357_PASET 0x2B +#define HX8357_RAMWR 0x2C +#define HX8357_RAMRD 0x2E + +#define HX8357_TEON 0x35 +#define HX8357_TEARLINE 0x44 +#define HX8357_MADCTL 0x36 +#define HX8357_COLMOD 0x3A + +#define HX8357_SETOSC 0xB0 +#define HX8357_SETPWR1 0xB1 +#define HX8357_SETRGB 0xB3 +#define HX8357D_SETCOM 0xB6 + +#define HX8357D_SETCYC 0xB4 +#define HX8357D_SETC 0xB9 + +#define HX8357D_SETSTBA 0xC0 + +#define HX8357_SETPANEL 0xCC + +#define HX8357D_SETGAMMA 0xE0 diff --git a/TFT_Drivers/HX8357D_Init.h b/TFT_Drivers/HX8357D_Init.h new file mode 100644 index 0000000..50389bb --- /dev/null +++ b/TFT_Drivers/HX8357D_Init.h @@ -0,0 +1,118 @@ + +// This is the command sequence that initialises the HX8357D driver +// +// This setup information uses simple 8 bit SPI writecommand() and writedata() functions +// +// See ST7735_Setup.h file for an alternative format + + +// Configure HX8357D display + + // setextc + writecommand(HX8357D_SETC); + writedata(0xFF); + writedata(0x83); + writedata(0x57); + delay(300); + + // setRGB which also enables SDO + writecommand(HX8357_SETRGB); + writedata(0x80); //enable SDO pin! +// writedata(0x00); //disable SDO pin! + writedata(0x0); + writedata(0x06); + writedata(0x06); + + writecommand(HX8357D_SETCOM); + writedata(0x25); // -1.52V + + writecommand(HX8357_SETOSC); + writedata(0x68); // Normal mode 70Hz, Idle mode 55 Hz + + writecommand(HX8357_SETPANEL); //Set Panel + writedata(0x05); // BGR, Gate direction swapped + + writecommand(HX8357_SETPWR1); + writedata(0x00); // Not deep standby + writedata(0x15); //BT + writedata(0x1C); //VSPR + writedata(0x1C); //VSNR + writedata(0x83); //AP + writedata(0xAA); //FS + + writecommand(HX8357D_SETSTBA); + writedata(0x50); //OPON normal + writedata(0x50); //OPON idle + writedata(0x01); //STBA + writedata(0x3C); //STBA + writedata(0x1E); //STBA + writedata(0x08); //GEN + + writecommand(HX8357D_SETCYC); + writedata(0x02); //NW 0x02 + writedata(0x40); //RTN + writedata(0x00); //DIV + writedata(0x2A); //DUM + writedata(0x2A); //DUM + writedata(0x0D); //GDON + writedata(0x78); //GDOFF + + writecommand(HX8357D_SETGAMMA); + writedata(0x02); + writedata(0x0A); + writedata(0x11); + writedata(0x1d); + writedata(0x23); + writedata(0x35); + writedata(0x41); + writedata(0x4b); + writedata(0x4b); + writedata(0x42); + writedata(0x3A); + writedata(0x27); + writedata(0x1B); + writedata(0x08); + writedata(0x09); + writedata(0x03); + writedata(0x02); + writedata(0x0A); + writedata(0x11); + writedata(0x1d); + writedata(0x23); + writedata(0x35); + writedata(0x41); + writedata(0x4b); + writedata(0x4b); + writedata(0x42); + writedata(0x3A); + writedata(0x27); + writedata(0x1B); + writedata(0x08); + writedata(0x09); + writedata(0x03); + writedata(0x00); + writedata(0x01); + + writecommand(HX8357_COLMOD); + writedata(0x55); // 16 bit + + writecommand(HX8357_MADCTL); + writedata(0xC0); + + writecommand(HX8357_TEON); // TE off + writedata(0x00); + + writecommand(HX8357_TEARLINE); // tear line + writedata(0x00); + writedata(0x02); + + writecommand(HX8357_SLPOUT); //Exit Sleep + delay(150); + + writecommand(HX8357_DISPON); // display on + delay(50); + +// End of HX8357D display configuration + + + diff --git a/TFT_Drivers/HX8357D_Rotation.h b/TFT_Drivers/HX8357D_Rotation.h new file mode 100644 index 0000000..9df230b --- /dev/null +++ b/TFT_Drivers/HX8357D_Rotation.h @@ -0,0 +1,26 @@ + // This is the command sequence that rotates the ILI9481 driver coordinate frame + + writecommand(TFT_MADCTL); + rotation = m % 4; + switch (rotation) { + case 0: // Portrait + writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_RGB); + _width = TFT_WIDTH; + _height = TFT_HEIGHT; + break; + case 1: // Landscape (Portrait + 90) + writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_RGB); + _width = TFT_HEIGHT; + _height = TFT_WIDTH; + break; + case 2: // Inverter portrait + writedata(TFT_MAD_RGB); + _width = TFT_WIDTH; + _height = TFT_HEIGHT; + break; + case 3: // Inverted landscape + writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_RGB); + _width = TFT_HEIGHT; + _height = TFT_WIDTH; + break; + } diff --git a/TFT_Drivers/ILI9481_Defines.h b/TFT_Drivers/ILI9481_Defines.h new file mode 100644 index 0000000..bd5fb88 --- /dev/null +++ b/TFT_Drivers/ILI9481_Defines.h @@ -0,0 +1,42 @@ +// Change the width and height if required (defined in portrait mode) +// or use the constructor to over-ride defaults +#define TFT_WIDTH 320 +#define TFT_HEIGHT 480 + + +// Delay between some initialisation commands +#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked + + +// Generic commands used by TFT_eSPI.cpp +#define TFT_NOP 0x00 +#define TFT_SWRST 0x01 + +#define TFT_SLPIN 0x10 +#define TFT_SLPOUT 0x11 + +#define TFT_INVOFF 0x20 +#define TFT_INVON 0x21 + +#define TFT_DISPOFF 0x28 +#define TFT_DISPON 0x29 + +#define TFT_CASET 0x2A +#define TFT_PASET 0x2B +#define TFT_RAMWR 0x2C + +#define TFT_RAMRD 0x2E + +#define TFT_MADCTL 0x36 + +#define TFT_MAD_MY 0x80 +#define TFT_MAD_MX 0x40 +#define TFT_MAD_MV 0x20 +#define TFT_MAD_ML 0x10 +#define TFT_MAD_RGB 0x00 +#define TFT_MAD_BGR 0x08 +#define TFT_MAD_MH 0x04 +#define TFT_MAD_SS 0x02 +#define TFT_MAD_GS 0x01 + +#define TFT_IDXRD 0x00 // ILI9341 only, indexed control register read diff --git a/TFT_Drivers/ILI9481_Init.h b/TFT_Drivers/ILI9481_Init.h new file mode 100644 index 0000000..038d1fd --- /dev/null +++ b/TFT_Drivers/ILI9481_Init.h @@ -0,0 +1,77 @@ + +// This is the command sequence that initialises the ILI9481 driver +// +// This setup information uses simple 8 bit SPI writecommand() and writedata() functions +// +// See ST7735_Setup.h file for an alternative format + + +// Configure ILI9481 display + + writecommand(TFT_SLPOUT); + delay(20); + + writecommand(0xD0); + writedata(0x07); + writedata(0x42); + writedata(0x18); + + writecommand(0xD1); + writedata(0x00); + writedata(0x07); + writedata(0x10); + + writecommand(0xD2); + writedata(0x01); + writedata(0x02); + + writecommand(0xC0); + writedata(0x10); + writedata(0x3B); + writedata(0x00); + writedata(0x02); + writedata(0x11); + + writecommand(0xC5); + writedata(0x03); + + writecommand(0xC8); + writedata(0x00); + writedata(0x32); + writedata(0x36); + writedata(0x45); + writedata(0x06); + writedata(0x16); + writedata(0x37); + writedata(0x75); + writedata(0x77); + writedata(0x54); + writedata(0x0C); + writedata(0x00); + + writecommand(TFT_MADCTL); + writedata(0x0A); + + writecommand(0x3A); + writedata(0x55); + + writecommand(TFT_CASET); + writedata(0x00); + writedata(0x00); + writedata(0x01); + writedata(0x3F); + + writecommand(TFT_PASET); + writedata(0x00); + writedata(0x00); + writedata(0x01); + writedata(0xDF); + + delay(120); + writecommand(TFT_DISPON); + + delay(25); +// End of ILI9481 display configuration + + + diff --git a/TFT_Drivers/ILI9481_Rotation.h b/TFT_Drivers/ILI9481_Rotation.h new file mode 100644 index 0000000..e80d08e --- /dev/null +++ b/TFT_Drivers/ILI9481_Rotation.h @@ -0,0 +1,27 @@ + // This is the command sequence that rotates the ILI9481 driver coordinate frame + + writecommand(TFT_MADCTL); + rotation = m % 4; + switch (rotation) { + case 0: // Portrait + writedata(TFT_MAD_BGR | TFT_MAD_SS); + _width = TFT_WIDTH; + _height = TFT_HEIGHT; + break; + case 1: // Landscape (Portrait + 90) + writedata(TFT_MAD_MV | TFT_MAD_BGR); + _width = TFT_HEIGHT; + _height = TFT_WIDTH; + break; + case 2: // Inverter portrait + writedata(TFT_MAD_BGR | TFT_MAD_GS); + _width = TFT_WIDTH; + _height = TFT_HEIGHT; + break; + case 3: // Inverted landscape + writedata(TFT_MAD_MV | TFT_MAD_BGR | TFT_MAD_SS | TFT_MAD_GS); + _width = TFT_HEIGHT; + _height = TFT_WIDTH; + break; + } + \ No newline at end of file diff --git a/TFT_Drivers/ILI9488_Defines.h b/TFT_Drivers/ILI9488_Defines.h new file mode 100644 index 0000000..bd5fb88 --- /dev/null +++ b/TFT_Drivers/ILI9488_Defines.h @@ -0,0 +1,42 @@ +// Change the width and height if required (defined in portrait mode) +// or use the constructor to over-ride defaults +#define TFT_WIDTH 320 +#define TFT_HEIGHT 480 + + +// Delay between some initialisation commands +#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked + + +// Generic commands used by TFT_eSPI.cpp +#define TFT_NOP 0x00 +#define TFT_SWRST 0x01 + +#define TFT_SLPIN 0x10 +#define TFT_SLPOUT 0x11 + +#define TFT_INVOFF 0x20 +#define TFT_INVON 0x21 + +#define TFT_DISPOFF 0x28 +#define TFT_DISPON 0x29 + +#define TFT_CASET 0x2A +#define TFT_PASET 0x2B +#define TFT_RAMWR 0x2C + +#define TFT_RAMRD 0x2E + +#define TFT_MADCTL 0x36 + +#define TFT_MAD_MY 0x80 +#define TFT_MAD_MX 0x40 +#define TFT_MAD_MV 0x20 +#define TFT_MAD_ML 0x10 +#define TFT_MAD_RGB 0x00 +#define TFT_MAD_BGR 0x08 +#define TFT_MAD_MH 0x04 +#define TFT_MAD_SS 0x02 +#define TFT_MAD_GS 0x01 + +#define TFT_IDXRD 0x00 // ILI9341 only, indexed control register read diff --git a/TFT_Drivers/ILI9488_Init.h b/TFT_Drivers/ILI9488_Init.h new file mode 100644 index 0000000..feaffdd --- /dev/null +++ b/TFT_Drivers/ILI9488_Init.h @@ -0,0 +1,97 @@ + +// This is the command sequence that initialises the ILI9488 driver +// +// This setup information uses simple 8 bit SPI writecommand() and writedata() functions +// +// See ST7735_Setup.h file for an alternative format + + +// Configure ILI9488 display + + writecommand(0x3A); // Pixel Interface Format (16 bit colour) + writedata(0x55); + + writecommand(0xB0); // Interface Mode Control + writedata(0x00); + + writecommand(0xB1); // Frame Rate Control + writedata(0xB0); + writedata(0x11); + + writecommand(0xB4); // Display Inversion Control + writedata(0x02); + + writecommand(0xB6); // Display Function Control + writedata(0x02); + writedata(0x02); + writedata(0x3B); + + writecommand(0xB7); // Entry Mode Set + writedata(0xC6); + + writecommand(0XC0); // Power Control 1 + writedata(0x10); + writedata(0x10); + + writecommand(0xC1); // Power Control 2 + writedata(0x41); + + writecommand(0xC5); // VCOM Control + writedata(0x00); + writedata(0x22); + writedata(0x80); + writedata(0x40); + + writecommand(0xE0); // Positive Gamma Control + writedata(0x00); + writedata(0x03); + writedata(0x09); + writedata(0x08); + writedata(0x16); + writedata(0x0A); + writedata(0x3F); + writedata(0x78); + writedata(0x4C); + writedata(0x09); + writedata(0x0A); + writedata(0x08); + writedata(0x16); + writedata(0x1A); + writedata(0x0F); + + writecommand(0XE1); // Negative Gamma Control + writedata(0x00); + writedata(0x16); + writedata(0x19); + writedata(0x03); + writedata(0x0F); + writedata(0x05); + writedata(0x32); + writedata(0x45); + writedata(0x46); + writedata(0x04); + writedata(0x0E); + writedata(0x0D); + writedata(0x35); + writedata(0x37); + writedata(0x0F); + + writecommand(0xF7); // Adjust Control 3 + writedata(0xA9); + writedata(0x51); + writedata(0x2C); + writedata(0x02); + + writecommand(TFT_MADCTL); // Memory Access Control + writedata(0x48); // MX, BGR + + writecommand(TFT_SLPOUT); //Exit Sleep +delay(120); + + writecommand(TFT_DISPON); //Display on +delay(25); + +// End of ILI9488 display configuration + + + diff --git a/TFT_Drivers/ILI9488_Rotation.h b/TFT_Drivers/ILI9488_Rotation.h new file mode 100644 index 0000000..6ab17bd --- /dev/null +++ b/TFT_Drivers/ILI9488_Rotation.h @@ -0,0 +1,27 @@ + // This is the command sequence that rotates the ILI9488 driver coordinate frame + + writecommand(TFT_MADCTL); + rotation = m % 4; + switch (rotation) { + case 0: // Portrait + writedata(TFT_MAD_MX | TFT_MAD_BGR); + _width = TFT_WIDTH; + _height = TFT_HEIGHT; + break; + case 1: // Landscape (Portrait + 90) + writedata(TFT_MAD_MV | TFT_MAD_BGR); + _width = TFT_HEIGHT; + _height = TFT_WIDTH; + break; + case 2: // Inverter portrait + writedata(TFT_MAD_MY | TFT_MAD_BGR); + _width = TFT_WIDTH; + _height = TFT_HEIGHT; + break; + case 3: // Inverted landscape + writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR); + _width = TFT_HEIGHT; + _height = TFT_WIDTH; + break; + } + \ No newline at end of file diff --git a/TFT_eSPI.cpp b/TFT_eSPI.cpp index 901f490..c5fa4ee 100644 --- a/TFT_eSPI.cpp +++ b/TFT_eSPI.cpp @@ -17,7 +17,9 @@ #include -#include +#ifndef ESP32_PARALLEL + #include +#endif // SUPPORT_TRANSACTIONS is mandatory for ESP32 so the hal mutex is toggled #if defined (ESP32) && !defined (SUPPORT_TRANSACTIONS) @@ -32,26 +34,32 @@ #define CMD_BITS 8-1 #endif -// Fast SPI block write prototype -void spiWriteBlock(uint16_t color, uint32_t repeat); +// Fast block write prototype +void writeBlock(uint16_t color, uint32_t repeat); + +// Byte read prototype +uint8_t readByte(void); + +// GPIO parallel input/output control +void busDir(uint32_t mask, uint8_t mode); // If the SPI library has transaction support, these functions // establish settings and protect from interference from other // libraries. Otherwise, they simply do nothing. inline void TFT_eSPI::spi_begin(void){ -#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) +#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(ESP32_PARALLEL) if (locked) {locked = false; SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0));} #endif } inline void TFT_eSPI::spi_end(void){ -#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) +#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(ESP32_PARALLEL) if(!inTransaction) {if (!locked) {locked = true; SPI.endTransaction();}} #endif } -#if defined (TOUCH_CS) && defined (SPI_TOUCH_FREQUENCY) +#if defined (TOUCH_CS) && defined (SPI_TOUCH_FREQUENCY) // && !defined(ESP32_PARALLEL) inline void TFT_eSPI::spi_begin_touch(void){ #if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) @@ -109,6 +117,39 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h) } #endif +#ifdef ESP32_PARALLEL + // Create a data bus and Write line GPIO bit clear mask + //clr_mask = (1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7) | (1 << TFT_WR); + + // Create a data bus GPIO bit direction mask + //dir_mask = (1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7); + + + // Create a bit set lookup table for data bus - wastes 1kbyte of RAM but speeds things up dramatically + for (int c = 0; c<256; c++) + { + xset_mask[c] = 0; + if ( c & 0x01 ) xset_mask[c] |= (1 << TFT_D0); + if ( c & 0x02 ) xset_mask[c] |= (1 << TFT_D1); + if ( c & 0x04 ) xset_mask[c] |= (1 << TFT_D2); + if ( c & 0x08 ) xset_mask[c] |= (1 << TFT_D3); + if ( c & 0x10 ) xset_mask[c] |= (1 << TFT_D4); + if ( c & 0x20 ) xset_mask[c] |= (1 << TFT_D5); + if ( c & 0x40 ) xset_mask[c] |= (1 << TFT_D6); + if ( c & 0x80 ) xset_mask[c] |= (1 << TFT_D7); + } + + // Make sure read is high before we set the bus to output + digitalWrite(TFT_RD, HIGH); + pinMode(TFT_RD, OUTPUT); + + GPIO.out_w1ts = set_mask(255); // Set data bus to 0xFF + + // Set TFT data bus lines to output + busDir(dir_mask, OUTPUT); + +#endif + _init_width = _width = w; // Set by specific xxxxx_Defines.h file or by users sketch _init_height = _height = h; // Set by specific xxxxx_Defines.h file or by users sketch rotation = 0; @@ -196,18 +237,19 @@ void TFT_eSPI::init(void) SPI.begin(); // This will set HMISO to input #else - #if defined (TFT_MOSI) && !defined (TFT_SPI_OVERLAP) - SPI.begin(TFT_SCLK, TFT_MISO, TFT_MOSI, -1); - #else - SPI.begin(); + #if !defined(ESP32_PARALLEL) + #if defined (TFT_MOSI) && !defined (TFT_SPI_OVERLAP) + SPI.begin(TFT_SCLK, TFT_MISO, TFT_MOSI, -1); + #else + SPI.begin(); + #endif #endif - #endif inTransaction = false; locked = true; - // SUPPORT_TRANSACTIONS is manadatory for ESP32 so the hal mutex is toggled + // SUPPORT_TRANSACTIONS is mandatory for ESP32 so the hal mutex is toggled // so the code here is for ESP8266 only #if !defined (SUPPORT_TRANSACTIONS) && defined (ESP8266) SPI.setBitOrder(MSBFIRST); @@ -215,14 +257,19 @@ void TFT_eSPI::init(void) SPI.setFrequency(SPI_FREQUENCY); #endif - // Set to output once again in case D6 (MISO) is used for CS -#ifdef TFT_CS - digitalWrite(TFT_CS, HIGH); // Chip select high (inactive) - pinMode(TFT_CS, OUTPUT); +#if defined(ESP32_PARALLEL) + digitalWrite(TFT_CS, LOW); // Chip select low permanently + pinMode(TFT_CS, OUTPUT); #else - SPI.setHwCs(1); // Use hardware SS toggling + #ifdef TFT_CS + // Set to output once again in case D6 (MISO) is used for CS + digitalWrite(TFT_CS, HIGH); // Chip select high (inactive) + pinMode(TFT_CS, OUTPUT); + #else + SPI.setHwCs(1); // Use hardware SS toggling + #endif #endif - + // Set to output once again in case D6 (MISO) is used for DC #ifdef TFT_DC digitalWrite(TFT_DC, HIGH); // Data/Command high = data mode @@ -265,6 +312,15 @@ void TFT_eSPI::init(void) #elif defined (RPI_ILI9486_DRIVER) #include "TFT_Drivers/RPI_ILI9486_Init.h" +#elif defined (ILI9481_DRIVER) + #include "TFT_Drivers/ILI9481_Init.h" + +#elif defined (ILI9488_DRIVER) + #include "TFT_Drivers/ILI9488_Init.h" + +#elif defined (HX8357D_DRIVER) + #include "TFT_Drivers/HX8357D_Init.h" + #endif spi_end(); @@ -297,6 +353,15 @@ void TFT_eSPI::setRotation(uint8_t m) #elif defined (RPI_ILI9486_DRIVER) #include "TFT_Drivers/RPI_ILI9486_Rotation.h" +#elif defined (ILI9481_DRIVER) + #include "TFT_Drivers/ILI9481_Rotation.h" + +#elif defined (ILI9488_DRIVER) + #include "TFT_Drivers/ILI9488_Rotation.h" + +#elif defined (HX8357D_DRIVER) + #include "TFT_Drivers/HX8357D_Rotation.h" + #endif delayMicroseconds(10); @@ -350,7 +415,7 @@ void TFT_eSPI::commandList (const uint8_t *addr) ***************************************************************************************/ void TFT_eSPI::spiwrite(uint8_t c) { - SPI.transfer(c); + transfer8(c); } @@ -362,10 +427,9 @@ void TFT_eSPI::writecommand(uint8_t c) { DC_C; CS_L; - #ifdef SEND_16_BITS - SPI.transfer(0); - #endif - SPI.transfer(c); + + transfer8(c); + CS_H; DC_D; } @@ -375,52 +439,71 @@ void TFT_eSPI::writecommand(uint8_t c) ** Function name: writedata ** Description: Send a 8 bit data value to the TFT ***************************************************************************************/ -void TFT_eSPI::writedata(uint8_t c) +void TFT_eSPI::writedata(uint8_t d) { CS_L; - #ifdef SEND_16_BITS - SPI.transfer(0); - #endif - SPI.transfer(c); + + transfer8(d); + CS_H; } /*************************************************************************************** -** Function name: readcommand8 (for ILI9341 Interface II i.e. IM [3:0] = "1101") +** Function name: readcommand8 ** Description: Read a 8 bit data value from an indexed command register ***************************************************************************************/ uint8_t TFT_eSPI::readcommand8(uint8_t cmd_function, uint8_t index) { + uint8_t reg = 0; +#ifdef ESP32_PARALLEL + + writecommand(cmd_function); // Sets DC and CS high + + busDir(dir_mask, INPUT); + + CS_L; + + // Read nth parameter (assumes caller discards 1st parameter or points index to 2nd) + while(index--) reg = readByte(); + + busDir(dir_mask, OUTPUT); + + CS_H; + +#else + // for ILI9341 Interface II i.e. IM [3:0] = "1101" spi_begin(); index = 0x10 + (index & 0x0F); DC_C; CS_L; - SPI.transfer(0xD9); + transfer8(0xD9); DC_D; - SPI.transfer(index); + transfer8(index); CS_H; DC_C; CS_L; - SPI.transfer(cmd_function); + transfer8(cmd_function); DC_D; - uint8_t reg = SPI.transfer(0); + reg = transfer8(0); CS_H; spi_end(); +#endif return reg; } /*************************************************************************************** -** Function name: readcommand16 (for ILI9341 Interface II i.e. IM [3:0] = "1101") +** Function name: readcommand16 ** Description: Read a 16 bit data value from an indexed command register ***************************************************************************************/ uint16_t TFT_eSPI::readcommand16(uint8_t cmd_function, uint8_t index) { - uint32_t reg = 0; + uint32_t reg; + reg |= (readcommand8(cmd_function, index + 0) << 8); reg |= (readcommand8(cmd_function, index + 1) << 0); @@ -429,7 +512,7 @@ uint16_t TFT_eSPI::readcommand16(uint8_t cmd_function, uint8_t index) /*************************************************************************************** -** Function name: readcommand32 (for ILI9341 Interface II i.e. IM [3:0] = "1101") +** Function name: readcommand32 ** Description: Read a 32 bit data value from an indexed command register ***************************************************************************************/ uint32_t TFT_eSPI::readcommand32(uint8_t cmd_function, uint8_t index) @@ -451,26 +534,124 @@ uint32_t TFT_eSPI::readcommand32(uint8_t cmd_function, uint8_t index) ***************************************************************************************/ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0) { +#if defined(ESP32_PARALLEL) + + readAddrWindow(x0, y0, x0, y0); // Sets CS low + + // Set masked pins D0- D7 to input + busDir(dir_mask, INPUT); + + // Dummy read to throw away don't care value + readByte(); + + // Fetch the 16 bit BRG pixel + //uint16_t rgb = (readByte() << 8) | readByte(); + +#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) // Read 3 bytes + + // Read window pixel 24 bit RGB values and fill in LS bits + uint16_t rgb = ((readByte() & 0xF8) << 8) | ((readByte() & 0xFC) << 3) | (readByte() >> 3); + + CS_H; + + // Set masked pins D0- D7 to output + busDir(dir_mask, OUTPUT); + + return rgb; + +#else // ILI9481 16 bit read + + // Fetch the 16 bit BRG pixel + uint16_t bgr = (readByte() << 8) | readByte(); + + CS_H; + + // Set masked pins D0- D7 to output + busDir(dir_mask, OUTPUT); + + // Swap Red and Blue (could check MADCTL setting to see if this is needed) + return (bgr>>11) | (bgr<<11) | (bgr & 0x7E0); +#endif + +#else // Not ESP32_PARALLEL + spi_begin(); readAddrWindow(x0, y0, x0, y0); // Sets CS low // Dummy read to throw away don't care value - SPI.transfer(0); + transfer8(0); // Read window pixel 24 bit RGB values - uint8_t r = SPI.transfer(0); - uint8_t g = SPI.transfer(0); - uint8_t b = SPI.transfer(0); + uint8_t r = transfer8(0); + uint8_t g = transfer8(0); + uint8_t b = transfer8(0); CS_H; spi_end(); return color565(r, g, b); + +#endif } +/*************************************************************************************** +** Function name: read byte - supports class functions +** Description: Read a byte from ESP32 8 bit data port +***************************************************************************************/ +// Bus MUST be set to input before calling this function! +uint8_t readByte(void) +{ + uint8_t b = 0; + +#ifdef ESP32_PARALLEL + RD_L; + uint32_t reg; // Read all GPIO pins 0-31 + reg = gpio_input_get(); // Read three times to allow for bus access time + reg = gpio_input_get(); + reg = gpio_input_get(); // Data should be stable now + RD_H; + + // Check GPIO bits used and build value + b = (((reg>>TFT_D0)&1) << 0); + b |= (((reg>>TFT_D1)&1) << 1); + b |= (((reg>>TFT_D2)&1) << 2); + b |= (((reg>>TFT_D3)&1) << 3); + b |= (((reg>>TFT_D4)&1) << 4); + b |= (((reg>>TFT_D5)&1) << 5); + b |= (((reg>>TFT_D6)&1) << 6); + b |= (((reg>>TFT_D7)&1) << 7); +#endif + + return b; +} + +/*************************************************************************************** +** Function name: masked GPIO direction control - supports class functions +** Description: Set masked ESP32 GPIO pins to input or output +***************************************************************************************/ +void busDir(uint32_t mask, uint8_t mode) +{ +#ifdef ESP32_PARALLEL + + // Supports GPIO 0 - 31 on ESP32 only + gpio_config_t gpio; + + gpio.pin_bit_mask = mask; + gpio.mode = GPIO_MODE_INPUT; + gpio.pull_up_en = GPIO_PULLUP_ENABLE; + gpio.pull_down_en = GPIO_PULLDOWN_DISABLE; + gpio.intr_type = GPIO_INTR_DISABLE; + + if (mode == OUTPUT) gpio.mode = GPIO_MODE_OUTPUT; + + gpio_config(&gpio); + +#endif +} + /*************************************************************************************** ** Function name: read rectangle (for SPI Interface II i.e. IM [3:0] = "1101") ** Description: Read 565 pixel colours from a defined area @@ -478,34 +659,73 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0) void TFT_eSPI::readRect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint16_t *data) { if ((x > _width) || (y > _height) || (w == 0) || (h == 0)) return; - + +#if defined(ESP32_PARALLEL) + + readAddrWindow(x, y, x + w - 1, y + h - 1); // Sets CS low + + // Set masked pins D0- D7 to input + busDir(dir_mask, INPUT); + + // Dummy read to throw away don't care value + readByte(); + + // Total pixel count + uint32_t len = w * h; + +#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) // Read 3 bytes + // Fetch the 24 bit RGB value + while (len--) { + // Assemble the RGB 16 bit colour + uint16_t rgb = ((readByte() & 0xF8) << 8) | ((readByte() & 0xFC) << 3) | (readByte() >> 3); + + // Swapped byte order for compatibility with pushRect() + *data++ = (rgb<<8) | (rgb>>8); + } +#else // ILI9481 reads as 16 bits + // Fetch the 16 bit BRG pixels + while (len--) { + // Read the BRG 16 bit colour + uint16_t bgr = (readByte() << 8) | readByte(); + + // Swap Red and Blue (could check MADCTL setting to see if this is needed) + uint16_t rgb = (bgr>>11) | (bgr<<11) | (bgr & 0x7E0); + + // Swapped byte order for compatibility with pushRect() + *data++ = (rgb<<8) | (rgb>>8); + } +#endif + CS_H; + + // Set masked pins D0- D7 to output + busDir(dir_mask, OUTPUT); + +#else // Not ESP32_PARALLEL + spi_begin(); readAddrWindow(x, y, x + w - 1, y + h - 1); // Sets CS low // Dummy read to throw away don't care value - SPI.transfer(0); + transfer8(0); // Read window pixel 24 bit RGB values uint32_t len = w * h; while (len--) { // Read the 3 RGB bytes, colour is actually only in the top 6 bits of each byte // as the TFT stores colours as 18 bits - uint8_t r = SPI.transfer(0); - uint8_t g = SPI.transfer(0); - uint8_t b = SPI.transfer(0); + uint8_t r = transfer8(0); + uint8_t g = transfer8(0); + uint8_t b = transfer8(0); + // Swapped colour byte order for compatibility with pushRect() *data++ = (r & 0xF8) | (g & 0xE0) >> 5 | (b & 0xF8) << 5 | (g & 0x1C) << 11; } - // Write NOP command to stop read mode - //DC_C; - //SPI.transfer(TFT_NOP); - //DC_D; - CS_H; spi_end(); +#endif } @@ -971,25 +1191,27 @@ bool TFT_eSPI::getSwapBytes(void) // If w and h are 1, then 1 pixel is read, *data array size must be 3 bytes per pixel void TFT_eSPI::readRectRGB(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_t *data) { +#if !defined(ESP32_PARALLEL) spi_begin(); readAddrWindow(x0, y0, x0 + w - 1, y0 + h - 1); // Sets CS low // Dummy read to throw away don't care value - SPI.transfer(0); + transfer8(0); // Read window pixel 24 bit RGB values, buffer must be set in sketch to 3 * w * h uint32_t len = w * h; while (len--) { // Read the 3 RGB bytes, colour is actually only in the top 6 bits of each byte // as the TFT stores colours as 18 bits - *data++ = SPI.transfer(0); - *data++ = SPI.transfer(0); - *data++ = SPI.transfer(0); + *data++ = transfer8(0); + *data++ = transfer8(0); + *data++ = transfer8(0); } CS_H; spi_end(); +#endif } @@ -997,41 +1219,6 @@ void TFT_eSPI::readRectRGB(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_ ** Function name: drawCircle ** Description: Draw a circle outline ***************************************************************************************/ -/* -// Midpoint circle algorithm, we can optimise this since y = 0 on first pass -// and we can eliminate the multiply as well -void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t radius, uint32_t color) -{ - int32_t x = radius; - int32_t y = 0; - int32_t err = 0; - - while (x >= y) - { - drawPixel(x0 + x, y0 + y, color); - drawPixel(x0 + x, y0 - y, color); - drawPixel(x0 - x, y0 - y, color); - drawPixel(x0 - x, y0 + y, color); - - drawPixel(x0 + y, y0 + x, color); - drawPixel(x0 + y, y0 - x, color); - drawPixel(x0 - y, y0 - x, color); - drawPixel(x0 - y, y0 + x, color); - - if (err <= 0) - { - y += 1; - err += 2*y + 1; - } - if (err > 0) - { - x -= 1; - err -= 2*x + 1; - } - } -} -*/ - // Optimised midpoint circle algorithm void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) { @@ -1127,7 +1314,6 @@ void TFT_eSPI::drawCircleHelper( int32_t x0, int32_t y0, int32_t r, uint8_t corn ***************************************************************************************/ // Optimised midpoint circle algorithm, changed to horizontal lines (faster in sprites) void TFT_eSPI::fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) - { int32_t x = 0; int32_t dx = 1; @@ -1848,20 +2034,16 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, u while(SPI1CMD & SPIBUSY) {} } #else // for ESP32 + for (int8_t j = 0; j < 8; j++) { for (int8_t k = 0; k < 5; k++ ) { - if (column[k] & mask) { - SPI.write16(color); - } - else { - SPI.write16(bg); - } + if (column[k] & mask) {transfer16(color);} + else {transfer16(bg);} } - mask <<= 1; - - SPI.write16(bg); + transfer16(bg); } + #endif CS_H; //inTransaction = false; @@ -2051,7 +2233,6 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, u ** Description: define an area to receive a stream of pixels ***************************************************************************************/ // Chip select is high at the end of this function - void TFT_eSPI::setWindow(int16_t x0, int16_t y0, int16_t x1, int16_t y1) { spi_begin(); @@ -2291,49 +2472,34 @@ inline void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t DC_C; CS_L; -#if defined (RPI_ILI9486_DRIVER) - SPI.write16(TFT_CASET); -#else - SPI.write(TFT_CASET); -#endif + transfer8(TFT_CASET); DC_D; - #if defined (RPI_ILI9486_DRIVER) uint8_t xBin[] = { 0, (uint8_t) (x0>>8), 0, (uint8_t) (x0>>0), 0, (uint8_t) (x1>>8), 0, (uint8_t) (x1>>0), }; SPI.writePattern(&xBin[0], 8, 1); #else - SPI.write32(xaw); + transfer32(xaw); #endif // Row addr set DC_C; - -#if defined (RPI_ILI9486_DRIVER) - SPI.write16(TFT_PASET); -#else - SPI.write(TFT_PASET); -#endif + transfer8(TFT_PASET); DC_D; - #if defined (RPI_ILI9486_DRIVER) uint8_t yBin[] = { 0, (uint8_t) (y0>>8), 0, (uint8_t) (y0>>0), 0, (uint8_t) (y1>>8), 0, (uint8_t) (y1>>0), }; SPI.writePattern(&yBin[0], 8, 1); #else - SPI.write32(yaw); + transfer32(yaw); #endif // write to RAM DC_C; -#if defined (RPI_ILI9486_DRIVER) - SPI.write16(TFT_RAMWR); -#else - SPI.write(TFT_RAMWR); -#endif + transfer8(TFT_RAMWR); DC_D; @@ -2436,23 +2602,25 @@ void TFT_eSPI::readAddrWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1) DC_C; CS_L; - SPI.write(TFT_CASET); + transfer8(TFT_CASET); + DC_D; - SPI.write32(xaw); + transfer32(xaw); // Row addr set DC_C; - SPI.write(TFT_PASET); + transfer8(TFT_PASET); DC_D; - SPI.write32(yaw); + transfer32(yaw); DC_C; - SPI.transfer(TFT_RAMRD); // Read CGRAM command + transfer8(TFT_RAMRD); // Read CGRAM command + DC_D; //spi_end(); @@ -2669,11 +2837,7 @@ void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color) DC_C; -#if defined (RPI_ILI9486_DRIVER) - SPI.write16(TFT_CASET); -#else - SPI.write(TFT_CASET); -#endif + transfer8(TFT_CASET); DC_D; @@ -2681,7 +2845,7 @@ void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color) uint8_t xBin[] = { 0, (uint8_t) (x>>8), 0, (uint8_t) (x>>0), 0, (uint8_t) (x>>8), 0, (uint8_t) (x>>0), }; SPI.writePattern(&xBin[0], 8, 1); #else - SPI.write32(xaw); + transfer32(xaw); #endif addr_col = x; @@ -2692,11 +2856,7 @@ void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color) DC_C; -#if defined (RPI_ILI9486_DRIVER) - SPI.write16(TFT_PASET); -#else - SPI.write(TFT_PASET); -#endif + transfer8(TFT_PASET); DC_D; @@ -2704,7 +2864,7 @@ void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color) uint8_t yBin[] = { 0, (uint8_t) (y>>8), 0, (uint8_t) (y>>0), 0, (uint8_t) (y>>8), 0, (uint8_t) (y>>0), }; SPI.writePattern(&yBin[0], 8, 1); #else - SPI.write32(yaw); + transfer32(yaw); #endif addr_row = y; @@ -2712,15 +2872,11 @@ void TFT_eSPI::drawPixel(uint32_t x, uint32_t y, uint32_t color) DC_C; -#if defined (RPI_ILI9486_DRIVER) - SPI.write16(TFT_RAMWR); -#else - SPI.write(TFT_RAMWR); -#endif + transfer8(TFT_RAMWR); DC_D; - SPI.write16(color); + transfer16(color); CS_H; @@ -2739,11 +2895,9 @@ void TFT_eSPI::pushColor(uint16_t color) spi_begin(); CS_L; -#if defined (ESP8266) - SPI.write16(color, true); -#else - SPI.write16(color); -#endif + + transfer16(color); + CS_H; spi_end(); @@ -2765,7 +2919,11 @@ void TFT_eSPI::pushColor(uint16_t color, uint16_t len) if(len) SPI.writePattern(&colorBin[0], 2, 1); len--; while(len--) {WR_L; WR_H;} #else - spiWriteBlock(color, len); + #ifdef ESP32_PARALLEL + while (len--) {transfer16(color);} + #else + writeBlock(color, len); + #endif #endif CS_H; @@ -2789,11 +2947,15 @@ void TFT_eSPI::pushColors(uint8_t *data, uint32_t len) while ( len >=64 ) {SPI.writePattern(data, 64, 1); data += 64; len -= 64; } if (len) SPI.writePattern(data, len, 1); #else - #if (SPI_FREQUENCY == 80000000) - while ( len >=64 ) {SPI.writePattern(data, 64, 1); data += 64; len -= 64; } - if (len) SPI.writePattern(data, len, 1); + #ifdef ESP32_PARALLEL + while (len--) {transfer8(*data); data++;} #else - SPI.writeBytes(data, len); + #if (SPI_FREQUENCY == 80000000) + while ( len >=64 ) {SPI.writePattern(data, 64, 1); data += 64; len -= 64; } + if (len) SPI.writePattern(data, len, 1); + #else + SPI.writeBytes(data, len); + #endif #endif #endif @@ -2814,10 +2976,13 @@ void TFT_eSPI::pushColors(uint16_t *data, uint32_t len, bool swap) CS_L; #if defined (ESP32) - -if (swap) SPI.writePixels(data,len<<1); -else SPI.writeBytes((uint8_t*)data,len<<1); - + #ifdef ESP32_PARALLEL + if (swap) while ( len-- ) {transfer16(*data); data++;} + else while ( len-- ) {transwap16(*data); data++;} + #else + if (swap) SPI.writePixels(data,len<<1); + else SPI.writeBytes((uint8_t*)data,len<<1); + #endif #else uint32_t color[8]; @@ -2889,41 +3054,6 @@ else SPI.writeBytes((uint8_t*)data,len<<1); SPI1CMD |= SPIBUSY; } -/* // Smaller version but slower - uint32_t count = 0; - while(len) - { - if(len>15) {count = 16; len -= 16;} - else {count = len; len = 0;} - uint32_t bits = (count*16-1); // bits left to shift - 1 - if (swap) - { - uint16_t* ptr = (uint16_t*)color; - while(count--) - { - *ptr++ = (*(data) >> 8) | (uint16_t)(*(data) << 8); - data++; - } - } - else - { - memcpy(color,data,count<<1); - data += 16; - } - while(SPI1CMD & SPIBUSY) {} - SPI1U1 = (SPI1U1 & mask) | (bits << SPILMOSI) | (bits << SPILMISO); - SPI1W0 = color[0]; - SPI1W1 = color[1]; - SPI1W2 = color[2]; - SPI1W3 = color[3]; - SPI1W4 = color[4]; - SPI1W5 = color[5]; - SPI1W6 = color[6]; - SPI1W7 = color[7]; - SPI1CMD |= SPIBUSY; - } -*/ - while(SPI1CMD & SPIBUSY) {} #endif @@ -3123,7 +3253,7 @@ void TFT_eSPI::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color) setAddrWindow(x, y, x, y + h - 1); - spiWriteBlock(color, h); + writeBlock(color, h); CS_H; @@ -3144,17 +3274,21 @@ void TFT_eSPI::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color) #ifdef RPI_WRITE_STROBE #if defined (ESP8266) + // SPI1U1 will already be set to transfer 16 bits by setAddrWindow() SPI1W0 = (color >> 8) | (color << 8); SPI1CMD |= SPIBUSY; while(SPI1CMD & SPIBUSY) {} #else - SPI.write16(color); + transfer16(color); #endif - h--; - while(h--) {WR_L; WR_H;} + h--; + while(h--) {WR_L; WR_H;} #else - //while(h--) SPI.write16(color); - spiWriteBlock(color, h); + #ifdef ESP32_PARALLEL + while (h--) {transfer16(color);} + #else + writeBlock(color, h); + #endif #endif CS_H; @@ -3178,7 +3312,7 @@ void TFT_eSPI::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color) setAddrWindow(x, y, x + w - 1, y); - spiWriteBlock(color, w); + writeBlock(color, w); CS_H; @@ -3198,17 +3332,21 @@ void TFT_eSPI::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color) #ifdef RPI_WRITE_STROBE #if defined (ESP8266) + // SPI1U1 will already be set to transfer 16 bits by setAddrWindow() SPI1W0 = (color >> 8) | (color << 8); SPI1CMD |= SPIBUSY; while(SPI1CMD & SPIBUSY) {} #else - SPI.write16(color); + transfer16(color); #endif - w--; - while(w--) {WR_L; WR_H;} + w--; + while(w--) {WR_L; WR_H;} #else - //while(w--) SPI.write16(color); - spiWriteBlock(color, w); + #ifdef ESP32_PARALLEL + while (w--) {transfer16(color);} + #else + writeBlock(color, w); + #endif #endif CS_H; @@ -3232,7 +3370,7 @@ void TFT_eSPI::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t col spi_begin(); setAddrWindow(x, y, x + w - 1, y + h - 1); - spiWriteBlock(color, w * h); + writeBlock(color, w * h); CS_H; @@ -3254,11 +3392,23 @@ void TFT_eSPI::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t col uint32_t n = (uint32_t)w * (uint32_t)h; #ifdef RPI_WRITE_STROBE - if(n) {SPI.write16(color); n--;} + transfer16(color); while(n--) {WR_L; WR_H;} #else - //while(n--) SPI.write16(color); - spiWriteBlock(color, n); + #ifdef ESP32_PARALLEL + if (color>>8 == (uint8_t)color) + { + transfer8(color); + n--; WR_L; WR_H; + while (n) {WR_L; WR_H; n--; WR_L; WR_H;} + } + else + { + while (n--) {transfer16(color);} + } + #else + writeBlock(color, n); + #endif #endif CS_H; @@ -3612,12 +3762,8 @@ int16_t TFT_eSPI::drawChar(unsigned int uniCode, int x, int y, int font) pX = x + k * 8; mask = 0x80; while (mask) { - if (line & mask) { - SPI.write16(textcolor); - } - else { - SPI.write16(textbgcolor); - } + if (line & mask) {transfer16(textcolor);} + else {transfer16(textbgcolor);} mask = mask >> 1; } } @@ -3671,13 +3817,9 @@ int16_t TFT_eSPI::drawChar(unsigned int uniCode, int x, int y, int font) if (ts) { tnp = np; - while (tnp--) { - SPI.write16(textcolor); - } - } - else { - SPI.write16(textcolor); + while (tnp--) {transfer16(textcolor);} } + else {transfer16(textcolor);} px += textsize; if (px >= (x + width * textsize)) @@ -3716,7 +3858,11 @@ int16_t TFT_eSPI::drawChar(unsigned int uniCode, int x, int y, int font) SPI.writePattern(&textcolorBin[0], 2, 1); line--; while(line--) {WR_L; WR_H;} #else - spiWriteBlock(textcolor,line); + #ifdef ESP32_PARALLEL + while (line--) {transfer16(textcolor);} + #else + writeBlock(textcolor,line); + #endif #endif } else { @@ -3725,7 +3871,11 @@ int16_t TFT_eSPI::drawChar(unsigned int uniCode, int x, int y, int font) SPI.writePattern(&textbgcolorBin[0], 2, 1); line--; while(line--) {WR_L; WR_H;} #else - spiWriteBlock(textbgcolor,line); + #ifdef ESP32_PARALLEL + while (line--) {transfer16(textbgcolor);} + #else + writeBlock(textbgcolor,line); + #endif #endif } } @@ -4199,8 +4349,8 @@ void TFT_eSPI::setTextFont(uint8_t f) // TFT_eSPI 98.06% 97.59% 94.24% // Adafruit_GFX 19.62% 14.31% 7.94% // -#if defined (ESP8266) // && (SPI_FREQUENCY != 80000000) -void spiWriteBlock(uint16_t color, uint32_t repeat) +#if defined (ESP8266) +void writeBlock(uint16_t color, uint32_t repeat) { uint16_t color16 = (color >> 8) | (color << 8); uint32_t color32 = color16 | color16 << 16; @@ -4259,23 +4409,12 @@ void spiWriteBlock(uint16_t color, uint32_t repeat) SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE; } -//#elif ESP8266 // ESP32 or a ESP8266 running at 80MHz SPI so slow things down -// -//#define BUFFER_SIZE 64 -//void spiWriteBlock(uint16_t color, uint32_t repeat) -//{ -// -// uint8_t colorBin[] = { (uint8_t) (color >> 8), (uint8_t) color}; -// SPI.writePattern(&colorBin[0], 2, repeat); -// -//} - #else // Low level register based ESP32 code #include "soc/spi_reg.h" #define SPI_NUM 0x3 -void spiWriteBlock(uint16_t color, uint32_t repeat) +void writeBlock(uint16_t color, uint32_t repeat) { uint16_t color16 = (color >> 8) | (color << 8); uint32_t color32 = color16 | color16 << 16; diff --git a/TFT_eSPI.h b/TFT_eSPI.h index 8148f59..22610f8 100644 --- a/TFT_eSPI.h +++ b/TFT_eSPI.h @@ -65,6 +65,12 @@ #ifndef LOAD_RLE #define LOAD_RLE #endif +#elif defined LOAD_FONT8N + #define LOAD_FONT8 + #include + #ifndef LOAD_RLE + #define LOAD_RLE + #endif #endif #include @@ -89,10 +95,13 @@ #define DC_C digitalWrite(TFT_DC, LOW) #define DC_D digitalWrite(TFT_DC, HIGH) #elif defined (ESP32) - //#define DC_C digitalWrite(TFT_DC, HIGH); GPIO.out_w1tc = (1 << TFT_DC)//digitalWrite(TFT_DC, LOW) - //#define DC_D digitalWrite(TFT_DC, LOW); GPIO.out_w1ts = (1 << TFT_DC)//digitalWrite(TFT_DC, HIGH) - #define DC_C GPIO.out_w1ts = (1 << TFT_DC); GPIO.out_w1ts = (1 << TFT_DC); GPIO.out_w1tc = (1 << TFT_DC) - #define DC_D GPIO.out_w1tc = (1 << TFT_DC); GPIO.out_w1ts = (1 << TFT_DC) + #if defined (ESP32_PARALLEL) + #define DC_C GPIO.out_w1tc = (1 << TFT_DC) // Too fast for ST7735 + #define DC_D GPIO.out_w1ts = (1 << TFT_DC) + #else + #define DC_C GPIO.out_w1ts = (1 << TFT_DC); GPIO.out_w1tc = (1 << TFT_DC) + #define DC_D GPIO.out_w1tc = (1 << TFT_DC); GPIO.out_w1ts = (1 << TFT_DC) + #endif #else #define DC_C GPOC=dcpinmask #define DC_D GPOS=dcpinmask @@ -110,10 +119,13 @@ #define CS_L digitalWrite(TFT_CS, LOW) #define CS_H digitalWrite(TFT_CS, HIGH) #elif defined (ESP32) - //#define CS_L digitalWrite(TFT_CS, HIGH); GPIO.out_w1tc = (1 << TFT_CS)//digitalWrite(TFT_CS, LOW) - //#define CS_H digitalWrite(TFT_CS, LOW); GPIO.out_w1ts = (1 << TFT_CS)//digitalWrite(TFT_CS, HIGH) - #define CS_L GPIO.out_w1ts = (1 << TFT_CS);GPIO.out_w1tc = (1 << TFT_CS) - #define CS_H GPIO.out_w1tc = (1 << TFT_CS);GPIO.out_w1ts = (1 << TFT_CS) + #if defined (ESP32_PARALLEL) + #define CS_L // The TFT CS is set permanently low during init() + #define CS_H + #else + #define CS_L GPIO.out_w1ts = (1 << TFT_CS);GPIO.out_w1tc = (1 << TFT_CS) + #define CS_H GPIO.out_w1tc = (1 << TFT_CS);GPIO.out_w1ts = (1 << TFT_CS) + #endif #else #define CS_L GPOC=cspinmask #define CS_H GPOS=cspinmask @@ -133,15 +145,66 @@ #ifdef TFT_WR #if defined (ESP32) #define WR_L GPIO.out_w1tc = (1 << TFT_WR) - //digitalWrite(TFT_WR, LOW) + //#define WR_L digitalWrite(TFT_WR, LOW) #define WR_H GPIO.out_w1ts = (1 << TFT_WR) - //digitalWrite(TFT_WR, HIGH) + //#define WR_H digitalWrite(TFT_WR, HIGH) #else #define WR_L GPOC=wrpinmask #define WR_H GPOS=wrpinmask #endif #endif + +#ifdef ESP32_PARALLEL + + #define dir_mask ((1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7)) + + #define clr_mask (dir_mask | (1 << TFT_WR)) + + #define set_mask(C) xset_mask[C] // 63fps Sprite rendering test 33% faster, graphicstest only 1.8% faster than shifting in real time + + // Real-time shifting alternative to above to save 1KByte RAM, 47 fps Sprite rendering test + //#define set_mask(C) ((C&0x80)>>7)<>6)<>5)<>4)<>3)<>2)<>1)<>0)<> 8)); WR_H; \ + GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 0)); WR_H + + // 16 bit transfer with swapped bytes + #define transwap16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 0)); WR_H; \ + GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 8)); WR_H + + #define transfer32(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 24)); WR_H; \ + GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 16)); WR_H; \ + GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 8)); WR_H; \ + GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 0)); WR_H + + #ifdef TFT_RD + #if defined (ESP32) + #define RD_L GPIO.out_w1tc = (1 << TFT_RD) + //#define RD_L digitalWrite(TFT_WR, LOW) + #define RD_H GPIO.out_w1ts = (1 << TFT_RD) + //#define RD_H digitalWrite(TFT_WR, HIGH) + #else + //#define RD_L GPOC=rdpinmask + //#define RD_H GPOS=rdpinmask + #endif + #endif + +#elif defined (SEND_16_BITS) + #define transfer8(C) SPI.transfer(0); SPI.transfer(C) + #define transfer16(C) SPI.write16(C) + #define transfer32(C) SPI.write32(C) + +#else + #define transfer8(C) SPI.transfer(C) + #define transfer16(C) SPI.write16(C) + #define transfer32(C) SPI.write32(C) + +#endif + #ifdef LOAD_GFXFF // We can include all the free fonts and they will only be built into // the sketch if they are used @@ -402,6 +465,7 @@ class TFT_eSPI : public Print { spiwrite(uint8_t), writecommand(uint8_t c), writedata(uint8_t d), + commandList(const uint8_t *addr); uint8_t readcommand8(uint8_t cmd_function, uint8_t index); @@ -497,6 +561,10 @@ class TFT_eSPI : public Print { uint32_t cspinmask, dcpinmask, wrpinmask; +#if defined(ESP32_PARALLEL) + uint32_t xclr_mask, xdir_mask, xset_mask[256]; +#endif + uint32_t lastColor = 0xFFFF; diff --git a/Tools/Create_Smooth_Font/Create_font_5/Create_font_5.pde b/Tools/Create_Smooth_Font/Create_font/Create_font.pde similarity index 98% rename from Tools/Create_Smooth_Font/Create_font_5/Create_font_5.pde rename to Tools/Create_Smooth_Font/Create_font/Create_font.pde index d89d6a9..fbd6b91 100644 --- a/Tools/Create_Smooth_Font/Create_font_5/Create_font_5.pde +++ b/Tools/Create_Smooth_Font/Create_font/Create_font.pde @@ -1,3 +1,5 @@ +// This is a Processing sketch, see https://processing.org/ to download the IDE + // Select the character range in the user configure section starting at line 100 /* @@ -107,7 +109,7 @@ String fontType = ".ttf"; //SPIFFS does not accept underscore in file //String fontType = ".otf"; // Use font number instead of name, -1 means use name above, or a value >=0 means use system font number from list. -int fontNumber = -1; // << Use [Number] in brackets from the fonts listed in console window +int fontNumber = 22; // << Use [Number] in brackets from the fonts listed in console window // Define the font size in points for the created font file int fontSize = 28; @@ -310,7 +312,7 @@ static final int[] specificUnicodes = { //*/ // More characters, change next line to //* to use - /* + //* 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x010C, 0x010D, 0x010E, 0x010F, 0x0110, 0x0111, 0x0118, 0x0119, 0x011A, 0x011B, @@ -413,8 +415,12 @@ void setup() { charset[index] = Character.toChars(specificUnicodes[i])[0]; index++; } + + // Make font smooth + boolean smooth = true; + // Create the font in memory - myFont = createFont(fontName+fontType, 32, true, charset); + myFont = createFont(fontName+fontType, displayFontSize, smooth, charset); // Print a few characters to the sketch window fill(0, 0, 0); @@ -455,9 +461,9 @@ void setup() { // creating font PFont font; - font = createFont(fontName+fontType, fontSize, true, charset); + font = createFont(fontName+fontType, fontSize, smooth, charset); - println("Created font " + fontName + ".vlw"); + println("Created font " + fontName + str(fontSize) + ".vlw"); // creating file try { diff --git a/Tools/Create_Smooth_Font/Create_font_5/data/Final-Frontier.ttf b/Tools/Create_Smooth_Font/Create_font/data/Final-Frontier.ttf similarity index 100% rename from Tools/Create_Smooth_Font/Create_font_5/data/Final-Frontier.ttf rename to Tools/Create_Smooth_Font/Create_font/data/Final-Frontier.ttf diff --git a/User_Setup.h b/User_Setup.h index 3d61313..fc2bb2b 100644 --- a/User_Setup.h +++ b/User_Setup.h @@ -6,6 +6,7 @@ // // If this file is edited correctly then all the library example sketches should // run without the need to make any more changes for a particular hardware setup! +// Note that some sketches are designed for a particular TFT pixel width/height // ################################################################################## // @@ -19,6 +20,9 @@ //#define ILI9163_DRIVER //#define S6D02A1_DRIVER //#define RPI_ILI9486_DRIVER // 20MHz maximum SPI +//#define HX8357D_DRIVER +//#define ILI9481_DRIVER +//#define ILI9488_DRIVER // For M5Stack ESP32 module with integrated display ONLY, remove // in line below //#define M5STACK @@ -134,6 +138,35 @@ //#define TFT_WR 22 // Write strobe for modified Raspberry Pi TFT only +// ###### EDIT THE PINs BELOW TO SUIT YOUR ESP32 PARALLEL TFT SETUP ###### + +// The library supports 8 bit parallel TFTs with the ESP32, the pin +// selection below is compatible with ESP32 boards in UNO format. +// Wemos D32 boards need to be modified, see diagram in Tools folder. +// Only ILI9481 and ILI9341 based displays have been tested! + +// Parallel bus is only supported on ESP32 +// Uncomment line below to use ESP32 Parallel interface instead of SPI + +//#define ESP32_PARALLEL + +// The ESP32 and TFT the pins used for testing are: +//#define TFT_CS 33 // Chip select control pin (library pulls permanently low +//#define TFT_DC 15 // Data Command control pin - use a pin in the range 0-31 +//#define TFT_RST 32 // Reset pin, toggles on startup + +//#define TFT_WR 4 // Write strobe control pin - use a pin in the range 0-31 +//#define TFT_RD 2 // Read strobe control pin - use a pin in the range 0-31 + +//#define TFT_D0 12 // Must use pins in the range 0-31 for the data bus +//#define TFT_D1 13 // so a single register write sets/clears all bits. +//#define TFT_D2 26 // Pins can be randomly assigned, this does not affect +//#define TFT_D3 25 // TFT screen update performance. +//#define TFT_D4 17 +//#define TFT_D5 16 +//#define TFT_D6 27 +//#define TFT_D7 14 + // ################################################################################## // // Section 2. Define the way the DC and/or CS lines are driven (ESP8266 only) @@ -166,6 +199,7 @@ #define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm #define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-. #define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-. +//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT #define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts // Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded diff --git a/User_Setup_Select.h b/User_Setup_Select.h index 93a0ac8..c4e720b 100644 --- a/User_Setup_Select.h +++ b/User_Setup_Select.h @@ -33,6 +33,10 @@ //#include // Setup file configured for my stock RPi TFT with touch //#include // Setup file configured for my stock RPi TFT with touch //#include // Setup file for the ESP32 based M5Stack +//#include // Setup file for the ESP32 with parallel bus TFT +//#include // Setup file for the ESP32 with parallel bus TFT +//#include // Setup file configured for HX8357D (untested) +//#include // Setup file for the ESP32 with parallel bus TFT //#include @@ -62,6 +66,12 @@ #include #elif defined (RPI_ILI9486_DRIVER) #include +#elif defined (ILI9481_DRIVER) + #include +#elif defined (ILI9488_DRIVER) + #include +#elif defined (HX8357D_DRIVER) + #include "TFT_Drivers/HX8357D_Defines.h" #endif // These are the pins for all ESP8266 boards diff --git a/library.json b/library.json index 019b150..bdf5b64 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TFT_eSPI", - "version": "0.18.21", + "version": "0.19.10", "keywords": "tft, display, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486", "description": "A TFT SPI graphics library for ESP8266 and ESP32", "repository": diff --git a/library.properties b/library.properties index 1f05e67..7b582f6 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TFT_eSPI -version=0.18.21 +version=0.19.10 author=Bodmer maintainer=Bodmer sentence=A fast TFT library for ESP8266 processors and the Arduino IDE