From e2affe7248ae7b4c251ac03279cc7326bfd8356f Mon Sep 17 00:00:00 2001 From: Sorin Fetche Date: Thu, 25 Jan 2024 23:03:32 -0800 Subject: [PATCH] hd44780: configure and write fixes - Write only the high-part of the byte when configuring in 4-bit mode similar to the LiquidCrystal library around [here](https://github.com/arduino-libraries/LiquidCrystal/blob/1.0.7/src/LiquidCrystal.cpp#L116) - Pulse enable after writing data similar to the LiquidCrystal library: [4-bits here](https://github.com/arduino-libraries/LiquidCrystal/blob/1.0.7/src/LiquidCrystal.cpp#L312), [8-bits here](https://github.com/arduino-libraries/LiquidCrystal/blob/1.0.7/src/LiquidCrystal.cpp#L320) Addresses issue [#646](https://github.com/tinygo-org/drivers/issues/646). --- hd44780/gpio.go | 43 +++++++++++++++++++++++++++++++++---------- hd44780/hd44780.go | 9 ++++----- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/hd44780/gpio.go b/hd44780/gpio.go index 71376fcf0..83c8ed20f 100644 --- a/hd44780/gpio.go +++ b/hd44780/gpio.go @@ -2,17 +2,26 @@ package hd44780 import ( "errors" + "time" "machine" ) +type WriteByteType int + +const ( + FullByte WriteByteType = 3 + HighNibble WriteByteType = 2 + LowNibble WriteByteType = 1 +) + type GPIO struct { dataPins []machine.Pin en machine.Pin rw machine.Pin rs machine.Pin - write func(data byte) + write func(data byte, wt WriteByteType) read func() byte } @@ -48,6 +57,10 @@ func newGPIO(dataPins []machine.Pin, en, rs, rw machine.Pin, mode byte) Device { } } +func (g *GPIO) WriteHighNibble(data byte) { + g.write(data, HighNibble) +} + // SetCommandMode sets command/instruction mode func (g *GPIO) SetCommandMode(set bool) { if set { @@ -68,26 +81,36 @@ func (g *GPIO) Write(data []byte) (n int, err error) { g.rw.Low() } for _, d := range data { - g.write(d) + g.write(d, FullByte) n++ } return n, nil } -func (g *GPIO) write8BitMode(data byte) { - g.en.High() +func (g *GPIO) write8BitMode(data byte, _ WriteByteType) { g.setPins(data) - g.en.Low() + g.pulseEnable() } -func (g *GPIO) write4BitMode(data byte) { - g.en.High() - g.setPins(data >> 4) - g.en.Low() +func (g *GPIO) write4BitMode(data byte, wt WriteByteType) { + if wt&HighNibble != 0 { + g.setPins(data >> 4) + g.pulseEnable() + } + if wt&LowNibble != 0 { + g.setPins(data) + g.pulseEnable() + } +} + +func (g *GPIO) pulseEnable() { + g.en.Low() + time.Sleep(time.Microsecond) g.en.High() - g.setPins(data) + time.Sleep(time.Microsecond) g.en.Low() + time.Sleep(100 * time.Microsecond) } // Read reads len(data) bytes from display RAM to data starting from RAM address counter position diff --git a/hd44780/hd44780.go b/hd44780/hd44780.go index 111f70d43..d560679bb 100644 --- a/hd44780/hd44780.go +++ b/hd44780/hd44780.go @@ -25,6 +25,7 @@ const ( type Buser interface { io.ReadWriter + WriteHighNibble(data byte) SetCommandMode(set bool) WriteOnly() bool } @@ -115,19 +116,17 @@ func (d *Device) Configure(cfg Config) error { time.Sleep(15 * time.Millisecond) d.bus.SetCommandMode(true) - d.bus.Write([]byte{DATA_LENGTH_8BIT}) + d.bus.WriteHighNibble(DATA_LENGTH_8BIT) time.Sleep(5 * time.Millisecond) for i := 0; i < 2; i++ { - d.bus.Write([]byte{DATA_LENGTH_8BIT}) + d.bus.WriteHighNibble(DATA_LENGTH_8BIT) time.Sleep(150 * time.Microsecond) - } if d.datalength == DATA_LENGTH_4BIT { - d.bus.Write([]byte{DATA_LENGTH_4BIT}) + d.bus.WriteHighNibble(DATA_LENGTH_4BIT) } - // Busy flag is now accessible d.SendCommand(memoryMap | cfg.Font | d.datalength) d.SendCommand(DISPLAY_OFF)