diff --git a/wasp/boards/simulator/micropython.py b/wasp/boards/simulator/micropython.py index 41c30a4..804f514 100644 --- a/wasp/boards/simulator/micropython.py +++ b/wasp/boards/simulator/micropython.py @@ -11,9 +11,13 @@ def viper(fn): def ptr8(buf): return buf + def ptr16(buf): + return memoryview(buf).cast('H') + # This is a bit of a hack since the scope for ptr8 won't be right # but it does mean no changes to the client fn.__globals__['ptr8'] = ptr8 + fn.__globals__['ptr16'] = ptr16 return fn diff --git a/wasp/draw565.py b/wasp/draw565.py index 50ff592..8dd8de5 100644 --- a/wasp/draw565.py +++ b/wasp/draw565.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: LGPL-3.0-or-later # Copyright (C) 2020 Daniel Thompson +import array import fonts.sans24 import micropython @@ -45,13 +46,10 @@ def _expand_rgb(eightbit: int) -> int: @micropython.viper def _fill(mv, color: int, count: int, offset: int): - p = ptr8(mv) - colorhi = color >> 8 - colorlo = color & 0xff + p = ptr16(mv) - for x in range(count): - p[2*(x+offset) ] = colorhi - p[2*(x+offset) + 1] = colorlo + for x in range(offset, offset+count): + p[x] = color def _bounding_box(s, font): w = 0 @@ -110,6 +108,7 @@ class Draw565(object): def rleblit(self, image, pos=(0, 0), fg=0xffff, bg=0): """Decode and draw a 1-bit RLE image.""" display = self._display + write_data = display.write_data (sx, sy, rle) = image display.set_window(pos[0], pos[1], sx, sy) @@ -126,7 +125,7 @@ class Draw565(object): rl -= count if bp >= sx: - display.write_data(buf) + write_data(buf) bp = 0 if color == bg: @@ -138,48 +137,50 @@ class Draw565(object): def rle2bit(self, image, x, y): """Decode and draw a 2-bit RLE image.""" display = self._display + quick_write = display.quick_write (sx, sy, rle) = image display.set_window(x, y, sx, sy) + palette = array.array('H', (0, 0xfffe, 0x7bef, 0xffff)) + next_color = 1 + rl = 0 buf = memoryview(display.linebuffer)[0:2*sx] bp = 0 - rl = 0 - palette = [ 0, 0xfffe, 0x7bef, 0xffff ] - next_color = 1 - - def blit_run(color, rl): - nonlocal bp - while rl: - count = min(sx - bp, rl) - _fill(buf, color, count, bp) - bp += count - rl -= count - - if bp >= sx: - display.write_data(buf) - bp = 0 + display.quick_start() for op in rle: if rl == 0: px = op >> 6 rl = op & 0x3f if 0 == rl: rl = -1 - elif rl < 63: - blit_run(palette[px], rl) - rl = 0 + continue + if rl >= 63: + continue elif rl > 0: rl += op - if op < 255: - blit_run(palette[px], rl) - rl = 0 + if op >= 255: + continue else: palette[next_color] = _expand_rgb(op) - next_color += 1 - if next_color >= len(palette): + if next_color < 3: + next_color += 1 + else: next_color = 1 rl = 0 + continue + + while rl: + count = min(sx - bp, rl) + _fill(buf, palette[px], count, bp) + bp += count + rl -= count + + if bp >= sx: + quick_write(buf) + bp = 0 + display.quick_end() def set_color(self, color, bg=0): """Set the foreground (color) and background (bg) color. diff --git a/wasp/drivers/st7789.py b/wasp/drivers/st7789.py index 980435b..aca89db 100644 --- a/wasp/drivers/st7789.py +++ b/wasp/drivers/st7789.py @@ -121,13 +121,13 @@ class ST7789(object): class ST7789_SPI(ST7789): def __init__(self, width, height, spi, cs, dc, res=None, rate=8000000): - self.spi = spi - self.dc = dc + self.quick_write = spi.write + self.cs = cs.value + self.dc = dc.value self.res = res - self.cs = cs self.rate = rate - #self.spi.init(baudrate=self.rate, polarity=1, phase=1) + #spi.init(baudrate=self.rate, polarity=1, phase=1) cs.init(cs.OUT, value=1) dc.init(dc.OUT, value=0) if res: @@ -145,13 +145,23 @@ class ST7789_SPI(ST7789): sleep_ms(125) def write_cmd(self, cmd): - self.dc(0) - self.cs(0) - self.spi.write(bytearray([cmd])) - self.cs(1) - self.dc(1) + dc = self.dc + cs = self.cs + + dc(0) + cs(0) + self.quick_write(bytearray([cmd])) + cs(1) + dc(1) def write_data(self, buf): + cs = self.cs + cs(0) + self.quick_write(buf) + cs(1) + + def quick_start(self): self.cs(0) - self.spi.write(buf) + + def quick_end(self): self.cs(1)