diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2018-06-22 22:07:48 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2018-06-22 23:47:09 -0400 |
commit | f08a0c5e93b92a6efa72d16a3d53968f3e54bf1c (patch) | |
tree | ef562213a7898d4c0dcc95c5fb0718c4f20769d9 /src | |
parent | 74de181e59fcc6f2d8d86190e73a1382810add8b (diff) | |
download | kutter-f08a0c5e93b92a6efa72d16a3d53968f3e54bf1c.tar.gz kutter-f08a0c5e93b92a6efa72d16a3d53968f3e54bf1c.tar.xz kutter-f08a0c5e93b92a6efa72d16a3d53968f3e54bf1c.zip |
lcd_st7920: Use a longer delay at the start of each command/data
It appears the st7920 requires a longer delay when switching from
command to data mode (and vice-versa). Slower MCUs don't show a
problem because the klipper command processing time results in a
sufficient delay. However, some of the faster MCUs can process
klipper commands fast enough that the next st7920 transfer is sent too
fast. Add an additional delay to account for this.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/lcd_st7920.c | 36 |
1 files changed, 27 insertions, 9 deletions
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) |