From 00c5edaf1695486d112daf6da705be2b992a8f2e Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Fri, 7 Jun 2024 10:53:25 +0100 Subject: [PATCH] Update st7789 driver for greyscale. --- drivers/st7789/st7789_4bit.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/st7789/st7789_4bit.py b/drivers/st7789/st7789_4bit.py index 0261980..8f13f85 100644 --- a/drivers/st7789/st7789_4bit.py +++ b/drivers/st7789/st7789_4bit.py @@ -37,15 +37,22 @@ WAVESHARE_13 = (0, 0, 16) # Waveshare 1.3" 240x240 LCD contributed by Aaron Mit @micropython.viper -def _lcopy(dest: ptr16, source: ptr8, lut: ptr16, length: int): +def _lcopy(dest: ptr16, source: ptr8, lut: ptr16, length: int, gscale: bool): # rgb565 - 16bit/pixel n: int = 0 x: int = 0 while length: c = source[x] - dest[n] = lut[c >> 4] # current pixel - n += 1 - dest[n] = lut[c & 0x0F] # next pixel + p = c >> 4 # current pixel + q = c & 0x0F # next pixel + if gscale: + dest[n] = (p >> 1 | p << 4 | p << 9 | ((p & 0x01) << 15)) ^ 0xFFFF + n += 1 + dest[n] = (q >> 1 | q << 4 | q << 9 | ((q & 0x01) << 15)) ^ 0xFFFF + else: + dest[n] = lut[p] # current pixel + n += 1 + dest[n] = lut[q] # next pixel n += 1 x += 1 length -= 1 @@ -88,11 +95,12 @@ class ST7789(framebuf.FrameBuffer): orientation = display[2] # where x, y is the RAM offset self._spi_init = init_spi # Possible user callback self._lock = asyncio.Lock() + self._gscale = False # Interpret buffer as index into color LUT mode = framebuf.GS4_HMSB # Use 4bit greyscale. self.palette = BoolPalette(mode) gc.collect() buf = bytearray(height * -(-width // 2)) # Ceiling division for odd widths - self._mvb = memoryview(buf) + self.mvb = memoryview(buf) super().__init__(buf, width, height, mode) self._linebuf = bytearray(self.width * 2) # 16 bit color out self._init(disp_mode, orientation) @@ -206,6 +214,11 @@ class ST7789(framebuf.FrameBuffer): # Row address set self._wcd(b"\x2b", int.to_bytes((ys << 16) + ye, 4, "big")) + def greyscale(self, gs=None): + if gs is not None: + self._gscale = gs + return self._gscale + # @micropython.native # Made virtually no difference to timing. def show(self): # Blocks for 83ms @60MHz SPI # Blocks for 60ms @30MHz SPI on TTGO in PORTRAIT mode @@ -215,7 +228,8 @@ class ST7789(framebuf.FrameBuffer): wd = -(-self.width // 2) # Ceiling division for odd number widths end = self.height * wd lb = memoryview(self._linebuf) - buf = self._mvb + cm = self._gscale # color False, greyscale True + buf = self.mvb if self._spi_init: # A callback was passed self._spi_init(self._spi) # Bus may be shared self._dc(0) @@ -223,7 +237,7 @@ class ST7789(framebuf.FrameBuffer): self._spi.write(b"\x2c") # RAMWR self._dc(1) for start in range(0, end, wd): - _lcopy(lb, buf[start:], clut, wd) # Copy and map colors + _lcopy(lb, buf[start:], clut, wd, cm) # Copy and map colors self._spi.write(lb) self._cs(1) # print(ticks_diff(ticks_us(), ts)) @@ -237,7 +251,8 @@ class ST7789(framebuf.FrameBuffer): clut = ST7789.lut wd = -(-self.width // 2) lb = memoryview(self._linebuf) - buf = self._mvb + cm = self._gscale # color False, greyscale True + buf = self.mvb line = 0 for n in range(split): if self._spi_init: # A callback was passed @@ -247,7 +262,7 @@ class ST7789(framebuf.FrameBuffer): self._spi.write(b"\x3c" if n else b"\x2c") # RAMWR/Write memory continue self._dc(1) for start in range(wd * line, wd * (line + lines), wd): - _lcopy(lb, buf[start:], clut, wd) # Copy and map colors + _lcopy(lb, buf[start:], clut, wd, cm) # Copy and map colors self._spi.write(lb) line += lines self._cs(1)