diff --git a/config/example-extras.cfg b/config/example-extras.cfg index 46e056ad..976d0081 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -1913,7 +1913,15 @@ # pixel) where '.' is a blank pixel and '*' is an on pixel (e.g., # "****************" to display a solid horizontal line). Put each # display line into a separate config line. The glyph must consist -# of exactly 16 lines with 16 bits each. +# of exactly 16 lines with 16 bits each. This parameter is optional. +#hd44780_data: +# Glyph to use on 20x4 hd44780 displays. The glyph must consist of +# exactly 8 lines with 5 bits each. This parameter is optional. +#hd44780_slot: +# The hd44780 hardware index (0..7) to store the glyph at. If +# multiple distinct images use the same slot then make sure to only +# use one of those images in any given screen. This parameter is +# required if hd44780_data is specified. # If a primary [display] section has been defined in printer.cfg as shown # above it is possible to define multiple auxilary displays. Note that diff --git a/klippy/extras/display/display.cfg b/klippy/extras/display/display.cfg index 1e9d152e..cddc9476 100644 --- a/klippy/extras/display/display.cfg +++ b/klippy/extras/display/display.cfg @@ -188,7 +188,7 @@ text: { render("_print_status") } ###################################################################### -# Default display glyphs +# Default 16x4 glyphs ###################################################################### [display_glyph extruder] @@ -327,8 +327,130 @@ data: # In addition to the above glyphs, 16x4 displays also have the # following hard-coded single character glyphs: right_arrow, degrees. -# The 20x4 displays do not have configurable glyphs. They do have -# hard-coded support for the following single character glyphs: -# right_arrow, degrees, extruder, bed, bed_heat1 (same as bed), -# bed_heat2 (same as bed), feedrate, clock, usb, sd, fan1, fan2 (same -# as fan1). + +###################################################################### +# Default 20x4 glyphs +###################################################################### + +[display_glyph extruder] +hd44780_slot: 0 +hd44780_data: + ..*.. + .*.*. + .*.*. + .*.*. + .*.*. + *...* + *...* + .***. + +[display_glyph bed] +hd44780_slot: 1 +hd44780_data: + ..... + ***** + *.*.* + *...* + *.*.* + ***** + ..... + ..... + +[display_glyph bed_heat1] +hd44780_slot: 1 +hd44780_data: + ..... + ***** + *.*.* + *...* + *.*.* + ***** + ..... + ..... + +[display_glyph bed_heat2] +hd44780_slot: 1 +hd44780_data: + ..... + ***** + *.*.* + *...* + *.*.* + ***** + ..... + ..... + +[display_glyph fan] +hd44780_slot: 2 +hd44780_data: + ..... + *..** + **.*. + ..*.. + .*.** + **..* + ..... + ..... + +[display_glyph feedrate] +hd44780_slot: 3 +hd44780_data: + ***.. + *.... + **... + *.*** + ..*.* + ..**. + ..*.* + ..... + +[display_glyph clock] +hd44780_slot: 4 +hd44780_data: + ..... + .***. + *..** + *.*.* + *...* + .***. + ..... + ..... + +[display_glyph degrees] +hd44780_slot: 5 +hd44780_data: + .**.. + *..*. + *..*. + .**.. + ..... + ..... + ..... + ..... + +[display_glyph usb] +hd44780_slot: 6 +hd44780_data: + .***. + .***. + .***. + ***** + ***** + ***** + ..*.. + ..*.. + +[display_glyph sd] +hd44780_slot: 6 +hd44780_data: + ..... + ..*** + .**** + ***** + ***** + ***** + ***** + ..... + +# In addition to the above glyphs, 20x4 displays also have the +# following hard-coded glyphs: right_arrow. diff --git a/klippy/extras/display/display.py b/klippy/extras/display/display.py index 78d6667c..ccf7c391 100644 --- a/klippy/extras/display/display.py +++ b/klippy/extras/display/display.py @@ -104,6 +104,18 @@ class PrinterLCD: self.screen_update_timer = self.reactor.register_timer( self.screen_update_event) # Configurable display + def _parse_glyph(self, config, glyph_name, data, width, height): + glyph_data = [] + for line in data.split('\n'): + line = line.strip().replace('.', '0').replace('*', '1') + if not line: + continue + if len(line) != width or line.replace('0', '').replace('1', ''): + raise config.error("Invalid glyph line in %s" % (glyph_name,)) + glyph_data.append(int(line, 2)) + if len(glyph_data) != height: + raise config.error("Glyph %s incorrect lines" % (glyph_name,)) + return glyph_data def load_config(self, config): # Load default display config file pconfig = self.printer.lookup_object('configfile') @@ -145,18 +157,15 @@ class PrinterLCD: if c.get_name() not in dg_main_names] for dg in dg_main + dg_def: glyph_name = dg.get_name()[len(dg_prefix):] - glyph_data = [] - for line in dg.get('data').split('\n'): - line = line.strip().replace('.', '0').replace('*', '1') - if not line: - continue - if len(line) != 16 or line.replace('0', '').replace('1', ''): - raise config.error("Invalid glyph line in %s" - % (glyph_name,)) - glyph_data.append(int(line, 2)) - if len(glyph_data) != 16: - raise config.error("Glyph %s must be 16 lines" % (glyph_name,)) - icons[glyph_name] = glyph_data + data = dg.get('data', None) + if data is not None: + idata = self._parse_glyph(config, glyph_name, data, 16, 16) + icons.setdefault(glyph_name, {})['icon16x16'] = idata + data = dg.get('hd44780_data', None) + if data is not None: + slot = dg.getint('hd44780_slot', minval=0, maxval=7) + idata = self._parse_glyph(config, glyph_name, data, 5, 8) + icons.setdefault(glyph_name, {})['icon5x8'] = (slot, idata) self.lcd_chip.set_glyphs(icons) # Initialization def handle_ready(self): diff --git a/klippy/extras/display/hd44780.py b/klippy/extras/display/hd44780.py index 19ad0d3e..8ef4102c 100644 --- a/klippy/extras/display/hd44780.py +++ b/klippy/extras/display/hd44780.py @@ -8,6 +8,8 @@ import logging BACKGROUND_PRIORITY_CLOCK = 0x7fffffff00000000 +TextGlyphs = { 'right_arrow': '\x7e' } + HD44780_DELAY = .000040 class HD44780: @@ -27,6 +29,7 @@ class HD44780: self.oid = self.mcu.create_oid() self.mcu.register_config_callback(self.build_config) self.send_data_cmd = self.send_cmds_cmd = None + self.icons = {} # framebuffers self.text_framebuffers = [bytearray(' '*40), bytearray(' '*40)] self.glyph_framebuffer = bytearray(64) @@ -85,10 +88,6 @@ class HD44780: for i, cmds in enumerate(init): minclock = self.mcu.print_time_to_clock(print_time + i * .100) self.send_cmds_cmd.send([self.oid, cmds], minclock=minclock) - # Add custom fonts - self.glyph_framebuffer[:len(HD44780_chars)] = HD44780_chars - for i in range(len(self.glyph_framebuffer)): - self.all_framebuffers[2][1][i] = self.glyph_framebuffer[i] ^ 1 self.flush() def write_text(self, x, y, data): if x + len(data) > 20: @@ -96,8 +95,17 @@ class HD44780: pos = x + ((y & 0x02) >> 1) * 20 self.text_framebuffers[y & 1][pos:pos+len(data)] = data def set_glyphs(self, glyphs): - pass + for glyph_name, glyph_data in glyphs.items(): + data = glyph_data.get('icon5x8') + if data is not None: + self.icons[glyph_name] = data def write_glyph(self, x, y, glyph_name): + data = self.icons.get(glyph_name) + if data is not None: + slot, bits = data + self.write_text(x, y, chr(slot)) + self.glyph_framebuffer[slot * 8:(slot + 1) * 8] = bits + return 1 char = TextGlyphs.get(glyph_name) if char is not None: # Draw character @@ -112,90 +120,3 @@ class HD44780: self.text_framebuffers[1][:] = spaces def get_dimensions(self): return (20, 4) - -HD44780_chars = [ - # Extruder (a thermometer) - 0b00100, - 0b01010, - 0b01010, - 0b01010, - 0b01010, - 0b10001, - 0b10001, - 0b01110, - # Heated bed - 0b00000, - 0b11111, - 0b10101, - 0b10001, - 0b10101, - 0b11111, - 0b00000, - 0b00000, - # Feed rate - 0b11100, - 0b10000, - 0b11000, - 0b10111, - 0b00101, - 0b00110, - 0b00101, - 0b00000, - # Clock - 0b00000, - 0b01110, - 0b10011, - 0b10101, - 0b10001, - 0b01110, - 0b00000, - 0b00000, - # Degrees - 0b01100, - 0b10010, - 0b10010, - 0b01100, - 0b00000, - 0b00000, - 0b00000, - 0b00000, - # USB - 0b01110, - 0b01110, - 0b01110, - 0b11111, - 0b11111, - 0b11111, - 0b00100, - 0b00100, - # SD - 0b00000, - 0b00111, - 0b01111, - 0b11111, - 0b11111, - 0b11111, - 0b11111, - 0b00000, - # Fan - 0b00000, - 0b10011, - 0b11010, - 0b00100, - 0b01011, - 0b11001, - 0b00000, - 0b00000, -] - -TextGlyphs = { - 'right_arrow': '\x7e', - 'extruder': '\x00', - 'bed': '\x01', 'bed_heat1': '\x01', 'bed_heat2': '\x01', - 'feedrate': '\x02', - 'clock': '\x03', - 'degrees': '\x04', - 'usb': '\x05', - 'sd': '\x06', - 'fan1': '\x07', 'fan2': '\x07', -} diff --git a/klippy/extras/display/st7920.py b/klippy/extras/display/st7920.py index 30c3dfb1..e368d869 100644 --- a/klippy/extras/display/st7920.py +++ b/klippy/extras/display/st7920.py @@ -137,7 +137,9 @@ class ST7920: self.graphics_framebuffers[gfx_fb][x:x+len(data)] = data def set_glyphs(self, glyphs): for glyph_name, glyph_data in glyphs.items(): - self.icons[glyph_name] = glyph_data + data = glyph_data.get('icon16x16') + if data is not None: + self.icons[glyph_name] = data # Setup animated glyphs self.cache_glyph('fan2', 'fan1', 0) self.cache_glyph('bed_heat2', 'bed_heat1', 1) diff --git a/klippy/extras/display/uc1701.py b/klippy/extras/display/uc1701.py index 690ea0bc..8f301df2 100644 --- a/klippy/extras/display/uc1701.py +++ b/klippy/extras/display/uc1701.py @@ -81,9 +81,11 @@ class DisplayBase: pix_x += 1 def set_glyphs(self, glyphs): for glyph_name, glyph_data in glyphs.items(): - top1, bot1 = self._swizzle_bits([d >> 8 for d in glyph_data]) - top2, bot2 = self._swizzle_bits(glyph_data) - self.icons[glyph_name] = (top1 + top2, bot1 + bot2) + data = glyph_data.get('icon16x16') + if data is not None: + top1, bot1 = self._swizzle_bits([d >> 8 for d in data]) + top2, bot2 = self._swizzle_bits(data) + self.icons[glyph_name] = (top1 + top2, bot1 + bot2) def write_glyph(self, x, y, glyph_name): icon = self.icons.get(glyph_name) if icon is not None and x < 15: