display: Make hd44780 glyphs configurable
Allow the 20x4 hd44780 screen glyphs to be customizable from the config file. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
1a7e4e51b3
commit
7713986ae1
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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',
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue