package display import ( "image" "log" "time" "github.com/stianeikeland/go-rpio/v4" ) const ( adressWriteTimeout = 140 * time.Nanosecond dataStrobeTimeout = 250 * time.Nanosecond // (Data transfer) ) type mt12864a struct { logger *log.Logger // 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 } func newMt12864a(logger *log.Logger) (Display, error) { rpio.Open() d := mt12864a{ logger: logger, pinA0: rpio.Pin(7), pinRW: rpio.Pin(11), pinE: rpio.Pin(13), pinDB0: rpio.Pin(15), pinDB1: rpio.Pin(19), pinDB2: rpio.Pin(21), pinDB3: rpio.Pin(23), pinDB4: rpio.Pin(27), pinDB5: rpio.Pin(29), pinDB6: rpio.Pin(31), pinDB7: rpio.Pin(33), pinE1: rpio.Pin(35), pinE2: rpio.Pin(37), pinRES: rpio.Pin(40), } d.initLCD() return &d, nil } func (d *mt12864a) GetBounds() image.Rectangle { return image.Rectangle{} } func (d *mt12864a) Flush(img *image.Gray) error { return nil } func (d *mt12864a) Close() error { return rpio.Close() } func (d *mt12864a) initLCD() { // Set All to output d.pinA0.Output() d.pinRW.Output() d.pinE.Output() d.pinE1.Output() d.pinE2.Output() d.pinRES.Output() d.busOutput() d.logger.Println("sdljfsldkf") // d.pinA0.Low() // d.logger.Println("pinA0 set low") // d.pinRW.Low() // d.logger.Println("pinRW set low") // d.pinE.Low() // d.logger.Println("pinE set low") // d.pinDB0.Low() // d.logger.Println("pinDB0 set low") // d.pinDB1.Low() // d.logger.Println("pinDB1 set low") // d.pinDB2.Low() // d.logger.Println("pinDB2 set low") // d.pinDB3.Low() // d.logger.Println("pinDB3 set low") // d.pinDB4.Low() // d.logger.Println("pinDB4 set low") // d.pinDB5.Low() // d.logger.Println("pinDB5 set low") // d.pinDB6.Low() // d.logger.Println("pinDB6 set low") // d.pinDB7.Low() // d.logger.Println("pinDB7 set low") // d.pinE1.Low() // d.logger.Println("pinE1 set low") // d.pinE2.Low() // d.logger.Println("pinE2 set low") // d.pinRES.Low() // d.logger.Println("pinRES set low") // d.pinE.Low() // d.pinRES.Low() // time.Sleep(time.Microsecond) // d.pinRES.High() // time.Sleep(10 * time.Microsecond) // d.writeCodeL(0xC0) // Top line to 0 // d.writeCodeR(0xC0) // d.writeCodeL(0x3F) // Display on // d.writeCodeR(0x3F) } func (d *mt12864a) writeCodeL(c byte) { d.writeByte(c, 0, 1, 0) } func (d *mt12864a) writeCodeR(c byte) { d.writeByte(c, 0, 0, 1) } func (d *mt12864a) writeDataL(b byte) { d.writeByte(b, 1, 1, 0) } func (d *mt12864a) writeDataR(b byte) { d.writeByte(b, 1, 0, 1) } func (d *mt12864a) readDataL() byte { return d.readByte(1, 1, 0) } func (d *mt12864a) readDataR() byte { return d.readByte(1, 0, 1) } func (d *mt12864a) writeByte(b byte, cd, l, r rpio.State) { if l == rpio.High && r == rpio.High { d.logger.Println("L and R are high!!!") return } d.waitReady(l, r) d.busOutput() d.pinRW.Low() // We write d.pinA0.Write(cd) d.pinE1.Write(l) // Select cristals d.pinE2.Write(r) // Select cristals // 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 *mt12864a) readByte(cd, l, r rpio.State) byte { if l == rpio.High && r == rpio.High { d.logger.Println("L and R are high!!!") return 0 } var b byte d.waitReady(l, r) d.busOutput() d.pinRW.High() // We write d.pinA0.Write(cd) d.pinE1.Write(l) // Select cristals d.pinE2.Write(r) // Select cristals // 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 } // Wait, checking status byte func (d *mt12864a) waitReady(l, r rpio.State) { d.busInput() // Set bus to input d.pinRW.High() // We read d.pinA0.Low() // Data d.pinE1.Write(l) // Select cristals d.pinE2.Write(r) // Select cristals time.Sleep(adressWriteTimeout) // Strobe start d.pinE.High() time.Sleep(dataStrobeTimeout) // Wait status flag drop counter := 0 for d.pinDB7.Read() == rpio.High && counter < 100 { counter++ } // Strobe end d.pinE.Low() time.Sleep(time.Millisecond - dataStrobeTimeout - adressWriteTimeout) } // Set bus pins to output func (d *mt12864a) 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 *mt12864a) 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() }