pull/106/head
George Sexton 1 year ago
parent f009056300
commit 7e3e54275b

@ -17,6 +17,7 @@ import (
"periph.io/x/conn/v3"
"periph.io/x/conn/v3/display"
"periph.io/x/conn/v3/gpio"
"periph.io/x/conn/v3/gpio/gpioreg"
"periph.io/x/conn/v3/physic"
"periph.io/x/conn/v3/spi"
)
@ -155,7 +156,11 @@ func NewImpression(p spi.Port, dc gpio.PinOut, reset gpio.PinOut, busy gpio.PinI
if o.Model == IMPRESSION73 {
cSpeed = acSpeed
}
c, err := p.Connect(cSpeed, spi.Mode0, cs0Pin)
// The SPI driver has a max buffer size of 4K bytes, but our image size
// is 192K Bytes. To make the Impression 7.3 treat this as single trans-
// action, we have to take over control of the CS pin and manipulate it
// as required.
c, err := p.Connect(cSpeed, spi.Mode0|spi.NoCS, cs0Pin)
if err != nil {
return nil, fmt.Errorf("failed to connect to inky over spi: %v", err)
}
@ -186,6 +191,7 @@ func NewImpression(p spi.Port, dc gpio.PinOut, reset gpio.PinOut, busy gpio.PinI
model: o.Model,
variant: o.DisplayVariant,
pcbVariant: o.PCBVariant,
cs: gpioreg.ByName("GPIO8"),
},
saturation: 50, // Looks good enough for most of the images.
}
@ -521,11 +527,12 @@ func (d *DevImpression) updateAC(pix []uint8) error {
// TODO there has to be a better way to force the white colour to be used instead of clear...
buf := make([]byte, len(pix))
for i := range pix {
if pix[i]&0xF == 7 {
buf[i] = (pix[i] & 0xF0) + 1
buf[i] = pix[i]
if buf[i]&0xF == 7 {
buf[i] = (buf[i] & 0xF0) + 1
}
if pix[i]&0xF0 == 0x70 {
buf[i] = (pix[i] & 0xF) + 0x10
if buf[i]&0xF0 == 0x70 {
buf[i] = (buf[i] & 0xF) + 0x10
}
}
@ -558,8 +565,28 @@ func (d *DevImpression) wait(dur time.Duration) {
log.Printf("Err: %s", err)
return
}
if d.busy.Read() == gpio.High {
time.Sleep(dur)
return
}
// Wait for rising edges (Low -> High) or the timeout.
d.busy.WaitForEdge(dur)
tEnd := time.Now().Add(dur)
edgeDur := dur
for tEnd.After(time.Now()) {
// Debounce the edge
edge := d.busy.WaitForEdge(edgeDur)
if edge {
// The python driver is using 10ms debounce period
time.Sleep(10 * time.Millisecond)
l := d.busy.Read()
if l {
// It's still high. Return
return
}
// It was a bounce. Recalculate the duration to wait for the edge.
edgeDur = tEnd.Sub(time.Now())
}
}
}
// ColorModel returns the device native color model.
@ -589,7 +616,7 @@ func (d *DevImpression) Set(x, y int, c color.Color) {
// Draw updates the display with the image.
func (d *DevImpression) Draw(r image.Rectangle, src image.Image, sp image.Point) error {
if r != d.Bounds() {
return fmt.Errorf("partial updates are not supported")
return fmt.Errorf("partial updates are not supported r=%#v bounds=%#v", r, d.Bounds())
}
if src.Bounds() != d.Bounds() {

@ -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/gpio/gpioreg"
"periph.io/x/conn/v3/physic"
"periph.io/x/conn/v3/spi"
)
@ -65,6 +66,7 @@ type Dev struct {
variant uint
// PCB Variant of the panel. Represents a version string as a number (12 -> 1.2).
pcbVariant uint
cs gpio.PinOut
}
// New opens a handle to an Inky pHAT or wHAT.
@ -99,6 +101,7 @@ func New(p spi.Port, dc gpio.PinOut, reset gpio.PinOut, busy gpio.PinIn, o *Opts
model: o.Model,
variant: o.DisplayVariant,
pcbVariant: o.PCBVariant,
cs: gpioreg.ByName("GPIO8"),
}
switch o.Model {
@ -337,12 +340,14 @@ func (d *Dev) reset() (err error) {
}
func (d *Dev) sendCommand(command byte, data []byte) error {
d.cs.Out(gpio.Low)
if err := d.dc.Out(gpio.Low); err != nil {
return err
}
if err := d.c.Tx([]byte{command}, nil); err != nil {
return fmt.Errorf("failed to send command %x to inky: %v", command, err)
}
d.cs.Out(gpio.High)
if data != nil {
if err := d.sendData(data); err != nil {
return fmt.Errorf("failed to send data for command %x to inky: %v", command, err)
@ -352,9 +357,12 @@ func (d *Dev) sendCommand(command byte, data []byte) error {
}
func (d *Dev) sendData(data []byte) error {
d.cs.Out(gpio.Low)
if err := d.dc.Out(gpio.High); err != nil {
return err
}
for len(data) != 0 {
var chunk []byte
if len(data) > d.maxTxSize {
@ -366,6 +374,9 @@ func (d *Dev) sendData(data []byte) error {
return fmt.Errorf("failed to send data to inky: %v", err)
}
}
d.cs.Out(gpio.High)
return nil
}

Loading…
Cancel
Save