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