From efb2447c84d395e355b2617c581510e2b17ff74d Mon Sep 17 00:00:00 2001 From: Andrey Egorov Date: Mon, 2 Sep 2024 13:11:36 +0300 Subject: [PATCH] Add: separated Parallel 8 bit lib --- display/mt-12864a.go | 37 ++++--- pkg/mt12864a/mt12864a.go | 53 +++++----- pkg/parallel8bit/parallel8bit.go | 160 +++++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+), 43 deletions(-) create mode 100644 pkg/parallel8bit/parallel8bit.go diff --git a/display/mt-12864a.go b/display/mt-12864a.go index e9d7e13..7ecd853 100644 --- a/display/mt-12864a.go +++ b/display/mt-12864a.go @@ -32,7 +32,9 @@ func newMt12864a(logger *log.Logger) (Display, error) { } // Temp debug draw + d.logger.Println("Draw...") d.test() + d.logger.Println("Draw finished") return &d, nil } @@ -105,19 +107,30 @@ func (d *displayMt12864a) test() { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF, }, } + _ = Logo128 - for p := byte(0); p < 8; p++ { - d.dev.WriteCodeL(p | 0xB8) - d.dev.WriteCodeL(0x40) - for c := 0; c < 64; c++ { - d.dev.WriteDataL(Logo128[p][c]) - } - d.dev.WriteCodeR(p | 0xB8) - d.dev.WriteCodeR(0x40) - for c := 64; c < 128; c++ { - d.dev.WriteDataR(Logo128[p][c]) - } - } + d.logger.Println("Write") + d.dev.WriteCodeL(0xB8) + d.dev.WriteCodeL(0x40) + d.dev.WriteDataL(47) + d.logger.Println("Read") + // d.dev.WriteCodeL(0xB8) + d.dev.WriteCodeL(0x40) + d.logger.Println(d.dev.ReadDataL()) + d.logger.Println(d.dev.ReadDataL()) + + // for p := byte(0); p < 8; p++ { + // d.dev.WriteCodeL(p | 0xB8) + // d.dev.WriteCodeL(0x40) + // for c := 0; c < 64; c++ { + // d.dev.WriteDataL(Logo128[p][c]) + // } + // d.dev.WriteCodeR(p | 0xB8) + // d.dev.WriteCodeR(0x40) + // for c := 64; c < 128; c++ { + // d.dev.WriteDataR(Logo128[p][c]) + // } + // } } func (d *displayMt12864a) GetBounds() image.Rectangle { diff --git a/pkg/mt12864a/mt12864a.go b/pkg/mt12864a/mt12864a.go index 034126f..78c762b 100644 --- a/pkg/mt12864a/mt12864a.go +++ b/pkg/mt12864a/mt12864a.go @@ -119,38 +119,37 @@ func (d *mt12864a) SetPixel(x, y byte, c bool) error { } func (d *mt12864a) PowerOn() error { - d.pinA0.Low() - d.pinRW.Low() - d.pinE.Low() - d.pinDB0.Low() - d.pinDB1.Low() - d.pinDB2.Low() - d.pinDB3.Low() - d.pinDB4.Low() - d.pinDB5.Low() - d.pinDB6.Low() - d.pinDB7.Low() - d.pinE1.Low() - d.pinE2.Low() - d.pinRES.Low() - d.logger.Println("All low ") - d.PrintPins() - d.logger.Println("Power on") + d.logger.Println(d.ReadStatus(1, 0)) // Should be 0 + d.logger.Println("Reset") d.pinE.Low() d.pinRES.Low() time.Sleep(time.Microsecond) + d.logger.Println(d.ReadStatus(1, 0)) // Should be 48 (power off and reset) d.pinRES.High() time.Sleep(10 * time.Microsecond) + d.logger.Println(d.ReadStatus(1, 0)) // Should be 32 (power off) + // Module is reset and should be turned off + if d.ReadStatus(1, 0) == 0 || d.ReadStatus(0, 1) == 0 { + return fmt.Errorf("no response from display(or it is possible that it is turned on but...)") + } + + d.logger.Println("Power on") d.PrintPins() d.logger.Println("Top line to 0") d.WriteCodeL(0xC0) // Top line to 0 d.WriteCodeR(0xC0) // Top line to 0 - d.PrintPins() d.logger.Println("Display on") d.WriteCodeL(0x3F) // Display on d.WriteCodeR(0x3F) // Display on - d.PrintPins() + + // Check that crystals are turned on + if (d.ReadStatus(1, 0) & (1 << 5)) != 0 { + return fmt.Errorf("Left cristal is still off") + } + if (d.ReadStatus(0, 1) & (1 << 5)) != 0 { + return fmt.Errorf("Right cristal is still off") + } return nil } @@ -188,7 +187,7 @@ func (d *mt12864a) ReadDataR() (byte, error) { // Low level functions func (d *mt12864a) writeByte(b byte, cd, l, r rpio.State) error { - d.logger.Println("Write byte", b, cd, l, r) + // d.logger.Println("Write byte", b, cd, l, r) if l == rpio.High && r == rpio.High { d.logger.Println("L and R are high!!!") return fmt.Errorf("cannot write left and right at the same times") @@ -218,14 +217,6 @@ func (d *mt12864a) writeByte(b byte, cd, l, r rpio.State) error { // Strobe end d.pinE.Low() - d.pinDB0.Low() - d.pinDB1.Low() - d.pinDB2.Low() - d.pinDB3.Low() - d.pinDB4.Low() - d.pinDB5.Low() - d.pinDB6.Low() - d.pinDB7.Low() time.Sleep(time.Millisecond - dataStrobeTimeout - adressWriteTimeout) return nil } @@ -269,7 +260,7 @@ func (d *mt12864a) readByte(cd, l, r rpio.State) (byte, error) { // Wait, checking status byte func (d *mt12864a) waitReady(l, r rpio.State) error { - d.logger.Println("Wait ready", l, r) + //d.logger.Println("Wait ready", l, r) d.busInput() // Set bus to input d.pinRW.High() // We read d.pinA0.Low() // Status @@ -286,7 +277,7 @@ func (d *mt12864a) waitReady(l, r rpio.State) error { d.busInput() // Set bus to input for counter := 0; counter < maxWaitCycles; counter++ { if d.pinDB7.Read() != rpio.High { - d.logger.Printf("BUS:%d%d%d%d%d%d%d%d\n", d.pinDB0.Read(), d.pinDB1.Read(), d.pinDB2.Read(), d.pinDB3.Read(), d.pinDB4.Read(), d.pinDB5.Read(), d.pinDB6.Read(), d.pinDB7.Read()) + //d.logger.Printf("BUS:%d%d%d%d%d%d%d%d\n", d.pinDB0.Read(), d.pinDB1.Read(), d.pinDB2.Read(), d.pinDB3.Read(), d.pinDB4.Read(), d.pinDB5.Read(), d.pinDB6.Read(), d.pinDB7.Read()) ok = true break } @@ -298,7 +289,7 @@ func (d *mt12864a) waitReady(l, r rpio.State) error { // Strobe end d.pinE.Low() time.Sleep(time.Millisecond - dataStrobeTimeout - adressWriteTimeout) - d.logger.Println("Ready") + // d.logger.Println("Ready") return nil } diff --git a/pkg/parallel8bit/parallel8bit.go b/pkg/parallel8bit/parallel8bit.go new file mode 100644 index 0000000..981d0c0 --- /dev/null +++ b/pkg/parallel8bit/parallel8bit.go @@ -0,0 +1,160 @@ +package parallel8bit + +import ( + "fmt" + "log" + "time" + + "github.com/stianeikeland/go-rpio/v4" +) + +const ( + adressWriteTimeout = 140 * time.Nanosecond + dataStrobeTimeout = 250 * time.Nanosecond // (Data transfer) + maxWaitCycles = 100 +) + +// Interface for MT displays (do not set cristals bits) +type Device interface { + WriteByte(b byte, cd rpio.State) + ReadByte(cd rpio.State) byte + + WaitReady() error +} + +type DevicePins struct { + // GPIO pins + PinA0 rpio.Pin + PinRW rpio.Pin + PinE rpio.Pin + PinDB0 rpio.Pin + PinDB1 rpio.Pin + PinDB2 rpio.Pin + PinDB3 rpio.Pin + PinDB4 rpio.Pin + PinDB5 rpio.Pin + PinDB6 rpio.Pin + PinDB7 rpio.Pin + PinE1 rpio.Pin + PinE2 rpio.Pin + PinRES rpio.Pin +} + +type device struct { + logger *log.Logger + + DevicePins +} + +func New(logger *log.Logger, pins DevicePins) Device { + return &device{ + logger: logger, + DevicePins: pins, + } +} + +func (d *device) WriteByte(b byte, cd rpio.State) { + // d.logger.Println("Write byte", b, cd, l, r) + d.busOutput() + d.PinRW.Low() // We write + d.PinA0.Write(cd) + + // Write bus + d.PinDB0.Write(rpio.State((b >> 0) & 1)) + d.PinDB1.Write(rpio.State((b >> 1) & 1)) + d.PinDB2.Write(rpio.State((b >> 2) & 1)) + d.PinDB3.Write(rpio.State((b >> 3) & 1)) + d.PinDB4.Write(rpio.State((b >> 4) & 1)) + d.PinDB5.Write(rpio.State((b >> 5) & 1)) + d.PinDB6.Write(rpio.State((b >> 6) & 1)) + d.PinDB7.Write(rpio.State((b >> 7) & 1)) + + // Strobe start + d.PinE.High() + time.Sleep(dataStrobeTimeout) + + // Strobe end + d.PinE.Low() + time.Sleep(time.Millisecond - dataStrobeTimeout - adressWriteTimeout) +} + +func (d *device) ReadByte(cd rpio.State) byte { + // Setup + var b byte + d.busOutput() + d.PinRW.High() // We write + d.PinA0.Write(cd) + + // Strobe start + d.PinE.High() + time.Sleep(dataStrobeTimeout) + + // Read + b = uint8(d.PinDB0.Read()) | + (uint8(d.PinDB1.Read()) << 1) | + (uint8(d.PinDB2.Read()) << 2) | + (uint8(d.PinDB3.Read()) << 3) | + (uint8(d.PinDB4.Read()) << 4) | + (uint8(d.PinDB5.Read()) << 5) | + (uint8(d.PinDB6.Read()) << 6) | + (uint8(d.PinDB7.Read()) << 7) + + // Strobe end + d.PinE.Low() + time.Sleep(time.Millisecond - dataStrobeTimeout - adressWriteTimeout) + return b +} + +func (d *device) WaitReady() error { + d.busInput() // Set bus to input + d.PinRW.High() // We read + d.PinA0.Low() // Status + time.Sleep(adressWriteTimeout) + + // Strobe start + d.PinE.High() + time.Sleep(dataStrobeTimeout) + + // Wait status flag drop + ok := false + d.busInput() // Set bus to input + for counter := 0; counter < maxWaitCycles; counter++ { + if d.PinDB7.Read() != rpio.High { + //d.logger.Printf("BUS:%d%d%d%d%d%d%d%d\n", d.pinDB0.Read(), d.pinDB1.Read(), d.pinDB2.Read(), d.pinDB3.Read(), d.pinDB4.Read(), d.pinDB5.Read(), d.pinDB6.Read(), d.pinDB7.Read()) + ok = true + break + } + } + if !ok { + return fmt.Errorf("busy timeout") + } + + // Strobe end + d.PinE.Low() + time.Sleep(time.Millisecond - dataStrobeTimeout - adressWriteTimeout) + // d.logger.Println("Ready") + return nil +} + +// Set bus pins to output +func (d *device) busOutput() { + d.PinDB0.Output() + d.PinDB1.Output() + d.PinDB2.Output() + d.PinDB3.Output() + d.PinDB4.Output() + d.PinDB5.Output() + d.PinDB6.Output() + d.PinDB7.Output() +} + +func (d *device) busInput() { + d.PinDB0.Input() + d.PinDB1.Input() + d.PinDB2.Input() + d.PinDB3.Input() + d.PinDB4.Input() + d.PinDB5.Input() + d.PinDB6.Input() + d.PinDB7.Input() +}