aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2018-11-21 18:03:13 -0500
committerKevin O'Connor <kevin@koconnor.net>2018-11-21 20:45:53 -0500
commitd2aa78c16a008fc989adc1e916086a97a5a051ce (patch)
tree8c9f1f5ab901d12a9b2281fc0a542a307262c153
parent065a8eb826bf4fe309646c9538bbad7138e98518 (diff)
downloadkutter-d2aa78c16a008fc989adc1e916086a97a5a051ce.tar.gz
kutter-d2aa78c16a008fc989adc1e916086a97a5a051ce.tar.xz
kutter-d2aa78c16a008fc989adc1e916086a97a5a051ce.zip
uc1701: Cache icons and fonts in byte display order
This reduces the amount of bit manipulaton needed during screen updates. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--klippy/extras/display/uc1701.py77
1 files changed, 34 insertions, 43 deletions
diff --git a/klippy/extras/display/uc1701.py b/klippy/extras/display/uc1701.py
index c9de56e0..86d0649f 100644
--- a/klippy/extras/display/uc1701.py
+++ b/klippy/extras/display/uc1701.py
@@ -13,7 +13,6 @@ TextGlyphs = { 'right_arrow': '\x1a', 'degrees': '\xf8' }
class UC1701:
DATA_PIN_NAME = "a0_pin"
- EMPTY_CHAR = (0, 32, 255)
def __init__(self, config):
self.spi = extras.bus.MCU_SPI_from_config(config, 0,
default_speed=10000000)
@@ -33,6 +32,13 @@ class UC1701:
self.vram = [bytearray(128) for i in range(8)]
self.all_framebuffers = [(self.vram[i], bytearray('~'*128), i)
for i in range(8)]
+ # Cache fonts and icons in display byte order
+ self.font = [self._swizzle_bits(c) for c in font8x14.VGA_FONT]
+ self.icons = {}
+ for name, icon in icons.Icons16x16.items():
+ top1, bot1 = self._swizzle_bits([d >> 8 for d in icon])
+ top2, bot2 = self._swizzle_bits(icon)
+ self.icons[name] = (top1 + top2, bot1 + bot2)
def build_config(self):
self.update_pin_cmd = self.spi.get_mcu().lookup_command(
"update_digital_out oid=%c value=%c",
@@ -93,60 +99,45 @@ class UC1701:
# Send Data
self.send(new_data[col_pos:col_pos+count], is_data=True)
old_data[:] = new_data
- def set_pixel(self, pix_x, pix_y, exclusive=True):
- page_idx = pix_y // 8
- page_byte = 0x01 << (pix_y % 8)
- if exclusive and self.vram[page_idx][pix_x] & page_byte:
- #invert pixel if it has alread been set
- self.vram[page_idx][pix_x] &= ~page_byte
- else:
- #set the correct pixel in the vram buffer to 1
- self.vram[page_idx][pix_x] |= page_byte
- def clear_pixel(self, pix_x, pix_y):
- page_idx = pix_y // 8
- page_byte = ~(0x01 << (pix_y % 8))
- #set the correct pixel in the vram buffer to 0
- self.vram[page_idx][pix_x] &= page_byte
+ def _swizzle_bits(self, data):
+ # Convert 8x16 data into display col/row order
+ bits_top = [0] * 8
+ bits_bot = [0] * 8
+ for row in range(8):
+ for col in range(8):
+ bits_top[col] |= ((data[row] >> (8 - col)) & 1) << row
+ bits_bot[col] |= ((data[row + 8] >> (8 - col)) & 1) << row
+ return (bits_top, bits_bot)
def write_text(self, x, y, data):
if x + len(data) > 16:
data = data[:16 - min(x, 16)]
- pix_x = x*8
- pix_y = y*16
+ pix_x = x * 8
+ page_top = self.vram[y * 2]
+ page_bot = self.vram[y * 2 + 1]
for c in data:
- c_idx = ord(c) & 0xFF
- if c_idx in self.EMPTY_CHAR:
- # Empty char
- pix_x += 8
- continue
- char = font8x14.VGA_FONT[c_idx]
- bit_y = pix_y
- for bits in char:
- if bits:
- bit_x = pix_x
- for i in range(7, -1, -1):
- mask = 0x01 << i
- if bits & mask:
- self.set_pixel(bit_x, bit_y)
- bit_x += 1
- bit_y += 1
+ bits_top, bits_bot = self.font[ord(c)]
+ page_top[pix_x:pix_x+8] = bits_top
+ page_bot[pix_x:pix_x+8] = bits_bot
pix_x += 8
def write_graphics(self, x, y, row, data):
if x + len(data) > 16:
data = data[:16 - min(x, 16)]
- pix_x = x*8
- pix_y = y*16 + row
+ page = self.vram[y * 2 + (row >= 8)]
+ bit = 1 << (row % 8)
+ pix_x = x * 8
for bits in data:
- for i in range(7, -1, -1):
- mask = 0x01 << i
- if bits & mask:
- self.set_pixel(pix_x, pix_y)
+ for col in range(8):
+ if (bits << col) & 0x80:
+ page[pix_x] ^= bit
pix_x += 1
def write_glyph(self, x, y, glyph_name):
- icon = icons.Icons16x16.get(glyph_name)
- if icon is not None:
+ icon = self.icons.get(glyph_name)
+ if icon is not None and x < 15:
# Draw icon in graphics mode
- for i, bits in enumerate(icon):
- self.write_graphics(x, y, i, [(bits >> 8) & 0xff, bits & 0xff])
+ pix_x = x * 8
+ page_idx = y * 2
+ self.vram[page_idx][pix_x:pix_x+16] = icon[0]
+ self.vram[page_idx + 1][pix_x:pix_x+16] = icon[1]
return 2
char = TextGlyphs.get(glyph_name)
if char is not None: