""" 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)