diff --git a/inky/doc.go b/inky/doc.go index 4b5d6d9..ac841c4 100644 --- a/inky/doc.go +++ b/inky/doc.go @@ -2,7 +2,7 @@ // Use of this source code is governed under the Apache License, Version 2.0 // that can be found in the LICENSE file. -// Package inky drives an Inky pHAT or wHAT E ink display. +// Package inky drives an Inky pHAT, pHAT v2 or wHAT E ink display. // // Datasheet // diff --git a/inky/inky.go b/inky/inky.go index f18c129..729ee26 100644 --- a/inky/inky.go +++ b/inky/inky.go @@ -14,6 +14,7 @@ import ( "periph.io/x/conn/v3" "periph.io/x/conn/v3/display" "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/i2c" "periph.io/x/conn/v3/physic" "periph.io/x/conn/v3/spi" ) @@ -69,12 +70,15 @@ type Model int const ( PHAT Model = iota WHAT + PHAT2 ) func (m *Model) String() string { switch *m { case PHAT: return "PHAT" + case PHAT2: + return "PHAT2" case WHAT: return "WHAT" default: @@ -87,6 +91,8 @@ func (m *Model) Set(s string) error { switch s { case "PHAT": *m = PHAT + case "PHAT2": + *m = PHAT2 case "WHAT": *m = WHAT default: @@ -106,6 +112,44 @@ type Opts struct { BorderColor Color } +// DetectOpts tries to read the device opts from EEPROM. +func DetectOpts(bus i2c.Bus) (*Opts, error) { + // Read data from EEPROM + data, err := readEep(bus) + if err != nil { + return nil, fmt.Errorf("failed to detect Inky board: %v", err) + } + + options := new(Opts) + + switch data[6] { + case 1, 4, 5: + options.Model = PHAT + case 10, 11, 12: + options.Model = PHAT2 + case 2, 3, 6, 7, 8: + options.Model = WHAT + default: + return nil, fmt.Errorf("failed to get ops: display type not supported") + } + + switch data[4] { + case 1: + options.ModelColor = Black + options.BorderColor = Black + case 2: + options.ModelColor = Red + options.BorderColor = Red + case 3: + options.ModelColor = Yellow + options.BorderColor = Yellow + default: + return nil, fmt.Errorf("failed to get ops: color not supported") + } + + return options, nil +} + var borderColor = map[Color]byte{ Black: 0x00, Red: 0x73, @@ -148,6 +192,9 @@ func New(p spi.Port, dc gpio.PinOut, reset gpio.PinOut, busy gpio.PinIn, o *Opts case PHAT: d.bounds = image.Rect(0, 0, 104, 212) d.flipVertically = true + case PHAT2: + d.bounds = image.Rect(0, 0, 122, 250) + d.flipVertically = true case WHAT: d.bounds = image.Rect(0, 0, 400, 300) } @@ -420,5 +467,18 @@ func pack(bits []bool) ([]byte, error) { return ret, nil } +func readEep(bus i2c.Bus) ([]byte, error) { + // Inky uses SMBus, specify read registry with data + write := []byte{0x00, 0x00} + + data := make([]byte, 29) + + if err := bus.Tx(0x50, write, data); err != nil { + return nil, err + } + + return data, nil +} + var _ display.Drawer = &Dev{} var _ conn.Resource = &Dev{}