kopia lustrzana https://github.com/GuyCarver/MicroPython
726 wiersze
23 KiB
Python
726 wiersze
23 KiB
Python
#driver for Sainsmart 1.8" TFT display ST7735
|
|
#Translated by Guy Carver from the ST7735 sample code.
|
|
|
|
import pyb
|
|
from math import sqrt
|
|
|
|
ST_NOP = 0x0
|
|
ST_SWRESET = 0x01
|
|
ST_RDDID = 0x04
|
|
ST_RDDST = 0x09
|
|
|
|
ST_SLPIN = 0x10
|
|
ST_SLPOUT = 0x11
|
|
ST_PTLON = 0x12
|
|
ST_NORON = 0x13
|
|
|
|
ST_INVOFF = 0x20
|
|
ST_INVON = 0x21
|
|
ST_DISPOFF = 0x28
|
|
ST_DISPON = 0x29
|
|
ST_CASET = 0x2A
|
|
ST_RASET = 0x2B
|
|
ST_RAMWR = 0x2C
|
|
ST_RAMRD = 0x2E
|
|
|
|
ST_COLMOD = 0x3A
|
|
ST_MADCTL = 0x36
|
|
|
|
ST_FRMCTR1 = 0xB1
|
|
ST_FRMCTR2 = 0xB2
|
|
ST_FRMCTR3 = 0xB3
|
|
ST_INVCTR = 0xB4
|
|
ST_DISSET5 = 0xB6
|
|
|
|
ST_PWCTR1 = 0xC0
|
|
ST_PWCTR2 = 0xC1
|
|
ST_PWCTR3 = 0xC2
|
|
ST_PWCTR4 = 0xC3
|
|
ST_PWCTR5 = 0xC4
|
|
ST_VMCTR1 = 0xC5
|
|
|
|
ST_RDID1 = 0xDA
|
|
ST_RDID2 = 0xDB
|
|
ST_RDID3 = 0xDC
|
|
ST_RDID4 = 0xDD
|
|
|
|
ST_PWCTR6 = 0xFC
|
|
|
|
ST_GMCTRP1 = 0xE0
|
|
ST_GMCTRN1 = 0xE1
|
|
|
|
#TFTRotations and TFTRGB are bits to set
|
|
# on MADCTL to control display rotation/color layout
|
|
#Looking at display with pins on top.
|
|
#00 = upper left printing right
|
|
#10 = does nothing (MADCTL_ML)
|
|
#20 = upper left printing down (backwards) (Vertical flip)
|
|
#40 = upper right printing left (backwards) (X Flip)
|
|
#80 = lower left printing right (backwards) (Y Flip)
|
|
#04 = (MADCTL_MH)
|
|
|
|
#60 = 90 right rotation
|
|
#C0 = 180 right rotation
|
|
#A0 = 270 right rotation
|
|
TFTRotations = [0x00, 0x60, 0xC0, 0xA0]
|
|
TFTBGR = 0x08 #When set color is bgr else rgb.
|
|
TFTRGB = 0x00
|
|
|
|
class Point(object):
|
|
"""2D point class"""
|
|
|
|
def __init__(self, x = 0, y = 0) :
|
|
self.x = x
|
|
self.y = y
|
|
|
|
def __str__(self) :
|
|
return "ST7735.Point(" + str(self.x) + "," + str(self.y)+ ")"
|
|
|
|
def __repr__(self) :
|
|
return self.__str__()
|
|
|
|
def clone( self ) :
|
|
return Point(self.x, self.y)
|
|
|
|
def clamp( aValue, aMin, aMax ) :
|
|
return max(aMin, min(aMax, aValue))
|
|
|
|
def TFTColor( aR, aG, aB ) :
|
|
'''Create a 16 bit rgb value from the given R,G,B from 0-255.
|
|
This assumes rgb 565 layout and will be incorrect for bgr.'''
|
|
return ((aR & 0xF8) << 8) | ((aG & 0xFC) << 3) | (aB >> 3)
|
|
|
|
BLACK = 0
|
|
RED = TFTColor(0xFF, 0x00, 0x00)
|
|
MAROON = TFTColor(0x80, 0x00, 0x00)
|
|
GREEN = TFTColor(0x00, 0xFF, 0x00)
|
|
BLUE = TFTColor(0x00, 0x00, 0xFF)
|
|
NAVY = TFTColor(0x00, 0x00, 0x80)
|
|
CYAN = TFTColor(0x00, 0xFF, 0xFF)
|
|
YELLOW = TFTColor(0xFF, 0xFF, 0x00)
|
|
PURPLE = TFTColor(0xFF, 0x00, 0xFF)
|
|
WHITE = TFTColor(0xFF, 0xFF, 0xFF)
|
|
GRAY = TFTColor(0x80, 0x80, 0x80)
|
|
|
|
ScreenSize = Point(128, 160)
|
|
|
|
class TFT(object) :
|
|
"""Sainsmart TFT 7735 display driver."""
|
|
|
|
@staticmethod
|
|
def makecolor(aR, aG, aB):
|
|
'''Create a 565 rgb TFTColor value'''
|
|
return TFTColor(aR, aG, aB)
|
|
|
|
def __init__(self, aLoc, aDC, aReset) :
|
|
"""aLoc SPI pin location is either 1 for 'X' or 2 for 'Y'.
|
|
aDC is the DC pin and aReset is the reset pin."""
|
|
self.size = ScreenSize.clone()
|
|
self.rotate = 0 #Vertical with top toward pins.
|
|
self.rgb = TFTRGB #color order of rgb.
|
|
self.dc = pyb.Pin(aDC, pyb.Pin.OUT_PP, pyb.Pin.PULL_DOWN)
|
|
self.reset = pyb.Pin(aReset, pyb.Pin.OUT_PP, pyb.Pin.PULL_DOWN)
|
|
rate = 100000000 #Set way high but will be clamped to a maximum in SPI constructor.
|
|
cs = "X5" if aLoc == 1 else "Y5"
|
|
self.cs = pyb.Pin(cs, pyb.Pin.OUT_PP, pyb.Pin.PULL_DOWN)
|
|
self.cs.high()
|
|
self.spi = pyb.SPI(aLoc, pyb.SPI.MASTER, baudrate = rate, polarity = 0, phase = 1, crc=None)
|
|
self.colorData = bytearray(2)
|
|
self.windowLocData = bytearray(4)
|
|
|
|
def on( self, aTF = True ) :
|
|
'''Turn display on or off.'''
|
|
self._writecommand(ST_DISPON if aTF else ST_DISPOFF)
|
|
|
|
def invertcolor( self, aBool ) :
|
|
'''Invert the color data IE: Black = White.'''
|
|
self._writecommand(ST_INVON if aBool else ST_INVOFF)
|
|
|
|
def setrgb( self, aTF = True ) :
|
|
'''True = rgb else bgr'''
|
|
self.rgb = TFTRBG if aTF else TFTBGR
|
|
self._setMADCTL()
|
|
|
|
def setrotation( self, aRot ) :
|
|
'''0 - 3. Starts vertical with top toward pins and rotates 90 deg
|
|
clockwise each step.'''
|
|
if (0 <= aRot < 4):
|
|
rotchange = self.rotate ^ aRot
|
|
self.rotate = aRot
|
|
#If switching from vertical to horizontal swap x,y
|
|
# (indicated by bit 0 changing).
|
|
if (rotchange & 1):
|
|
self.size.x, self.size.y = self.size.y, self.size.x
|
|
self._setMADCTL()
|
|
|
|
def drawpixel( self, aPos, aColor ) :
|
|
'''Draw a pixel at the given position'''
|
|
if 0 <= aPos.x < self.size.x and 0 <= aPos.y < self.size.y:
|
|
self._setwindowpoint(aPos)
|
|
self._pushcolor(aColor)
|
|
|
|
def drawstring( self, aPos, aString, aColor, aFont, aSize = 1 ) :
|
|
'''Draw a string at the given position. If the string reaches the end of the
|
|
display it is wrapped to aPos.x on the next line. aSize may be an integer
|
|
which will size the font uniformly on w,h or a Point with x,y scales or
|
|
any type that may be indexed with [0] or [1].'''
|
|
|
|
#Make a size either from single value or 2 elements.
|
|
if (type(aSize) == int) or (type(aSize) == float):
|
|
wh = Point(aSize, aSize)
|
|
elif (type(aSize) == Point):
|
|
wh = aSize
|
|
else:
|
|
wh = Point(aSize[0], aSize[1])
|
|
|
|
pos = aPos.clone()
|
|
width = wh.x * aFont["Width"] + 1
|
|
for c in aString:
|
|
self.drawchar(pos, c, aColor, aFont, wh)
|
|
pos.x += width
|
|
#We check > rather than >= to let the right (blank) edge of the
|
|
# character print off the right of the screen.
|
|
if pos.x + width > self.size.x:
|
|
pos.y += aFont["Height"] * wh.y + 1
|
|
pos.x = aPos.x
|
|
|
|
def drawchar( self, aPos, aChar, aColor, aFont, aSizes ) :
|
|
'''Draw a character at the given position using the given font and color.
|
|
aSizes is a Point with x, y as integer scales indicating the
|
|
# of pixels to draw for each pixel in the character.'''
|
|
|
|
if aFont == None:
|
|
return
|
|
|
|
startchar = aFont['Start']
|
|
endchar = aFont['End']
|
|
|
|
ci = ord(aChar)
|
|
if (startchar <= ci <= endchar):
|
|
fontw = aFont['Width']
|
|
fonth = aFont['Height']
|
|
ci = (ci - startchar) * fontw
|
|
|
|
charA = aFont["Data"][ci:ci + fontw]
|
|
pos = aPos.clone()
|
|
if aSizes.x <= 1 and aSizes.y <= 1 :
|
|
for c in charA :
|
|
pos.y = aPos.y
|
|
for r in range(fonth) :
|
|
if c & 0x01 :
|
|
self.drawpixel(pos, aColor)
|
|
pos.y += 1
|
|
c >>= 1
|
|
pos.x += 1
|
|
else:
|
|
for c in charA :
|
|
pos.y = aPos.y
|
|
for r in range(fonth) :
|
|
if c & 0x01 :
|
|
self.fillrect(pos, aSizes, aColor)
|
|
pos.y += aSizes.y
|
|
c >>= 1
|
|
pos.x += aSizes.x
|
|
|
|
def drawline( self, aStart, aEnd, aColor ) :
|
|
'''Draws a line from aStart to aEnd in the given color. Vertical or horizontal
|
|
lines are forwarded to vline and hline.'''
|
|
if aStart.x == aEnd.x:
|
|
#Make sure we use the smallest y.
|
|
pnt = aEnd if (aEnd.y < aStart.y) else aStart
|
|
self.vline(pnt, abs(aEnd.y - aStart.y) + 1, aColor)
|
|
elif aStart.y == aEnd.y:
|
|
#Make sure we use the smallest x.
|
|
pnt = aEnd if aEnd.x < aStart.x else aStart
|
|
self.hline(pnt, abs(aEnd.x - aStart.x) + 1, aColor)
|
|
else:
|
|
slope = float(aEnd.y - aStart.y) / (aEnd.x - aStart.x)
|
|
if (abs(slope) < 1.0):
|
|
for x in range(aStart.x, aEnd.x + 1) :
|
|
y = (x - aStart.x) * slope + aStart.y
|
|
self.drawpixel(Point(x, int(y + 0.5)), aColor)
|
|
else:
|
|
for y in range(aStart.y, aEnd.y + 1) :
|
|
x = (y - aStart.y) / slope + aStart.x
|
|
self.drawpixel(Point(int(x + 0.5), y), aColor)
|
|
|
|
def vline( self, aStart, aLen, aColor ) :
|
|
'''Draw a vertical line from aStart for aLen. aLen may be negative.'''
|
|
start = Point(clamp(aStart.x, 0, self.size.x), clamp(aStart.y, 0, self.size.y))
|
|
stop = Point(start.x, clamp(start.y + aLen, 0, self.size.y))
|
|
#Make sure smallest y 1st.
|
|
if (stop.y < start.y):
|
|
start, stop = stop, start
|
|
self._setwindowloc(start, stop)
|
|
self._draw(aLen, aColor)
|
|
|
|
def hline( self, aStart, aLen, aColor ) :
|
|
'''Draw a horizontal line from aStart for aLen. aLen may be negative.'''
|
|
start = Point(clamp(aStart.x, 0, self.size.x), clamp(aStart.y, 0, self.size.y))
|
|
stop = Point(clamp(start.x + aLen, 0, self.size.x), start.y)
|
|
#Make sure smallest x 1st.
|
|
if (stop.x < start.x):
|
|
start, stop = stop, start
|
|
self._setwindowloc(start, stop)
|
|
self._draw(aLen, aColor)
|
|
|
|
def rect( self, aStart, aSize, aColor ) :
|
|
'''Draw a hollow rectangle. aStart is the smallest coordinate corner
|
|
and aSize is a Point indicating width, height.'''
|
|
self.hline(aStart, aSize.x, aColor)
|
|
self.hline(Point(aStart.x, aStart.y + aSize.y - 1), aSize.x, aColor)
|
|
self.vline(aStart, aSize.y, aColor)
|
|
self.vline(Point(aStart.x + aSize.x - 1, aStart.y), aSize.y, aColor)
|
|
|
|
def fillrect( self, aStart, aSize, aColor ) :
|
|
'''Draw a filled rectangle. aStart is the smallest coordinate corner
|
|
and aSize is a Point indicating width, height.'''
|
|
start = Point(clamp(aStart.x, 0, self.size.x), clamp(aStart.y, 0, self.size.y))
|
|
end = Point(clamp(start.x + aSize.x - 1, 0, self.size.x), clamp(start.y + aSize.y - 1, 0, self.size.y))
|
|
|
|
if (end.x < start.x):
|
|
end.x, start.x = start.x, end.x
|
|
if (end.y < start.y):
|
|
end.y, start.y = start.y, end.y
|
|
|
|
self._setwindowloc(start, end)
|
|
numPixels = (end.x - start.x + 1) * (end.y - start.y + 1)
|
|
self._draw(numPixels, aColor)
|
|
|
|
def circle( self, aPos, aRadius, aColor ) :
|
|
'''Draw a hollow circle with the given radius and color with aPos as center.'''
|
|
self.colorData[0] = aColor >> 8
|
|
self.colorData[1] = aColor
|
|
xend = int(0.7071 * aRadius) + 1
|
|
rsq = aRadius * aRadius
|
|
for x in range(xend) :
|
|
y = int(sqrt(rsq - x * x))
|
|
xp = aPos.x + x
|
|
yp = aPos.y + y
|
|
xn = aPos.x - x
|
|
yn = aPos.y - y
|
|
xyp = aPos.x + y
|
|
yxp = aPos.y + x
|
|
xyn = aPos.x - y
|
|
yxn = aPos.y - x
|
|
|
|
self._setwindowpoint(Point(xp, yp))
|
|
self._writedata(self.colorData)
|
|
self._setwindowpoint(Point(xp, yn))
|
|
self._writedata(self.colorData)
|
|
self._setwindowpoint(Point(xn, yp))
|
|
self._writedata(self.colorData)
|
|
self._setwindowpoint(Point(xn, yn))
|
|
self._writedata(self.colorData)
|
|
self._setwindowpoint(Point(xp, yn))
|
|
self._writedata(self.colorData)
|
|
self._setwindowpoint(Point(xyp, yxp))
|
|
self._writedata(self.colorData)
|
|
self._setwindowpoint(Point(xyp, yxn))
|
|
self._writedata(self.colorData)
|
|
self._setwindowpoint(Point(xyn, yxp))
|
|
self._writedata(self.colorData)
|
|
self._setwindowpoint(Point(xyn, yxn))
|
|
self._writedata(self.colorData)
|
|
|
|
def fillcircle( self, aPos, aRadius, aColor ) :
|
|
'''Draw a filled circle with given radius and color with aPos as center'''
|
|
rsq = aRadius * aRadius
|
|
for x in range(aRadius) :
|
|
y = int(sqrt(rsq - x * x))
|
|
y0 = aPos.y - y
|
|
ln = y * 2
|
|
self.vline(Point(aPos.x + x, y0), ln, aColor)
|
|
self.vline(Point(aPos.x - x, y0), ln, aColor)
|
|
|
|
def fill( self, aColor ) :
|
|
'''Fill screen with the given color.'''
|
|
self.fillrect(Point(0, 0), self.size, aColor)
|
|
self._draw(self.size.x * self.size.y, aColor)
|
|
|
|
def _draw( self, aPixels, aColor ) :
|
|
'''Send given color to the device aPixels times.'''
|
|
self.colorData[0] = aColor >> 8
|
|
self.colorData[1] = aColor
|
|
|
|
self.dc.high()
|
|
self.cs.low()
|
|
for i in range(aPixels):
|
|
self.spi.send(self.colorData)
|
|
self.cs.high()
|
|
|
|
def _setwindowpoint( self, aPos ) :
|
|
'''Set a single point for drawing a color to.'''
|
|
x = int(aPos.x)
|
|
y = int(aPos.y)
|
|
self._writecommand(ST_CASET) #Column address set.
|
|
self.windowLocData[0] = 0x00
|
|
self.windowLocData[1] = x
|
|
self.windowLocData[2] = 0x00
|
|
self.windowLocData[3] = x
|
|
self._writedata(self.windowLocData)
|
|
|
|
self._writecommand(ST_RASET) #Row address set.
|
|
self.windowLocData[1] = y
|
|
self.windowLocData[3] = y
|
|
self._writedata(self.windowLocData)
|
|
self._writecommand(ST_RAMWR) #Write to RAM.
|
|
|
|
def _setwindowloc( self, aPos0, aPos1 ) :
|
|
'''Set a rectangular area for drawing a color to.'''
|
|
self._writecommand(ST_CASET) #Column address set.
|
|
self.windowLocData[0] = 0x00
|
|
self.windowLocData[1] = int(aPos0.x)
|
|
self.windowLocData[2] = 0x00
|
|
self.windowLocData[3] = int(aPos1.x)
|
|
self._writedata(self.windowLocData)
|
|
|
|
self._writecommand(ST_RASET) #Row address set.
|
|
self.windowLocData[1] = int(aPos0.y)
|
|
self.windowLocData[3] = int(aPos1.y)
|
|
self._writedata(self.windowLocData)
|
|
|
|
self._writecommand(ST_RAMWR) #Write to RAM.
|
|
|
|
def _writecommand( self, aCommand ) :
|
|
'''Write given command to the device.'''
|
|
self.dc.low()
|
|
self.cs.low()
|
|
self.spi.send(aCommand)
|
|
self.cs.high()
|
|
|
|
def _writedata( self, aData ) :
|
|
'''Write given data to the device. This may be
|
|
either a single int or a bytearray of values.'''
|
|
self.dc.high()
|
|
self.cs.low()
|
|
self.spi.send(aData)
|
|
self.cs.high()
|
|
|
|
def _pushcolor( self, aColor ) :
|
|
'''Push given color to the device.'''
|
|
self.colorData[0] = aColor >> 8
|
|
self.colorData[1] = aColor
|
|
self._writedata(self.colorData)
|
|
|
|
def _setMADCTL( self ) :
|
|
'''Set screen rotation and RGB/BGR format.'''
|
|
self._writecommand(ST_MADCTL)
|
|
self._writedata(TFTRotations[self.rotate] | self.rgb)
|
|
|
|
def _reset(self):
|
|
'''Reset the device.'''
|
|
self.dc.low()
|
|
self.reset.high()
|
|
pyb.delay(500)
|
|
self.reset.low()
|
|
pyb.delay(500)
|
|
self.reset.high()
|
|
pyb.delay(500)
|
|
|
|
def _initb(self):
|
|
'''Initialize blue tab version.'''
|
|
self.size.x = ScreenSize.x + 2
|
|
self.size.y = ScreenSize.y + 1
|
|
self._reset()
|
|
self._writecommand(ST_SWRESET) #Software reset.
|
|
pyb.delay(50)
|
|
self._writecommand(ST_SLPOUT) #out of sleep mode.
|
|
pyb.delay(500)
|
|
|
|
data1 = bytearray(1)
|
|
self._writecommand(ST_COLMOD) #Set color mode.
|
|
data1[0] = 0x05 #16 bit color.
|
|
self._writedata(data1)
|
|
pyb.delay(10)
|
|
|
|
data3 = bytearray([0x00, 0x06, 0x03]) #fastest refresh, 6 lines front, 3 lines back.
|
|
self._writecommand(ST_FRMCTR1) #Frame rate control.
|
|
self._writedata(data3)
|
|
pyb.delay(10)
|
|
|
|
self._writecommand(ST_MADCTL)
|
|
data1[0] = 0x08 #row address/col address, bottom to top refresh
|
|
self._writedata(data1)
|
|
|
|
data2 = bytearray(2)
|
|
self._writecommand(ST_DISSET5) #Display settings
|
|
data2[0] = 0x15 #1 clock cycle nonoverlap, 2 cycle gate rise, 3 cycle oscil, equalize
|
|
data2[1] = 0x02 #fix on VTL
|
|
self._writedata(data2)
|
|
|
|
self._writecommand(ST_INVCTR) #Display inversion control
|
|
data1[0] = 0x00 #Line inversion.
|
|
self._writedata(data1)
|
|
|
|
self._writecommand(ST_PWCTR1) #Power control
|
|
data2[0] = 0x02 #GVDD = 4.7V
|
|
data2[1] = 0x70 #1.0uA
|
|
self._writedata(data2)
|
|
pyb.delay(10)
|
|
|
|
self._writecommand(ST_PWCTR2) #Power control
|
|
data1[0] = 0x05 #VGH = 14.7V, VGL = -7.35V
|
|
self._writedata(data1)
|
|
|
|
#Took this out because with it the screen stays all white.
|
|
#But I tested on green tab version so maybe it will work for blue.
|
|
# self._writecommand(ST_PWCTR3) #Power control
|
|
# data2[0] = 0x01 #Opamp current small
|
|
# data2[1] = 0x02 #Boost frequency
|
|
# self._writedata(data2)
|
|
|
|
self._writecommand(ST_VMCTR1) #Power control
|
|
data2[0] = 0x3C #VCOMH = 4V
|
|
data2[1] = 0x38 #VCOML = -1.1V
|
|
self._writedata(data2)
|
|
pyb.delay(10)
|
|
|
|
self._writecommand(ST_PWCTR6) #Power control
|
|
data2[0] = 0x11
|
|
data2[1] = 0x15
|
|
self._writedata(data2)
|
|
|
|
#These different values don't seem to make a difference.
|
|
# dataGMCTRP = bytearray([0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f,
|
|
# 0x1b, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10])
|
|
dataGMCTRP = bytearray([0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29,
|
|
0x25, 0x2b, 0x39, 0x00, 0x01, 0x03, 0x10])
|
|
self._writecommand(ST_GMCTRP1)
|
|
self._writedata(dataGMCTRP)
|
|
|
|
# dataGMCTRN = bytearray([0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30,
|
|
# 0x30, 0x39, 0x3f, 0x00, 0x07, 0x03, 0x10])
|
|
dataGMCTRN = bytearray([0x03, 0x1d, 0x07, 0x06, 0x2e, 0x2c, 0x29, 0x2d, 0x2e,
|
|
0x2e, 0x37, 0x3f, 0x00, 0x00, 0x02, 0x10])
|
|
self._writecommand(ST_GMCTRN1)
|
|
self._writedata(dataGMCTRN)
|
|
pyb.delay(10)
|
|
|
|
self._writecommand(ST_CASET) #Column address set.
|
|
self.windowLocData[0] = 0x00
|
|
self.windowLocData[1] = 2 #Start at column 2
|
|
self.windowLocData[2] = 0x00
|
|
self.windowLocData[3] = self.size.x - 1
|
|
self._writedata(self.windowLocData)
|
|
|
|
self._writecommand(ST_RASET) #Row address set.
|
|
self.windowLocData[1] = 1 #Start at row 2.
|
|
self.windowLocData[3] = self.size.y - 1
|
|
self._writedata(self.windowLocData)
|
|
|
|
self._writecommand(ST_NORON) #Normal display on.
|
|
pyb.delay(10)
|
|
|
|
self._writecommand(ST_RAMWR)
|
|
pyb.delay(500)
|
|
|
|
self._writecommand(ST_DISPON)
|
|
self.cs.high()
|
|
pyb.delay(500)
|
|
|
|
def _initr(self):
|
|
'''Initialize a red tab version.'''
|
|
self._reset()
|
|
|
|
self._writecommand(ST_SWRESET) #Software reset.
|
|
pyb.delay(150)
|
|
self._writecommand(ST_SLPOUT) #out of sleep mode.
|
|
pyb.delay(500)
|
|
|
|
data3 = bytearray([0x01, 0x2C, 0x2D]) #fastest refresh, 6 lines front, 3 lines back.
|
|
self._writecommand(ST_FRMCTR1) #Frame rate control.
|
|
self._writedata(data3)
|
|
|
|
self._writecommand(ST_FRMCTR2) #Frame rate control.
|
|
self._writedata(data3)
|
|
|
|
data6 = bytearray([0x01, 0x2c, 0x2d, 0x01, 0x2c, 0x2d])
|
|
self._writecommand(ST_FRMCTR3) #Frame rate control.
|
|
self._writedata(data6)
|
|
pyb.delay(10)
|
|
|
|
data1 = bytearray(1)
|
|
self._writecommand(ST_INVCTR) #Display inversion control
|
|
data1[0] = 0x07 #Line inversion.
|
|
self._writedata(data1)
|
|
|
|
self._writecommand(ST_PWCTR1) #Power control
|
|
data3[0] = 0xA2
|
|
data3[1] = 0x02
|
|
data3[2] = 0x84
|
|
self._writedata(data3)
|
|
|
|
self._writecommand(ST_PWCTR2) #Power control
|
|
data1[0] = 0xC5 #VGH = 14.7V, VGL = -7.35V
|
|
self._writedata(data1)
|
|
|
|
data2 = bytearray(2)
|
|
self._writecommand(ST_PWCTR3) #Power control
|
|
data2[0] = 0x0A #Opamp current small
|
|
data2[1] = 0x00 #Boost frequency
|
|
self._writedata(data2)
|
|
|
|
self._writecommand(ST_PWCTR4) #Power control
|
|
data2[0] = 0x8A #Opamp current small
|
|
data2[1] = 0x2A #Boost frequency
|
|
self._writedata(data2)
|
|
|
|
self._writecommand(ST_PWCTR5) #Power control
|
|
data2[0] = 0x8A #Opamp current small
|
|
data2[1] = 0xEE #Boost frequency
|
|
self._writedata(data2)
|
|
|
|
self._writecommand(ST_VMCTR1) #Power control
|
|
data1[0] = 0x0E
|
|
self._writedata(data1)
|
|
|
|
self._writecommand(ST_INVOFF)
|
|
|
|
self._writecommand(ST_MADCTL) #Power control
|
|
data1[0] = 0xC8
|
|
self._writedata(data1)
|
|
|
|
self._writecommand(ST_COLMOD)
|
|
data1[0] = 0x05
|
|
self._writedata(data1)
|
|
|
|
self._writecommand(ST_CASET) #Column address set.
|
|
self.windowLocData[0] = 0x00
|
|
self.windowLocData[1] = 0x00
|
|
self.windowLocData[2] = 0x00
|
|
self.windowLocData[3] = self.size.x - 1
|
|
self._writedata(self.windowLocData)
|
|
|
|
self._writecommand(ST_RASET) #Row address set.
|
|
self.windowLocData[3] = self.size.y - 1
|
|
self._writedata(self.windowLocData)
|
|
|
|
dataGMCTRP = bytearray([0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f,
|
|
0x1b, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10])
|
|
self._writecommand(ST_GMCTRP1)
|
|
self._writedata(dataGMCTRP)
|
|
|
|
dataGMCTRN = bytearray([0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30,
|
|
0x30, 0x39, 0x3f, 0x00, 0x07, 0x03, 0x10])
|
|
self._writecommand(ST_GMCTRN1)
|
|
self._writedata(dataGMCTRN)
|
|
pyb.delay(10)
|
|
|
|
self._writecommand(ST_DISPON)
|
|
pyb.delay(100)
|
|
|
|
self._writecommand(ST_NORON) #Normal display on.
|
|
pyb.delay(10)
|
|
|
|
self.cs.high()
|
|
|
|
def _initg(self):
|
|
'''Initialize a green tab version.'''
|
|
self._reset()
|
|
|
|
self._writecommand(ST_SWRESET) #Software reset.
|
|
pyb.delay(150)
|
|
self._writecommand(ST_SLPOUT) #out of sleep mode.
|
|
pyb.delay(255)
|
|
|
|
data3 = bytearray([0x01, 0x2C, 0x2D]) #fastest refresh, 6 lines front, 3 lines back.
|
|
self._writecommand(ST_FRMCTR1) #Frame rate control.
|
|
self._writedata(data3)
|
|
|
|
self._writecommand(ST_FRMCTR2) #Frame rate control.
|
|
self._writedata(data3)
|
|
|
|
data6 = bytearray([0x01, 0x2c, 0x2d, 0x01, 0x2c, 0x2d])
|
|
self._writecommand(ST_FRMCTR3) #Frame rate control.
|
|
self._writedata(data6)
|
|
pyb.delay(10)
|
|
|
|
self._writecommand(ST_INVCTR) #Display inversion control
|
|
self._writedata(0x07)
|
|
|
|
self._writecommand(ST_PWCTR1) #Power control
|
|
data3[0] = 0xA2
|
|
data3[1] = 0x02
|
|
data3[2] = 0x84
|
|
self._writedata(data3)
|
|
|
|
self._writecommand(ST_PWCTR2) #Power control
|
|
self._writedata(0xC5)
|
|
|
|
data2 = bytearray(2)
|
|
self._writecommand(ST_PWCTR3) #Power control
|
|
data2[0] = 0x0A #Opamp current small
|
|
data2[1] = 0x00 #Boost frequency
|
|
self._writedata(data2)
|
|
|
|
self._writecommand(ST_PWCTR4) #Power control
|
|
data2[0] = 0x8A #Opamp current small
|
|
data2[1] = 0x2A #Boost frequency
|
|
self._writedata(data2)
|
|
|
|
self._writecommand(ST_PWCTR5) #Power control
|
|
data2[0] = 0x8A #Opamp current small
|
|
data2[1] = 0xEE #Boost frequency
|
|
self._writedata(data2)
|
|
|
|
self._writecommand(ST_VMCTR1) #Power control
|
|
self._writedata(0x0E)
|
|
|
|
self._writecommand(ST_INVOFF)
|
|
|
|
self._setMADCTL()
|
|
|
|
self._writecommand(ST_COLMOD)
|
|
self._writedata(0x05)
|
|
|
|
self._writecommand(ST_CASET) #Column address set.
|
|
self.windowLocData[0] = 0x00
|
|
self.windowLocData[1] = 0x01 #Start at row/column 1.
|
|
self.windowLocData[2] = 0x00
|
|
self.windowLocData[3] = self.size.x - 1
|
|
self._writedata(self.windowLocData)
|
|
|
|
self._writecommand(ST_RASET) #Row address set.
|
|
self.windowLocData[3] = self.size.y - 1
|
|
self._writedata(self.windowLocData)
|
|
|
|
dataGMCTRP = bytearray([0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29,
|
|
0x25, 0x2b, 0x39, 0x00, 0x01, 0x03, 0x10])
|
|
self._writecommand(ST_GMCTRP1)
|
|
self._writedata(dataGMCTRP)
|
|
|
|
dataGMCTRN = bytearray([0x03, 0x1d, 0x07, 0x06, 0x2e, 0x2c, 0x29, 0x2d, 0x2e,
|
|
0x2e, 0x37, 0x3f, 0x00, 0x00, 0x02, 0x10])
|
|
self._writecommand(ST_GMCTRN1)
|
|
self._writedata(dataGMCTRN)
|
|
|
|
self._writecommand(ST_NORON) #Normal display on.
|
|
pyb.delay(10)
|
|
|
|
self._writecommand(ST_DISPON)
|
|
pyb.delay(100)
|
|
|
|
self.cs.high()
|
|
|
|
def maker():
|
|
t = TFT(1, "X1", "X2")
|
|
print("Initializing")
|
|
t._initr()
|
|
t.fill(0)
|
|
return t
|
|
|
|
def makeb( ):
|
|
t = TFT(1, "X1", "X2")
|
|
print("Initializing")
|
|
t._initb()
|
|
t.fill(0)
|
|
return t
|
|
|
|
def makeg( ):
|
|
t = TFT(1, "X1", "X2")
|
|
print("Initializing")
|
|
t._initg()
|
|
t.fill(0)
|
|
return t
|