package mt12864a import ( "fmt" "io" "log" "time" "gitea.unprism.ru/yotia/display-test/pkg/parallel8bit" "github.com/stianeikeland/go-rpio/v4" ) type mt12864a struct { logger *log.Logger dev parallel8bit.Device pinE1 rpio.Pin pinE2 rpio.Pin pinRES rpio.Pin } type Device interface { PowerOn() error SetPixel(x, y byte, c bool) error WriteCodeL(c byte) error WriteCodeR(c byte) error WriteDataL(b byte) error WriteDataR(b byte) error ReadDataL() (byte, error) ReadDataR() (byte, error) ReadStatus(l, r rpio.State) byte io.Closer } func New(logger *log.Logger) (Device, error) { rpio.Open() d := mt12864a{ logger: logger, dev: parallel8bit.New(logger, parallel8bit.DevicePins{ PinA0: rpio.Pin(18), PinRW: rpio.Pin(17), PinE: rpio.Pin(27), PinDB0: rpio.Pin(22), PinDB1: rpio.Pin(10), PinDB2: rpio.Pin(9), // From 21 PinDB3: rpio.Pin(11), PinDB4: rpio.Pin(12), PinDB5: rpio.Pin(16), // From 32 PinDB6: rpio.Pin(20), // From 31 PinDB7: rpio.Pin(13), // From 33 }), pinE1: rpio.Pin(19), pinE2: rpio.Pin(26), pinRES: rpio.Pin(21), } d.pinE1.Output() d.pinE2.Output() d.pinRES.Output() d.dev.Reset() return &d, nil } func (d *mt12864a) Close() error { return rpio.Close() } func (d *mt12864a) SetPixel(x, y byte, c bool) error { // var c8 byte // var mask byte // Check bounds if x > 127 || y > 63 { return fmt.Errorf("positions out of bounds") } if x < 64 { // Left crystal d.WriteCodeL(0xB8 | (y >> 3)) // Set page d.WriteCodeL(0x40 | x) // Set addr // c8=ReadDataL(); // ?? ok // c8=ReadDataL(); // Read byte // m8=1<<(y&0x07);//Вычислить маску нужного бита в байте // if (c==1) //Зажигать точку? // c8|=m8//Установить нужный бит в байте // else //Или гасить точку? // c8&=~m8;//Сбросить нужный бит в байте // WriteCodeL(0x40|x);//Снова установить адрес нужного байта d.WriteDataL(0x34) // Write byte } return nil } func (d *mt12864a) PowerOn() error { d.logger.Println(d.ReadStatus(1, 0)) // Should be 0 d.logger.Println("Reset") 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.logger.Println("Top line to 0") d.WriteCodeL(0xC0) // Top line to 0 d.WriteCodeR(0xC0) // Top line to 0 d.logger.Println("Display on") d.WriteCodeL(0x3F) // Display on d.WriteCodeR(0x3F) // Display on // 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 } // Write codes func (d *mt12864a) WriteCodeL(c byte) error { return d.writeByte(c, 0, 1, 0) } func (d *mt12864a) WriteCodeR(c byte) error { return d.writeByte(c, 0, 0, 1) } // Write data as byte func (d *mt12864a) WriteDataL(b byte) error { return d.writeByte(b, 1, 1, 0) } func (d *mt12864a) WriteDataR(b byte) error { return d.writeByte(b, 1, 0, 1) } // Read data func (d *mt12864a) ReadDataL() (byte, error) { return d.readByte(1, 1, 0) } func (d *mt12864a) ReadDataR() (byte, error) { return d.readByte(1, 0, 1) } // Low level functions func (d *mt12864a) writeByte(b byte, cd, l, r rpio.State) error { // 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") } if err := d.waitReady(l, r); err != nil { return fmt.Errorf("wait ready: %w", err) } d.pinE1.Write(l) // Select cristals d.pinE2.Write(r) // Select cristals d.dev.WriteByte(b, cd) return nil } func (d *mt12864a) readByte(cd, l, r rpio.State) (byte, error) { if l == rpio.High && r == rpio.High { d.logger.Println("L and R are high!!!") return 0, fmt.Errorf("cannot ready left and right at the same time") } // Setup if err := d.waitReady(l, r); err != nil { return 0, fmt.Errorf("wait ready: %w", err) } d.pinE1.Write(l) // Select cristals d.pinE2.Write(r) // Select cristals return d.dev.ReadByte(cd), nil } // Wait, checking status byte func (d *mt12864a) waitReady(l, r rpio.State) error { d.pinE1.Write(l) // Select cristals d.pinE2.Write(r) // Select cristals return d.dev.WaitReady() } func (d *mt12864a) ReadStatus(l, r rpio.State) byte { d.pinE1.Write(l) // Select cristals d.pinE2.Write(r) // Select cristals return d.dev.ReadByte(1) }