diff --git a/config/example-extras.cfg b/config/example-extras.cfg index 1398f992..81231f75 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -539,10 +539,6 @@ #sid_pin: # The pins connected to an st7920 type lcd. These parameters must be # provided when using an st7920 display. -#chip_delay: -# This parameter specifies the internal command delay (in seconds) -# on st7920 displays. It may be necessary to increase this if the -# display shows garbled data. The default is 0.000020. # Custom thermistors (one may define any number of sections with a diff --git a/config/generic-re-arm.cfg b/config/generic-re-arm.cfg index 4a9c9fab..13a2c792 100644 --- a/config/generic-re-arm.cfg +++ b/config/generic-re-arm.cfg @@ -93,8 +93,3 @@ max_z_accel: 100 #cs_pin: P0.16 #sclk_pin: P0.15 #sid_pin: P0.18 -#chip_delay needs to be set to the below for the LCD to initialise correctly. -#chip_delay: .000040 - - - diff --git a/klippy/extras/display.py b/klippy/extras/display.py index e68c3db7..00a4777d 100644 --- a/klippy/extras/display.py +++ b/klippy/extras/display.py @@ -161,7 +161,9 @@ HD44780_chars = [ # ST7920 (128x64 graphics) lcd chip ###################################################################### -ST7920_DELAY = .000020 # Spec says 72us, but faster is possible in practice +# Spec says 72us, but faster is possible in practice +ST7920_CMD_DELAY = .000020 +ST7920_SYNC_DELAY = .000045 class ST7920: char_right_arrow = '\x1a' @@ -182,7 +184,6 @@ class ST7920: self.mcu = mcu self.oid = self.mcu.create_oid() self.mcu.add_config_object(self) - self.chip_delay = config.getfloat('chip_delay', ST7920_DELAY, minval=0.) self.send_data_cmd = self.send_cmds_cmd = None self.is_extended = False # framebuffers @@ -195,9 +196,10 @@ class ST7920: def build_config(self): self.mcu.add_config_cmd( "config_st7920 oid=%u cs_pin=%s sclk_pin=%s sid_pin=%s" - " delay_ticks=%d" % ( + " sync_delay_ticks=%d cmd_delay_ticks=%d" % ( self.oid, self.pins[0], self.pins[1], self.pins[2], - self.mcu.seconds_to_clock(self.chip_delay))) + self.mcu.seconds_to_clock(ST7920_SYNC_DELAY), + self.mcu.seconds_to_clock(ST7920_CMD_DELAY))) cmd_queue = self.mcu.alloc_command_queue() self.send_cmds_cmd = self.mcu.lookup_command( "st7920_send_cmds oid=%c cmds=%*s", cq=cmd_queue) diff --git a/src/lcd_st7920.c b/src/lcd_st7920.c index 4351d6ac..8cd76c50 100644 --- a/src/lcd_st7920.c +++ b/src/lcd_st7920.c @@ -12,7 +12,7 @@ #include "sched.h" // DECL_SHUTDOWN struct st7920 { - uint32_t last_cmd_time, cmd_wait_ticks; + uint32_t last_cmd_time, sync_wait_ticks, cmd_wait_ticks; struct gpio_out sclk, sid; }; @@ -45,16 +45,31 @@ st7920_xmit_byte(struct st7920 *s, uint8_t data) static void st7920_xmit(struct st7920 *s, uint8_t count, uint8_t *cmds) { - uint32_t last_cmd_time=s->last_cmd_time, cmd_wait_ticks=s->cmd_wait_ticks; - while (count--) { + if (!count) + return; + + // Send first byte (with longer delay) + uint32_t last_cmd_time = s->last_cmd_time, wait_ticks = s->sync_wait_ticks; + uint8_t cmd = *cmds++; + st7920_xmit_byte(s, cmd & 0xf0); + while (timer_read_time() - last_cmd_time < wait_ticks) + // Can't complete transfer until delay complete + irq_poll(); + st7920_xmit_byte(s, cmd << 4); + last_cmd_time = timer_read_time(); + + // Send subsequent bytes + wait_ticks = s->cmd_wait_ticks; + while (--count) { uint8_t cmd = *cmds++; st7920_xmit_byte(s, cmd & 0xf0); - // Can't complete transfer until delay complete - while (timer_read_time() - last_cmd_time < cmd_wait_ticks) + while (timer_read_time() - last_cmd_time < wait_ticks) + // Can't complete transfer until delay complete irq_poll(); st7920_xmit_byte(s, cmd << 4); last_cmd_time = timer_read_time(); } + s->last_cmd_time = last_cmd_time; } @@ -80,13 +95,16 @@ command_config_st7920(uint32_t *args) uint32_t end = timer_read_time(); irq_enable(); s->last_cmd_time = end; - uint32_t diff = end - start, delay_ticks = args[4]; - if (delay_ticks > diff) - s->cmd_wait_ticks = delay_ticks - diff; + uint32_t diff = end - start, sync_delay_ticks = args[4]; + if (sync_delay_ticks > diff) + s->sync_wait_ticks = sync_delay_ticks - diff; + uint32_t cmd_delay_ticks = args[5]; + if (cmd_delay_ticks > diff) + s->cmd_wait_ticks = cmd_delay_ticks - diff; } DECL_COMMAND(command_config_st7920, "config_st7920 oid=%c cs_pin=%u sclk_pin=%u sid_pin=%u" - " delay_ticks=%u"); + " sync_delay_ticks=%u cmd_delay_ticks=%u"); void command_st7920_send_cmds(uint32_t *args)