From fb485e862d3007554c6d8bbb9910f20d645d78b8 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Tue, 26 Nov 2019 09:34:42 -0500 Subject: [PATCH] lcd_hd44780: Add proper timing delays around gpio updates A fast micro-controller may update the gpio pins faster than the hd44780 chip can handle. Add in the appropriate delays. Signed-off-by: Kevin O'Connor --- src/lcd_hd44780.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/lcd_hd44780.c b/src/lcd_hd44780.c index 9c23814b..fe65f5cf 100644 --- a/src/lcd_hd44780.c +++ b/src/lcd_hd44780.c @@ -4,6 +4,7 @@ // // This file may be distributed under the terms of the GNU GPLv3 license. +#include "autoconf.h" // CONFIG_CLOCK_FREQ #include "basecmd.h" // oid_alloc #include "board/gpio.h" // gpio_out_write #include "board/irq.h" // irq_disable @@ -22,6 +23,23 @@ struct hd44780 { * Transmit functions ****************************************************************/ +static uint32_t +nsecs_to_ticks(uint32_t ns) +{ + return timer_from_us(ns * 1000) / 1000000; +} + +static inline void +ndelay(uint32_t nsecs) +{ + if (CONFIG_CLOCK_FREQ <= 48000000) + // Slower MCUs don't require a delay + return; + uint32_t end = timer_read_time() + nsecs_to_ticks(nsecs); + while (timer_is_before(timer_read_time(), end)) + irq_poll(); +} + // Write 4 bits to the hd44780 using the 4bit parallel interface static __always_inline void hd44780_xmit_bits(uint8_t toggle, struct gpio_out e, struct gpio_out d4 @@ -36,6 +54,7 @@ hd44780_xmit_bits(uint8_t toggle, struct gpio_out e, struct gpio_out d4 gpio_out_toggle(d6); if (toggle & 0x80) gpio_out_toggle(d7); + ndelay(80); gpio_out_toggle(e); } @@ -46,6 +65,7 @@ hd44780_xmit_byte(struct hd44780 *h, uint8_t data) struct gpio_out e = h->e, d4 = h->d4, d5 = h->d5, d6 = h->d6, d7 = h->d7; hd44780_xmit_bits(h->last ^ data, e, d4, d5, d6, d7); h->last = data << 4; + ndelay(500 - 80); hd44780_xmit_bits(data ^ h->last, e, d4, d5, d6, d7); }