104 lines
3.5 KiB
Python
104 lines
3.5 KiB
Python
"""
|
|
ST7789/FrameBuffer
|
|
|
|
MicroPython library for the ST7789(TFT-SPI)
|
|
=======================================================
|
|
@dahanzimin From the Mixly Team
|
|
"""
|
|
import time
|
|
import uframebuf
|
|
from machine import Pin, PWM
|
|
|
|
class ST7789(uframebuf.FrameBuffer_Uincode):
|
|
def __init__(self, spi, width, height, dc_pin=None, cs_pin=None, bl_pin=None, brightness=0.6, font_address=0x700000):
|
|
self.spi = spi
|
|
self.dc = Pin(dc_pin, Pin.OUT, value=1)
|
|
self.cs = Pin(cs_pin, Pin.OUT, value=1)
|
|
self._buffer = bytearray(width * height * 2)
|
|
super().__init__(self._buffer, width, height, uframebuf.RGB565)
|
|
self.font(font_address)
|
|
self._init()
|
|
# self.show()
|
|
self.bl_led = bl_pin if callable(bl_pin) else PWM(Pin(bl_pin))
|
|
self._oneclight = True
|
|
self._brightness = brightness
|
|
|
|
def _write(self, cmd, dat=None):
|
|
self.cs.off()
|
|
self.dc.off()
|
|
self.spi.write(bytearray([cmd]))
|
|
self.cs.on()
|
|
if dat is not None:
|
|
self.cs.off()
|
|
self.dc.on()
|
|
self.spi.write(dat)
|
|
self.cs.on()
|
|
|
|
def _init(self):
|
|
"""Display initialization configuration"""
|
|
for cmd, data, delay in [
|
|
(0x11, None, 120000),
|
|
(0x36, b'\x00', 10),
|
|
(0x3A, b'\x05', 10),
|
|
(0xB2, b'\x1F\x1F\x00\x33\x33', 10),
|
|
(0xB7, b'\x00', 10),
|
|
(0xBB, b'\x3F', 10),
|
|
(0xC0, b'\x2C', 10),
|
|
(0xC2, b'\x01', 10),
|
|
(0xC3, b'\x0F', 10),
|
|
(0xC4, b'\x20', 10),
|
|
(0xC6, b'\x13', 10),
|
|
(0xD0, b'\xA4\xA1', 10),
|
|
(0xD6, b'\xA1', 10),
|
|
(0xE0, b'\xF0\x06\x0D\x0B\x0A\x07\x2E\x43\x45\x38\x14\x13\x25\x29', 10),
|
|
(0xE1, b'\xF0\x07\x0A\x08\x07\x23\x2E\x33\x44\x3A\x16\x17\x26\x2C', 10),
|
|
(0xE4, b'\x1D\x00\x00', 10),
|
|
(0x21, None, 10),
|
|
(0x29, None, 10),
|
|
]:
|
|
self._write(cmd, data)
|
|
if delay:
|
|
time.sleep_us(delay)
|
|
|
|
def _write(self, command=None, data=None):
|
|
"""SPI write to the device: commands and data."""
|
|
if command is not None:
|
|
self.cs.off()
|
|
self.dc.off()
|
|
self.spi.write(bytes([command]))
|
|
self.cs.on()
|
|
if data is not None:
|
|
self.cs.off()
|
|
self.dc.on()
|
|
self.spi.write(data)
|
|
self.cs.on()
|
|
|
|
def get_brightness(self):
|
|
return self._brightness
|
|
|
|
def set_brightness(self, brightness):
|
|
if not 0.0 <= brightness <= 1.0:
|
|
raise ValueError(
|
|
"Brightness must be a decimal number in the range: 0.0~1.0")
|
|
self._brightness = brightness
|
|
if callable(self.bl_led):
|
|
self.bl_led(brightness * 100)
|
|
elif isinstance(self.bl_led, PWM):
|
|
self.bl_led.duty_u16(int(brightness * 60000))
|
|
|
|
def color(self, red, green=None, blue=None):
|
|
""" Convert red, green and blue values (0-255) into a 16-bit 565 encoding."""
|
|
if green is None or blue is None:
|
|
return red
|
|
else:
|
|
return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3
|
|
|
|
def show(self):
|
|
"""Refresh the display and show the changes."""
|
|
if self._oneclight:
|
|
self.set_brightness(self._brightness)
|
|
self._oneclight = False
|
|
self._write(0x2A, b'\x00\x00\x00\xef')
|
|
self._write(0x2B, b'\x00\x00\x00\xef')
|
|
self._write(0x2C, self._buffer)
|