├── test128x160.bmp ├── offscreen-buffer.py ├── tftbmp.py ├── README.md ├── graphicstest.py └── ST7735.py /test128x160.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boochow/MicroPython-ST7735/HEAD/test128x160.bmp -------------------------------------------------------------------------------- /offscreen-buffer.py: -------------------------------------------------------------------------------- 1 | from machine import SPI,Pin 2 | from ST7735 import TFT 3 | spi = SPI(0, baudrate=20000000, polarity=0, phase=0, sck=Pin(2), mosi=Pin(3), miso=Pin(0)) 4 | tft=TFT(spi,4,5,1) 5 | tft.initr() 6 | tft.rgb(True) 7 | tft.fill(TFT.BLACK) 8 | 9 | from framebuf import FrameBuffer, RGB565 10 | buf = bytearray(128*160*2) 11 | fb = FrameBuffer(buf, 128, 160, RGB565) 12 | 13 | tft._setwindowloc((0,0),(127,159)) 14 | 15 | size=20 16 | (xmax, ymax) = (128-size, 160-size) 17 | (x, y) = (size, size) 18 | (vx, vy) = (1, 1) 19 | 20 | while True: 21 | fb.fill(0) 22 | fb.ellipse(x, y, size, size, 0xffff, True) 23 | x += vx 24 | if x == xmax or x == size: 25 | vx = -vx 26 | y += vy 27 | if y == ymax or y == size: 28 | vy = -vy 29 | tft._writedata(buf) 30 | -------------------------------------------------------------------------------- /tftbmp.py: -------------------------------------------------------------------------------- 1 | from ST7735 import TFT,TFTColor 2 | from machine import SPI,Pin 3 | spi = SPI(2, baudrate=20000000, polarity=0, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12)) 4 | tft=TFT(spi,16,17,18) 5 | tft.initr() 6 | tft.rgb(True) 7 | tft.fill(TFT.BLACK) 8 | 9 | f=open('test128x160.bmp', 'rb') 10 | if f.read(2) == b'BM': #header 11 | dummy = f.read(8) #file size(4), creator bytes(4) 12 | offset = int.from_bytes(f.read(4), 'little') 13 | hdrsize = int.from_bytes(f.read(4), 'little') 14 | width = int.from_bytes(f.read(4), 'little') 15 | height = int.from_bytes(f.read(4), 'little') 16 | if int.from_bytes(f.read(2), 'little') == 1: #planes must be 1 17 | depth = int.from_bytes(f.read(2), 'little') 18 | if depth == 24 and int.from_bytes(f.read(4), 'little') == 0:#compress method == uncompressed 19 | print("Image size:", width, "x", height) 20 | rowsize = (width * 3 + 3) & ~3 21 | if height < 0: 22 | height = -height 23 | flip = False 24 | else: 25 | flip = True 26 | w, h = width, height 27 | if w > 128: w = 128 28 | if h > 160: h = 160 29 | tft._setwindowloc((0,0),(w - 1,h - 1)) 30 | for row in range(h): 31 | if flip: 32 | pos = offset + (height - 1 - row) * rowsize 33 | else: 34 | pos = offset + row * rowsize 35 | if f.tell() != pos: 36 | dummy = f.seek(pos) 37 | for col in range(w): 38 | bgr = f.read(3) 39 | tft._pushcolor(TFTColor(bgr[2],bgr[1],bgr[0])) 40 | spi.deinit() 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MicroPython-ST7735 2 | 3 | This is a modified version of [GuyCarver's ST7735.py](https://github.com/GuyCarver/MicroPython/blob/master/lib/ST7735.py) ST7735 TFT LCD driver for MicroPython. 4 | 5 | A font file is necessary for displaying text (some font files are in [GuyCarver's repo](https://github.com/GuyCarver/MicroPython/tree/master/lib)). 6 | 7 | Text nowrap option added(default: nowrap=False). 8 | 9 | `graphicstest.py` is a sample code. I wrote this to make it similar to [Adafruit's graphicstest sketch for Arduino](https://github.com/adafruit/Adafruit-ST7735-Library/tree/master/examples/graphicstest). 10 | 11 | If `graphicstest.py` doesn't work correctly, try replaceing `initr()` at line 8 to `initg()` or `initb()` or `initb2()`. You can also change `rgb(True)` to `rgb(False)` to switch red and blue pixels if your LCD module shows incorrect colors. 12 | 13 | Pin connections for ESP32: 14 | 15 | LCD |ESP32-DevKitC 16 | ----|---- 17 | VLED|3V3 18 | RST |IO17 19 | A0 |IO16(DC) 20 | SDA |IO13(MOSI) 21 | SCK |IO14(CLK) 22 | VCC |3V3 23 | CS |IO18 24 | GND |GND 25 | 26 | [![YouTube image here](https://img.youtube.com/vi/xIy8DPBZsIk/0.jpg)](https://www.youtube.com/watch?v=xIy8DPBZsIk) 27 | 28 | `tftbmp.py` is another sample similar to [Adafruit's tftbmp sketch for Arduino](https://github.com/adafruit/Adafruit-ST7735-Library/blob/master/examples/spitftbitmap/spitftbitmap.ino). 29 | 30 | Place bmp file named `test128x160.bmp` in the file system of MicroPython using file uploading tool such as [ampy](https://github.com/adafruit/ampy), etc. 31 | 32 | `offscreen-buffer.py` shows how you can use an offscreen frame buffer which is an instance of FrameBuffer class. I tested this on Raspberry Pi Pico. See https://github.com/boochow/MicroPython-ST7735/issues/9 for the pin connections. -------------------------------------------------------------------------------- /graphicstest.py: -------------------------------------------------------------------------------- 1 | from ST7735 import TFT 2 | from sysfont import sysfont 3 | from machine import SPI,Pin 4 | import time 5 | import math 6 | spi = SPI(2, baudrate=20000000, polarity=0, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12)) 7 | tft=TFT(spi,16,17,18) 8 | tft.initr() 9 | tft.rgb(True) 10 | 11 | def testlines(color): 12 | tft.fill(TFT.BLACK) 13 | for x in range(0, tft.size()[0], 6): 14 | tft.line((0,0),(x, tft.size()[1] - 1), color) 15 | for y in range(0, tft.size()[1], 6): 16 | tft.line((0,0),(tft.size()[0] - 1, y), color) 17 | 18 | tft.fill(TFT.BLACK) 19 | for x in range(0, tft.size()[0], 6): 20 | tft.line((tft.size()[0] - 1, 0), (x, tft.size()[1] - 1), color) 21 | for y in range(0, tft.size()[1], 6): 22 | tft.line((tft.size()[0] - 1, 0), (0, y), color) 23 | 24 | tft.fill(TFT.BLACK) 25 | for x in range(0, tft.size()[0], 6): 26 | tft.line((0, tft.size()[1] - 1), (x, 0), color) 27 | for y in range(0, tft.size()[1], 6): 28 | tft.line((0, tft.size()[1] - 1), (tft.size()[0] - 1,y), color) 29 | 30 | tft.fill(TFT.BLACK) 31 | for x in range(0, tft.size()[0], 6): 32 | tft.line((tft.size()[0] - 1, tft.size()[1] - 1), (x, 0), color) 33 | for y in range(0, tft.size()[1], 6): 34 | tft.line((tft.size()[0] - 1, tft.size()[1] - 1), (0, y), color) 35 | 36 | def testfastlines(color1, color2): 37 | tft.fill(TFT.BLACK) 38 | for y in range(0, tft.size()[1], 5): 39 | tft.hline((0,y), tft.size()[0], color1) 40 | for x in range(0, tft.size()[0], 5): 41 | tft.vline((x,0), tft.size()[1], color2) 42 | 43 | def testdrawrects(color): 44 | tft.fill(TFT.BLACK); 45 | for x in range(0,tft.size()[0],6): 46 | tft.rect((tft.size()[0]//2 - x//2, tft.size()[1]//2 - x/2), (x, x), color) 47 | 48 | def testfillrects(color1, color2): 49 | tft.fill(TFT.BLACK); 50 | for x in range(tft.size()[0],0,-6): 51 | tft.fillrect((tft.size()[0]//2 - x//2, tft.size()[1]//2 - x/2), (x, x), color1) 52 | tft.rect((tft.size()[0]//2 - x//2, tft.size()[1]//2 - x/2), (x, x), color2) 53 | 54 | 55 | def testfillcircles(radius, color): 56 | for x in range(radius, tft.size()[0], radius * 2): 57 | for y in range(radius, tft.size()[1], radius * 2): 58 | tft.fillcircle((x, y), radius, color) 59 | 60 | def testdrawcircles(radius, color): 61 | for x in range(0, tft.size()[0] + radius, radius * 2): 62 | for y in range(0, tft.size()[1] + radius, radius * 2): 63 | tft.circle((x, y), radius, color) 64 | 65 | def testtriangles(): 66 | tft.fill(TFT.BLACK); 67 | color = 0xF800 68 | w = tft.size()[0] // 2 69 | x = tft.size()[1] - 1 70 | y = 0 71 | z = tft.size()[0] 72 | for t in range(0, 15): 73 | tft.line((w, y), (y, x), color) 74 | tft.line((y, x), (z, x), color) 75 | tft.line((z, x), (w, y), color) 76 | x -= 4 77 | y += 4 78 | z -= 4 79 | color += 100 80 | 81 | def testroundrects(): 82 | tft.fill(TFT.BLACK); 83 | color = 100 84 | for t in range(5): 85 | x = 0 86 | y = 0 87 | w = tft.size()[0] - 2 88 | h = tft.size()[1] - 2 89 | for i in range(17): 90 | tft.rect((x, y), (w, h), color) 91 | x += 2 92 | y += 3 93 | w -= 4 94 | h -= 6 95 | color += 1100 96 | color += 100 97 | 98 | def tftprinttest(): 99 | tft.fill(TFT.BLACK); 100 | v = 30 101 | tft.text((0, v), "Hello World!", TFT.RED, sysfont, 1, nowrap=True) 102 | v += sysfont["Height"] 103 | tft.text((0, v), "Hello World!", TFT.YELLOW, sysfont, 2, nowrap=True) 104 | v += sysfont["Height"] * 2 105 | tft.text((0, v), "Hello World!", TFT.GREEN, sysfont, 3, nowrap=True) 106 | v += sysfont["Height"] * 3 107 | tft.text((0, v), str(1234.567), TFT.BLUE, sysfont, 4, nowrap=True) 108 | time.sleep_ms(1500) 109 | tft.fill(TFT.BLACK); 110 | v = 0 111 | tft.text((0, v), "Hello World!", TFT.RED, sysfont) 112 | v += sysfont["Height"] 113 | tft.text((0, v), str(math.pi), TFT.GREEN, sysfont) 114 | v += sysfont["Height"] 115 | tft.text((0, v), " Want pi?", TFT.GREEN, sysfont) 116 | v += sysfont["Height"] * 2 117 | tft.text((0, v), hex(8675309), TFT.GREEN, sysfont) 118 | v += sysfont["Height"] 119 | tft.text((0, v), " Print HEX!", TFT.GREEN, sysfont) 120 | v += sysfont["Height"] * 2 121 | tft.text((0, v), "Sketch has been", TFT.WHITE, sysfont) 122 | v += sysfont["Height"] 123 | tft.text((0, v), "running for: ", TFT.WHITE, sysfont) 124 | v += sysfont["Height"] 125 | tft.text((0, v), str(time.ticks_ms() / 1000), TFT.PURPLE, sysfont) 126 | v += sysfont["Height"] 127 | tft.text((0, v), " seconds.", TFT.WHITE, sysfont) 128 | 129 | def test_main(): 130 | tft.fill(TFT.BLACK) 131 | tft.text((0, 0), "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", TFT.WHITE, sysfont, 1) 132 | time.sleep_ms(1000) 133 | 134 | tftprinttest() 135 | time.sleep_ms(4000) 136 | 137 | testlines(TFT.YELLOW) 138 | time.sleep_ms(500) 139 | 140 | testfastlines(TFT.RED, TFT.BLUE) 141 | time.sleep_ms(500) 142 | 143 | testdrawrects(TFT.GREEN) 144 | time.sleep_ms(500) 145 | 146 | testfillrects(TFT.YELLOW, TFT.PURPLE) 147 | time.sleep_ms(500) 148 | 149 | tft.fill(TFT.BLACK) 150 | testfillcircles(10, TFT.BLUE) 151 | testdrawcircles(10, TFT.WHITE) 152 | time.sleep_ms(500) 153 | 154 | testroundrects() 155 | time.sleep_ms(500) 156 | 157 | testtriangles() 158 | time.sleep_ms(500) 159 | 160 | test_main() 161 | -------------------------------------------------------------------------------- /ST7735.py: -------------------------------------------------------------------------------- 1 | #driver for Sainsmart 1.8" TFT display ST7735 2 | #Translated by Guy Carver from the ST7735 sample code. 3 | #Modirfied for micropython-esp32 by boochow 4 | 5 | import machine 6 | import time 7 | from math import sqrt 8 | 9 | #TFTRotations and TFTRGB are bits to set 10 | # on MADCTL to control display rotation/color layout 11 | #Looking at display with pins on top. 12 | #00 = upper left printing right 13 | #10 = does nothing (MADCTL_ML) 14 | #20 = upper left printing down (backwards) (Vertical flip) 15 | #40 = upper right printing left (backwards) (X Flip) 16 | #80 = lower left printing right (backwards) (Y Flip) 17 | #04 = (MADCTL_MH) 18 | 19 | #60 = 90 right rotation 20 | #C0 = 180 right rotation 21 | #A0 = 270 right rotation 22 | TFTRotations = [0x00, 0x60, 0xC0, 0xA0] 23 | TFTBGR = 0x08 #When set color is bgr else rgb. 24 | TFTRGB = 0x00 25 | 26 | #@micropython.native 27 | def clamp( aValue, aMin, aMax ) : 28 | return max(aMin, min(aMax, aValue)) 29 | 30 | #@micropython.native 31 | def TFTColor( aR, aG, aB ) : 32 | '''Create a 16 bit rgb value from the given R,G,B from 0-255. 33 | This assumes rgb 565 layout and will be incorrect for bgr.''' 34 | return ((aR & 0xF8) << 8) | ((aG & 0xFC) << 3) | (aB >> 3) 35 | 36 | ScreenSize = (128, 160) 37 | 38 | class TFT(object) : 39 | """Sainsmart TFT 7735 display driver.""" 40 | 41 | NOP = 0x0 42 | SWRESET = 0x01 43 | RDDID = 0x04 44 | RDDST = 0x09 45 | 46 | SLPIN = 0x10 47 | SLPOUT = 0x11 48 | PTLON = 0x12 49 | NORON = 0x13 50 | 51 | INVOFF = 0x20 52 | INVON = 0x21 53 | DISPOFF = 0x28 54 | DISPON = 0x29 55 | CASET = 0x2A 56 | RASET = 0x2B 57 | RAMWR = 0x2C 58 | RAMRD = 0x2E 59 | 60 | VSCRDEF = 0x33 61 | VSCSAD = 0x37 62 | 63 | COLMOD = 0x3A 64 | MADCTL = 0x36 65 | 66 | FRMCTR1 = 0xB1 67 | FRMCTR2 = 0xB2 68 | FRMCTR3 = 0xB3 69 | INVCTR = 0xB4 70 | DISSET5 = 0xB6 71 | 72 | PWCTR1 = 0xC0 73 | PWCTR2 = 0xC1 74 | PWCTR3 = 0xC2 75 | PWCTR4 = 0xC3 76 | PWCTR5 = 0xC4 77 | VMCTR1 = 0xC5 78 | 79 | RDID1 = 0xDA 80 | RDID2 = 0xDB 81 | RDID3 = 0xDC 82 | RDID4 = 0xDD 83 | 84 | PWCTR6 = 0xFC 85 | 86 | GMCTRP1 = 0xE0 87 | GMCTRN1 = 0xE1 88 | 89 | BLACK = 0 90 | RED = TFTColor(0xFF, 0x00, 0x00) 91 | MAROON = TFTColor(0x80, 0x00, 0x00) 92 | GREEN = TFTColor(0x00, 0xFF, 0x00) 93 | FOREST = TFTColor(0x00, 0x80, 0x80) 94 | BLUE = TFTColor(0x00, 0x00, 0xFF) 95 | NAVY = TFTColor(0x00, 0x00, 0x80) 96 | CYAN = TFTColor(0x00, 0xFF, 0xFF) 97 | YELLOW = TFTColor(0xFF, 0xFF, 0x00) 98 | PURPLE = TFTColor(0xFF, 0x00, 0xFF) 99 | WHITE = TFTColor(0xFF, 0xFF, 0xFF) 100 | GRAY = TFTColor(0x80, 0x80, 0x80) 101 | 102 | @staticmethod 103 | def color( aR, aG, aB ) : 104 | '''Create a 565 rgb TFTColor value''' 105 | return TFTColor(aR, aG, aB) 106 | 107 | def __init__( self, spi, aDC, aReset, aCS) : 108 | """aLoc SPI pin location is either 1 for 'X' or 2 for 'Y'. 109 | aDC is the DC pin and aReset is the reset pin.""" 110 | self._size = ScreenSize 111 | self._offset = bytearray([0,0]) 112 | self.rotate = 0 #Vertical with top toward pins. 113 | self._rgb = True #color order of rgb. 114 | self.tfa = 0 #top fixed area 115 | self.bfa = 0 #bottom fixed area 116 | self.dc = machine.Pin(aDC, machine.Pin.OUT, machine.Pin.PULL_DOWN) 117 | self.reset = machine.Pin(aReset, machine.Pin.OUT, machine.Pin.PULL_DOWN) 118 | self.cs = machine.Pin(aCS, machine.Pin.OUT, machine.Pin.PULL_DOWN) 119 | self.cs(1) 120 | self.spi = spi 121 | self.colorData = bytearray(2) 122 | self.windowLocData = bytearray(4) 123 | 124 | def size( self ) : 125 | return self._size 126 | 127 | # @micropython.native 128 | def on( self, aTF = True ) : 129 | '''Turn display on or off.''' 130 | self._writecommand(TFT.DISPON if aTF else TFT.DISPOFF) 131 | 132 | # @micropython.native 133 | def invertcolor( self, aBool ) : 134 | '''Invert the color data IE: Black = White.''' 135 | self._writecommand(TFT.INVON if aBool else TFT.INVOFF) 136 | 137 | # @micropython.native 138 | def rgb( self, aTF = True ) : 139 | '''True = rgb else bgr''' 140 | self._rgb = aTF 141 | self._setMADCTL() 142 | 143 | # @micropython.native 144 | def rotation( self, aRot ) : 145 | '''0 - 3. Starts vertical with top toward pins and rotates 90 deg 146 | clockwise each step.''' 147 | if (0 <= aRot < 4): 148 | rotchange = self.rotate ^ aRot 149 | self.rotate = aRot 150 | #If switching from vertical to horizontal swap x,y 151 | # (indicated by bit 0 changing). 152 | if (rotchange & 1): 153 | self._size =(self._size[1], self._size[0]) 154 | self._setMADCTL() 155 | 156 | # @micropython.native 157 | def pixel( self, aPos, aColor ) : 158 | '''Draw a pixel at the given position''' 159 | if 0 <= aPos[0] < self._size[0] and 0 <= aPos[1] < self._size[1]: 160 | self._setwindowpoint(aPos) 161 | self._pushcolor(aColor) 162 | 163 | # @micropython.native 164 | def text( self, aPos, aString, aColor, aFont, aSize = 1, nowrap = False ) : 165 | '''Draw a text at the given position. If the string reaches the end of the 166 | display it is wrapped to aPos[0] on the next line. aSize may be an integer 167 | which will size the font uniformly on w,h or a or any type that may be 168 | indexed with [0] or [1].''' 169 | 170 | if aFont == None: 171 | return 172 | 173 | #Make a size either from single value or 2 elements. 174 | if (type(aSize) == int) or (type(aSize) == float): 175 | wh = (aSize, aSize) 176 | else: 177 | wh = aSize 178 | 179 | px, py = aPos 180 | width = wh[0] * aFont["Width"] + 1 181 | for c in aString: 182 | self.char((px, py), c, aColor, aFont, wh) 183 | px += width 184 | #We check > rather than >= to let the right (blank) edge of the 185 | # character print off the right of the screen. 186 | if px + width > self._size[0]: 187 | if nowrap: 188 | break 189 | else: 190 | py += aFont["Height"] * wh[1] + 1 191 | px = aPos[0] 192 | 193 | # @micropython.native 194 | def char( self, aPos, aChar, aColor, aFont, aSizes ) : 195 | '''Draw a character at the given position using the given font and color. 196 | aSizes is a tuple with x, y as integer scales indicating the 197 | # of pixels to draw for each pixel in the character.''' 198 | 199 | if aFont == None: 200 | return 201 | 202 | startchar = aFont['Start'] 203 | endchar = aFont['End'] 204 | 205 | ci = ord(aChar) 206 | if (startchar <= ci <= endchar): 207 | fontw = aFont['Width'] 208 | fonth = aFont['Height'] 209 | ci = (ci - startchar) * fontw 210 | 211 | charA = aFont["Data"][ci:ci + fontw] 212 | px = aPos[0] 213 | if aSizes[0] <= 1 and aSizes[1] <= 1 : 214 | buf = bytearray(2 * fonth * fontw) 215 | for q in range(fontw) : 216 | c = charA[q] 217 | for r in range(fonth) : 218 | if c & 0x01 : 219 | pos = 2 * (r * fontw + q) 220 | buf[pos] = aColor >> 8 221 | buf[pos + 1] = aColor & 0xff 222 | c >>= 1 223 | self.image(aPos[0], aPos[1], aPos[0] + fontw - 1, aPos[1] + fonth - 1, buf) 224 | else: 225 | for c in charA : 226 | py = aPos[1] 227 | for r in range(fonth) : 228 | if c & 0x01 : 229 | self.fillrect((px, py), aSizes, aColor) 230 | py += aSizes[1] 231 | c >>= 1 232 | px += aSizes[0] 233 | 234 | # @micropython.native 235 | def line( self, aStart, aEnd, aColor ) : 236 | '''Draws a line from aStart to aEnd in the given color. Vertical or horizontal 237 | lines are forwarded to vline and hline.''' 238 | if aStart[0] == aEnd[0]: 239 | #Make sure we use the smallest y. 240 | pnt = aEnd if (aEnd[1] < aStart[1]) else aStart 241 | self.vline(pnt, abs(aEnd[1] - aStart[1]) + 1, aColor) 242 | elif aStart[1] == aEnd[1]: 243 | #Make sure we use the smallest x. 244 | pnt = aEnd if aEnd[0] < aStart[0] else aStart 245 | self.hline(pnt, abs(aEnd[0] - aStart[0]) + 1, aColor) 246 | else: 247 | px, py = aStart 248 | ex, ey = aEnd 249 | dx = ex - px 250 | dy = ey - py 251 | inx = 1 if dx > 0 else -1 252 | iny = 1 if dy > 0 else -1 253 | 254 | dx = abs(dx) 255 | dy = abs(dy) 256 | if (dx >= dy): 257 | dy <<= 1 258 | e = dy - dx 259 | dx <<= 1 260 | while (px != ex): 261 | self.pixel((px, py), aColor) 262 | if (e >= 0): 263 | py += iny 264 | e -= dx 265 | e += dy 266 | px += inx 267 | else: 268 | dx <<= 1 269 | e = dx - dy 270 | dy <<= 1 271 | while (py != ey): 272 | self.pixel((px, py), aColor) 273 | if (e >= 0): 274 | px += inx 275 | e -= dy 276 | e += dx 277 | py += iny 278 | 279 | # @micropython.native 280 | def vline( self, aStart, aLen, aColor ) : 281 | '''Draw a vertical line from aStart for aLen. aLen may be negative.''' 282 | start = (clamp(aStart[0], 0, self._size[0]), clamp(aStart[1], 0, self._size[1])) 283 | stop = (start[0], clamp(start[1] + aLen, 0, self._size[1])) 284 | #Make sure smallest y 1st. 285 | if (stop[1] < start[1]): 286 | start, stop = stop, start 287 | self._setwindowloc(start, stop) 288 | self._setColor(aColor) 289 | self._draw(aLen) 290 | 291 | # @micropython.native 292 | def hline( self, aStart, aLen, aColor ) : 293 | '''Draw a horizontal line from aStart for aLen. aLen may be negative.''' 294 | start = (clamp(aStart[0], 0, self._size[0]), clamp(aStart[1], 0, self._size[1])) 295 | stop = (clamp(start[0] + aLen, 0, self._size[0]), start[1]) 296 | #Make sure smallest x 1st. 297 | if (stop[0] < start[0]): 298 | start, stop = stop, start 299 | self._setwindowloc(start, stop) 300 | self._setColor(aColor) 301 | self._draw(aLen) 302 | 303 | # @micropython.native 304 | def rect( self, aStart, aSize, aColor ) : 305 | '''Draw a hollow rectangle. aStart is the smallest coordinate corner 306 | and aSize is a tuple indicating width, height.''' 307 | self.hline(aStart, aSize[0], aColor) 308 | self.hline((aStart[0], aStart[1] + aSize[1] - 1), aSize[0], aColor) 309 | self.vline(aStart, aSize[1], aColor) 310 | self.vline((aStart[0] + aSize[0] - 1, aStart[1]), aSize[1], aColor) 311 | 312 | # @micropython.native 313 | def fillrect( self, aStart, aSize, aColor ) : 314 | '''Draw a filled rectangle. aStart is the smallest coordinate corner 315 | and aSize is a tuple indicating width, height.''' 316 | start = (clamp(aStart[0], 0, self._size[0]), clamp(aStart[1], 0, self._size[1])) 317 | end = (clamp(start[0] + aSize[0] - 1, 0, self._size[0]), clamp(start[1] + aSize[1] - 1, 0, self._size[1])) 318 | 319 | if (end[0] < start[0]): 320 | tmp = end[0] 321 | end = (start[0], end[1]) 322 | start = (tmp, start[1]) 323 | if (end[1] < start[1]): 324 | tmp = end[1] 325 | end = (end[0], start[1]) 326 | start = (start[0], tmp) 327 | 328 | self._setwindowloc(start, end) 329 | numPixels = (end[0] - start[0] + 1) * (end[1] - start[1] + 1) 330 | self._setColor(aColor) 331 | self._draw(numPixels) 332 | 333 | # @micropython.native 334 | def circle( self, aPos, aRadius, aColor ) : 335 | '''Draw a hollow circle with the given radius and color with aPos as center.''' 336 | self.colorData[0] = aColor >> 8 337 | self.colorData[1] = aColor 338 | xend = int(0.7071 * aRadius) + 1 339 | rsq = aRadius * aRadius 340 | for x in range(xend) : 341 | y = int(sqrt(rsq - x * x)) 342 | xp = aPos[0] + x 343 | yp = aPos[1] + y 344 | xn = aPos[0] - x 345 | yn = aPos[1] - y 346 | xyp = aPos[0] + y 347 | yxp = aPos[1] + x 348 | xyn = aPos[0] - y 349 | yxn = aPos[1] - x 350 | 351 | self._setwindowpoint((xp, yp)) 352 | self._writedata(self.colorData) 353 | self._setwindowpoint((xp, yn)) 354 | self._writedata(self.colorData) 355 | self._setwindowpoint((xn, yp)) 356 | self._writedata(self.colorData) 357 | self._setwindowpoint((xn, yn)) 358 | self._writedata(self.colorData) 359 | self._setwindowpoint((xyp, yxp)) 360 | self._writedata(self.colorData) 361 | self._setwindowpoint((xyp, yxn)) 362 | self._writedata(self.colorData) 363 | self._setwindowpoint((xyn, yxp)) 364 | self._writedata(self.colorData) 365 | self._setwindowpoint((xyn, yxn)) 366 | self._writedata(self.colorData) 367 | 368 | # @micropython.native 369 | def fillcircle( self, aPos, aRadius, aColor ) : 370 | '''Draw a filled circle with given radius and color with aPos as center''' 371 | rsq = aRadius * aRadius 372 | for x in range(aRadius) : 373 | y = int(sqrt(rsq - x * x)) 374 | y0 = aPos[1] - y 375 | ey = y0 + y * 2 376 | y0 = clamp(y0, 0, self._size[1]) 377 | ln = abs(ey - y0) + 1; 378 | 379 | self.vline((aPos[0] + x, y0), ln, aColor) 380 | self.vline((aPos[0] - x, y0), ln, aColor) 381 | 382 | def fill( self, aColor = BLACK ) : 383 | '''Fill screen with the given color.''' 384 | self.fillrect((0, 0), self._size, aColor) 385 | 386 | def image( self, x0, y0, x1, y1, data ) : 387 | self._setwindowloc((x0, y0), (x1, y1)) 388 | self._writedata(data) 389 | 390 | def setvscroll(self, tfa, bfa) : 391 | ''' set vertical scroll area ''' 392 | self._writecommand(TFT.VSCRDEF) 393 | data2 = bytearray([0, tfa]) 394 | self._writedata(data2) 395 | data2[1] = 162 - tfa - bfa 396 | self._writedata(data2) 397 | data2[1] = bfa 398 | self._writedata(data2) 399 | self.tfa = tfa 400 | self.bfa = bfa 401 | 402 | def vscroll(self, value) : 403 | a = value + self.tfa 404 | if (a + self.bfa > 162) : 405 | a = 162 - self.bfa 406 | self._vscrolladdr(a) 407 | 408 | def _vscrolladdr(self, addr) : 409 | self._writecommand(TFT.VSCSAD) 410 | data2 = bytearray([addr >> 8, addr & 0xff]) 411 | self._writedata(data2) 412 | 413 | # @micropython.native 414 | def _setColor( self, aColor ) : 415 | self.colorData[0] = aColor >> 8 416 | self.colorData[1] = aColor 417 | self.buf = bytes(self.colorData) * 32 418 | 419 | # @micropython.native 420 | def _draw( self, aPixels ) : 421 | '''Send given color to the device aPixels times.''' 422 | 423 | self.dc(1) 424 | self.cs(0) 425 | for i in range(aPixels//32): 426 | self.spi.write(self.buf) 427 | rest = (int(aPixels) % 32) 428 | if rest > 0: 429 | buf2 = bytes(self.colorData) * rest 430 | self.spi.write(buf2) 431 | self.cs(1) 432 | 433 | # @micropython.native 434 | def _setwindowpoint( self, aPos ) : 435 | '''Set a single point for drawing a color to.''' 436 | x = self._offset[0] + int(aPos[0]) 437 | y = self._offset[1] + int(aPos[1]) 438 | self._writecommand(TFT.CASET) #Column address set. 439 | self.windowLocData[0] = self._offset[0] 440 | self.windowLocData[1] = x 441 | self.windowLocData[2] = self._offset[0] 442 | self.windowLocData[3] = x 443 | self._writedata(self.windowLocData) 444 | 445 | self._writecommand(TFT.RASET) #Row address set. 446 | self.windowLocData[0] = self._offset[1] 447 | self.windowLocData[1] = y 448 | self.windowLocData[2] = self._offset[1] 449 | self.windowLocData[3] = y 450 | self._writedata(self.windowLocData) 451 | self._writecommand(TFT.RAMWR) #Write to RAM. 452 | 453 | # @micropython.native 454 | def _setwindowloc( self, aPos0, aPos1 ) : 455 | '''Set a rectangular area for drawing a color to.''' 456 | self._writecommand(TFT.CASET) #Column address set. 457 | self.windowLocData[0] = self._offset[0] 458 | self.windowLocData[1] = self._offset[0] + int(aPos0[0]) 459 | self.windowLocData[2] = self._offset[0] 460 | self.windowLocData[3] = self._offset[0] + int(aPos1[0]) 461 | self._writedata(self.windowLocData) 462 | 463 | self._writecommand(TFT.RASET) #Row address set. 464 | self.windowLocData[0] = self._offset[1] 465 | self.windowLocData[1] = self._offset[1] + int(aPos0[1]) 466 | self.windowLocData[2] = self._offset[1] 467 | self.windowLocData[3] = self._offset[1] + int(aPos1[1]) 468 | self._writedata(self.windowLocData) 469 | 470 | self._writecommand(TFT.RAMWR) #Write to RAM. 471 | 472 | #@micropython.native 473 | def _writecommand( self, aCommand ) : 474 | '''Write given command to the device.''' 475 | self.dc(0) 476 | self.cs(0) 477 | self.spi.write(bytearray([aCommand])) 478 | self.cs(1) 479 | 480 | #@micropython.native 481 | def _writedata( self, aData ) : 482 | '''Write given data to the device. This may be 483 | either a single int or a bytearray of values.''' 484 | self.dc(1) 485 | self.cs(0) 486 | self.spi.write(aData) 487 | self.cs(1) 488 | 489 | #@micropython.native 490 | def _pushcolor( self, aColor ) : 491 | '''Push given color to the device.''' 492 | self.colorData[0] = aColor >> 8 493 | self.colorData[1] = aColor 494 | self._writedata(self.colorData) 495 | 496 | #@micropython.native 497 | def _setMADCTL( self ) : 498 | '''Set screen rotation and RGB/BGR format.''' 499 | self._writecommand(TFT.MADCTL) 500 | rgb = TFTRGB if self._rgb else TFTBGR 501 | self._writedata(bytearray([TFTRotations[self.rotate] | rgb])) 502 | 503 | #@micropython.native 504 | def _reset( self ) : 505 | '''Reset the device.''' 506 | self.dc(0) 507 | self.reset(1) 508 | time.sleep_us(500) 509 | self.reset(0) 510 | time.sleep_us(500) 511 | self.reset(1) 512 | time.sleep_us(500) 513 | 514 | def initb( self ) : 515 | '''Initialize blue tab version.''' 516 | self._size = (ScreenSize[0] + 2, ScreenSize[1] + 1) 517 | self._reset() 518 | self._writecommand(TFT.SWRESET) #Software reset. 519 | time.sleep_us(50) 520 | self._writecommand(TFT.SLPOUT) #out of sleep mode. 521 | time.sleep_us(500) 522 | 523 | data1 = bytearray(1) 524 | self._writecommand(TFT.COLMOD) #Set color mode. 525 | data1[0] = 0x05 #16 bit color. 526 | self._writedata(data1) 527 | time.sleep_us(10) 528 | 529 | data3 = bytearray([0x00, 0x06, 0x03]) #fastest refresh, 6 lines front, 3 lines back. 530 | self._writecommand(TFT.FRMCTR1) #Frame rate control. 531 | self._writedata(data3) 532 | time.sleep_us(10) 533 | 534 | self._writecommand(TFT.MADCTL) 535 | data1[0] = 0x08 #row address/col address, bottom to top refresh 536 | self._writedata(data1) 537 | 538 | data2 = bytearray(2) 539 | self._writecommand(TFT.DISSET5) #Display settings 540 | data2[0] = 0x15 #1 clock cycle nonoverlap, 2 cycle gate rise, 3 cycle oscil, equalize 541 | data2[1] = 0x02 #fix on VTL 542 | self._writedata(data2) 543 | 544 | self._writecommand(TFT.INVCTR) #Display inversion control 545 | data1[0] = 0x00 #Line inversion. 546 | self._writedata(data1) 547 | 548 | self._writecommand(TFT.PWCTR1) #Power control 549 | data2[0] = 0x02 #GVDD = 4.7V 550 | data2[1] = 0x70 #1.0uA 551 | self._writedata(data2) 552 | time.sleep_us(10) 553 | 554 | self._writecommand(TFT.PWCTR2) #Power control 555 | data1[0] = 0x05 #VGH = 14.7V, VGL = -7.35V 556 | self._writedata(data1) 557 | 558 | self._writecommand(TFT.PWCTR3) #Power control 559 | data2[0] = 0x01 #Opamp current small 560 | data2[1] = 0x02 #Boost frequency 561 | self._writedata(data2) 562 | 563 | self._writecommand(TFT.VMCTR1) #Power control 564 | data2[0] = 0x3C #VCOMH = 4V 565 | data2[1] = 0x38 #VCOML = -1.1V 566 | self._writedata(data2) 567 | time.sleep_us(10) 568 | 569 | self._writecommand(TFT.PWCTR6) #Power control 570 | data2[0] = 0x11 571 | data2[1] = 0x15 572 | self._writedata(data2) 573 | 574 | #These different values don't seem to make a difference. 575 | # dataGMCTRP = bytearray([0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f, 576 | # 0x1b, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10]) 577 | dataGMCTRP = bytearray([0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 578 | 0x25, 0x2b, 0x39, 0x00, 0x01, 0x03, 0x10]) 579 | self._writecommand(TFT.GMCTRP1) 580 | self._writedata(dataGMCTRP) 581 | 582 | # dataGMCTRN = bytearray([0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30, 583 | # 0x30, 0x39, 0x3f, 0x00, 0x07, 0x03, 0x10]) 584 | dataGMCTRN = bytearray([0x03, 0x1d, 0x07, 0x06, 0x2e, 0x2c, 0x29, 0x2d, 0x2e, 585 | 0x2e, 0x37, 0x3f, 0x00, 0x00, 0x02, 0x10]) 586 | self._writecommand(TFT.GMCTRN1) 587 | self._writedata(dataGMCTRN) 588 | time.sleep_us(10) 589 | 590 | self._writecommand(TFT.CASET) #Column address set. 591 | self.windowLocData[0] = 0x00 592 | self.windowLocData[1] = 2 #Start at column 2 593 | self.windowLocData[2] = 0x00 594 | self.windowLocData[3] = self._size[0] - 1 595 | self._writedata(self.windowLocData) 596 | 597 | self._writecommand(TFT.RASET) #Row address set. 598 | self.windowLocData[1] = 1 #Start at row 2. 599 | self.windowLocData[3] = self._size[1] - 1 600 | self._writedata(self.windowLocData) 601 | 602 | self._writecommand(TFT.NORON) #Normal display on. 603 | time.sleep_us(10) 604 | 605 | self._writecommand(TFT.RAMWR) 606 | time.sleep_us(500) 607 | 608 | self._writecommand(TFT.DISPON) 609 | self.cs(1) 610 | time.sleep_us(500) 611 | 612 | def initr( self ) : 613 | '''Initialize a red tab version.''' 614 | self._reset() 615 | 616 | self._writecommand(TFT.SWRESET) #Software reset. 617 | time.sleep_us(150) 618 | self._writecommand(TFT.SLPOUT) #out of sleep mode. 619 | time.sleep_us(500) 620 | 621 | data3 = bytearray([0x01, 0x2C, 0x2D]) #fastest refresh, 6 lines front, 3 lines back. 622 | self._writecommand(TFT.FRMCTR1) #Frame rate control. 623 | self._writedata(data3) 624 | 625 | self._writecommand(TFT.FRMCTR2) #Frame rate control. 626 | self._writedata(data3) 627 | 628 | data6 = bytearray([0x01, 0x2c, 0x2d, 0x01, 0x2c, 0x2d]) 629 | self._writecommand(TFT.FRMCTR3) #Frame rate control. 630 | self._writedata(data6) 631 | time.sleep_us(10) 632 | 633 | data1 = bytearray(1) 634 | self._writecommand(TFT.INVCTR) #Display inversion control 635 | data1[0] = 0x07 #Line inversion. 636 | self._writedata(data1) 637 | 638 | self._writecommand(TFT.PWCTR1) #Power control 639 | data3[0] = 0xA2 640 | data3[1] = 0x02 641 | data3[2] = 0x84 642 | self._writedata(data3) 643 | 644 | self._writecommand(TFT.PWCTR2) #Power control 645 | data1[0] = 0xC5 #VGH = 14.7V, VGL = -7.35V 646 | self._writedata(data1) 647 | 648 | data2 = bytearray(2) 649 | self._writecommand(TFT.PWCTR3) #Power control 650 | data2[0] = 0x0A #Opamp current small 651 | data2[1] = 0x00 #Boost frequency 652 | self._writedata(data2) 653 | 654 | self._writecommand(TFT.PWCTR4) #Power control 655 | data2[0] = 0x8A #Opamp current small 656 | data2[1] = 0x2A #Boost frequency 657 | self._writedata(data2) 658 | 659 | self._writecommand(TFT.PWCTR5) #Power control 660 | data2[0] = 0x8A #Opamp current small 661 | data2[1] = 0xEE #Boost frequency 662 | self._writedata(data2) 663 | 664 | self._writecommand(TFT.VMCTR1) #Power control 665 | data1[0] = 0x0E 666 | self._writedata(data1) 667 | 668 | self._writecommand(TFT.INVOFF) 669 | 670 | self._writecommand(TFT.MADCTL) #Power control 671 | data1[0] = 0xC8 672 | self._writedata(data1) 673 | 674 | self._writecommand(TFT.COLMOD) 675 | data1[0] = 0x05 676 | self._writedata(data1) 677 | 678 | self._writecommand(TFT.CASET) #Column address set. 679 | self.windowLocData[0] = 0x00 680 | self.windowLocData[1] = 0x00 681 | self.windowLocData[2] = 0x00 682 | self.windowLocData[3] = self._size[0] - 1 683 | self._writedata(self.windowLocData) 684 | 685 | self._writecommand(TFT.RASET) #Row address set. 686 | self.windowLocData[3] = self._size[1] - 1 687 | self._writedata(self.windowLocData) 688 | 689 | dataGMCTRP = bytearray([0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f, 690 | 0x1b, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10]) 691 | self._writecommand(TFT.GMCTRP1) 692 | self._writedata(dataGMCTRP) 693 | 694 | dataGMCTRN = bytearray([0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30, 695 | 0x30, 0x39, 0x3f, 0x00, 0x07, 0x03, 0x10]) 696 | self._writecommand(TFT.GMCTRN1) 697 | self._writedata(dataGMCTRN) 698 | time.sleep_us(10) 699 | 700 | self._writecommand(TFT.DISPON) 701 | time.sleep_us(100) 702 | 703 | self._writecommand(TFT.NORON) #Normal display on. 704 | time.sleep_us(10) 705 | 706 | self.cs(1) 707 | 708 | def initb2( self ) : 709 | '''Initialize another blue tab version.''' 710 | self._size = (ScreenSize[0] + 2, ScreenSize[1] + 1) 711 | self._offset[0] = 2 712 | self._offset[1] = 1 713 | self._reset() 714 | self._writecommand(TFT.SWRESET) #Software reset. 715 | time.sleep_us(50) 716 | self._writecommand(TFT.SLPOUT) #out of sleep mode. 717 | time.sleep_us(500) 718 | 719 | data3 = bytearray([0x01, 0x2C, 0x2D]) # 720 | self._writecommand(TFT.FRMCTR1) #Frame rate control. 721 | self._writedata(data3) 722 | time.sleep_us(10) 723 | 724 | self._writecommand(TFT.FRMCTR2) #Frame rate control. 725 | self._writedata(data3) 726 | time.sleep_us(10) 727 | 728 | self._writecommand(TFT.FRMCTR3) #Frame rate control. 729 | self._writedata(data3) 730 | time.sleep_us(10) 731 | 732 | self._writecommand(TFT.INVCTR) #Display inversion control 733 | data1 = bytearray(1) # 734 | data1[0] = 0x07 735 | self._writedata(data1) 736 | 737 | self._writecommand(TFT.PWCTR1) #Power control 738 | data3[0] = 0xA2 # 739 | data3[1] = 0x02 # 740 | data3[2] = 0x84 # 741 | self._writedata(data3) 742 | time.sleep_us(10) 743 | 744 | self._writecommand(TFT.PWCTR2) #Power control 745 | data1[0] = 0xC5 # 746 | self._writedata(data1) 747 | 748 | self._writecommand(TFT.PWCTR3) #Power control 749 | data2 = bytearray(2) 750 | data2[0] = 0x0A # 751 | data2[1] = 0x00 # 752 | self._writedata(data2) 753 | 754 | self._writecommand(TFT.PWCTR4) #Power control 755 | data2[0] = 0x8A # 756 | data2[1] = 0x2A # 757 | self._writedata(data2) 758 | 759 | self._writecommand(TFT.PWCTR5) #Power control 760 | data2[0] = 0x8A # 761 | data2[1] = 0xEE # 762 | self._writedata(data2) 763 | 764 | self._writecommand(TFT.VMCTR1) #Power control 765 | data1[0] = 0x0E # 766 | self._writedata(data1) 767 | time.sleep_us(10) 768 | 769 | self._writecommand(TFT.MADCTL) 770 | data1[0] = 0xC8 #row address/col address, bottom to top refresh 771 | self._writedata(data1) 772 | 773 | #These different values don't seem to make a difference. 774 | # dataGMCTRP = bytearray([0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f, 775 | # 0x1b, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10]) 776 | dataGMCTRP = bytearray([0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 777 | 0x25, 0x2b, 0x39, 0x00, 0x01, 0x03, 0x10]) 778 | self._writecommand(TFT.GMCTRP1) 779 | self._writedata(dataGMCTRP) 780 | 781 | # dataGMCTRN = bytearray([0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30, 782 | # 0x30, 0x39, 0x3f, 0x00, 0x07, 0x03, 0x10]) 783 | dataGMCTRN = bytearray([0x03, 0x1d, 0x07, 0x06, 0x2e, 0x2c, 0x29, 0x2d, 0x2e, 784 | 0x2e, 0x37, 0x3f, 0x00, 0x00, 0x02, 0x10]) 785 | self._writecommand(TFT.GMCTRN1) 786 | self._writedata(dataGMCTRN) 787 | time.sleep_us(10) 788 | 789 | self._writecommand(TFT.CASET) #Column address set. 790 | self.windowLocData[0] = 0x00 791 | self.windowLocData[1] = 0x02 #Start at column 2 792 | self.windowLocData[2] = 0x00 793 | self.windowLocData[3] = self._size[0] - 1 794 | self._writedata(self.windowLocData) 795 | 796 | self._writecommand(TFT.RASET) #Row address set. 797 | self.windowLocData[1] = 0x01 #Start at row 2. 798 | self.windowLocData[3] = self._size[1] - 1 799 | self._writedata(self.windowLocData) 800 | 801 | data1 = bytearray(1) 802 | self._writecommand(TFT.COLMOD) #Set color mode. 803 | data1[0] = 0x05 #16 bit color. 804 | self._writedata(data1) 805 | time.sleep_us(10) 806 | 807 | self._writecommand(TFT.NORON) #Normal display on. 808 | time.sleep_us(10) 809 | 810 | self._writecommand(TFT.RAMWR) 811 | time.sleep_us(500) 812 | 813 | self._writecommand(TFT.DISPON) 814 | self.cs(1) 815 | time.sleep_us(500) 816 | 817 | #@micropython.native 818 | def initg( self ) : 819 | '''Initialize a green tab version.''' 820 | self._reset() 821 | 822 | self._writecommand(TFT.SWRESET) #Software reset. 823 | time.sleep_us(150) 824 | self._writecommand(TFT.SLPOUT) #out of sleep mode. 825 | time.sleep_us(255) 826 | 827 | data3 = bytearray([0x01, 0x2C, 0x2D]) #fastest refresh, 6 lines front, 3 lines back. 828 | self._writecommand(TFT.FRMCTR1) #Frame rate control. 829 | self._writedata(data3) 830 | 831 | self._writecommand(TFT.FRMCTR2) #Frame rate control. 832 | self._writedata(data3) 833 | 834 | data6 = bytearray([0x01, 0x2c, 0x2d, 0x01, 0x2c, 0x2d]) 835 | self._writecommand(TFT.FRMCTR3) #Frame rate control. 836 | self._writedata(data6) 837 | time.sleep_us(10) 838 | 839 | self._writecommand(TFT.INVCTR) #Display inversion control 840 | self._writedata(bytearray([0x07])) 841 | self._writecommand(TFT.PWCTR1) #Power control 842 | data3[0] = 0xA2 843 | data3[1] = 0x02 844 | data3[2] = 0x84 845 | self._writedata(data3) 846 | 847 | self._writecommand(TFT.PWCTR2) #Power control 848 | self._writedata(bytearray([0xC5])) 849 | 850 | data2 = bytearray(2) 851 | self._writecommand(TFT.PWCTR3) #Power control 852 | data2[0] = 0x0A #Opamp current small 853 | data2[1] = 0x00 #Boost frequency 854 | self._writedata(data2) 855 | 856 | self._writecommand(TFT.PWCTR4) #Power control 857 | data2[0] = 0x8A #Opamp current small 858 | data2[1] = 0x2A #Boost frequency 859 | self._writedata(data2) 860 | 861 | self._writecommand(TFT.PWCTR5) #Power control 862 | data2[0] = 0x8A #Opamp current small 863 | data2[1] = 0xEE #Boost frequency 864 | self._writedata(data2) 865 | 866 | self._writecommand(TFT.VMCTR1) #Power control 867 | self._writedata(bytearray([0x0E])) 868 | 869 | self._writecommand(TFT.INVOFF) 870 | 871 | self._setMADCTL() 872 | 873 | self._writecommand(TFT.COLMOD) 874 | self._writedata(bytearray([0x05])) 875 | 876 | self._writecommand(TFT.CASET) #Column address set. 877 | self.windowLocData[0] = 0x00 878 | self.windowLocData[1] = 0x01 #Start at row/column 1. 879 | self.windowLocData[2] = 0x00 880 | self.windowLocData[3] = self._size[0] - 1 881 | self._writedata(self.windowLocData) 882 | 883 | self._writecommand(TFT.RASET) #Row address set. 884 | self.windowLocData[3] = self._size[1] - 1 885 | self._writedata(self.windowLocData) 886 | 887 | dataGMCTRP = bytearray([0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 888 | 0x25, 0x2b, 0x39, 0x00, 0x01, 0x03, 0x10]) 889 | self._writecommand(TFT.GMCTRP1) 890 | self._writedata(dataGMCTRP) 891 | 892 | dataGMCTRN = bytearray([0x03, 0x1d, 0x07, 0x06, 0x2e, 0x2c, 0x29, 0x2d, 0x2e, 893 | 0x2e, 0x37, 0x3f, 0x00, 0x00, 0x02, 0x10]) 894 | self._writecommand(TFT.GMCTRN1) 895 | self._writedata(dataGMCTRN) 896 | 897 | self._writecommand(TFT.NORON) #Normal display on. 898 | time.sleep_us(10) 899 | 900 | self._writecommand(TFT.DISPON) 901 | time.sleep_us(100) 902 | 903 | self.cs(1) 904 | 905 | def maker( ) : 906 | t = TFT(1, "X1", "X2") 907 | print("Initializing") 908 | t.initr() 909 | t.fill(0) 910 | return t 911 | 912 | def makeb( ) : 913 | t = TFT(1, "X1", "X2") 914 | print("Initializing") 915 | t.initb() 916 | t.fill(0) 917 | return t 918 | 919 | def makeg( ) : 920 | t = TFT(1, "X1", "X2") 921 | print("Initializing") 922 | t.initg() 923 | t.fill(0) 924 | return t 925 | --------------------------------------------------------------------------------