waveshare213v2: Unify initialization, separate mode config

Merge the common logic in the "initDisplayFull" and "initDisplayPartial"
functions and separate out the parts related to the display update mode.
In a forthcoming change the update mode will no longer be set when
initializing, but rather via a separate setter function, requiring the
ability to reconfigure the display controller without a full
re-initialization.

Signed-off-by: Michael Hanselmann <public@hansmi.ch>
pull/42/head
Michael Hanselmann 4 years ago committed by M-A
parent 4f995754b0
commit 85bed23e58

@ -10,7 +10,7 @@ type controller interface {
waitUntilIdle() waitUntilIdle()
} }
func initDisplayFull(ctrl controller, opts *Opts) { func initDisplay(ctrl controller, opts *Opts) {
ctrl.waitUntilIdle() ctrl.waitUntilIdle()
ctrl.sendCommand(swReset) ctrl.sendCommand(swReset)
ctrl.waitUntilIdle() ctrl.waitUntilIdle()
@ -28,12 +28,6 @@ func initDisplayFull(ctrl controller, opts *Opts) {
0x00, 0x00,
}) })
ctrl.sendCommand(borderWaveformControl)
ctrl.sendData([]byte{0x03})
ctrl.sendCommand(writeVcomRegister)
ctrl.sendData([]byte{0x55})
ctrl.sendCommand(gateDrivingVoltageControl) ctrl.sendCommand(gateDrivingVoltageControl)
ctrl.sendData([]byte{gateDrivingVoltage19V}) ctrl.sendData([]byte{gateDrivingVoltage19V})
@ -45,20 +39,31 @@ func initDisplayFull(ctrl controller, opts *Opts) {
ctrl.sendCommand(setGateTime) ctrl.sendCommand(setGateTime)
ctrl.sendData([]byte{0x0A}) ctrl.sendData([]byte{0x0A})
ctrl.sendCommand(writeLutRegister)
ctrl.sendData(opts.FullUpdate[:70])
} }
func initDisplayPartial(ctrl controller, opts *Opts) { func configDisplayMode(ctrl controller, mode PartialUpdate, lut LUT) {
var vcom byte
var borderWaveformControlValue byte
switch mode {
case Full:
vcom = 0x55
borderWaveformControlValue = 0x03
case Partial:
vcom = 0x24
borderWaveformControlValue = 0x01
}
ctrl.sendCommand(writeVcomRegister) ctrl.sendCommand(writeVcomRegister)
ctrl.sendData([]byte{0x26}) ctrl.sendData([]byte{vcom})
ctrl.waitUntilIdle() ctrl.sendCommand(borderWaveformControl)
ctrl.sendData([]byte{borderWaveformControlValue})
ctrl.sendCommand(writeLutRegister) ctrl.sendCommand(writeLutRegister)
ctrl.sendData(opts.PartialUpdate[:70]) ctrl.sendData(lut[:70])
if mode == Partial {
// Undocumented command used in vendor example code. // Undocumented command used in vendor example code.
ctrl.sendCommand(0x37) ctrl.sendCommand(0x37)
ctrl.sendData([]byte{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00}) ctrl.sendData([]byte{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00})
@ -67,9 +72,7 @@ func initDisplayPartial(ctrl controller, opts *Opts) {
ctrl.sendData([]byte{0xC0}) ctrl.sendData([]byte{0xC0})
ctrl.sendCommand(masterActivation) ctrl.sendCommand(masterActivation)
}
ctrl.waitUntilIdle() ctrl.waitUntilIdle()
ctrl.sendCommand(borderWaveformControl)
ctrl.sendData([]byte{0x01})
} }

@ -5,6 +5,7 @@
package waveshare2in13v2 package waveshare2in13v2
import ( import (
"bytes"
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
@ -32,7 +33,7 @@ func (r *fakeController) sendData(data []byte) {
func (*fakeController) waitUntilIdle() { func (*fakeController) waitUntilIdle() {
} }
func TestInitDisplayFull(t *testing.T) { func TestInitDisplay(t *testing.T) {
for _, tc := range []struct { for _, tc := range []struct {
name string name string
opts Opts opts Opts
@ -49,8 +50,6 @@ func TestInitDisplayFull(t *testing.T) {
cmd: driverOutputControl, cmd: driverOutputControl,
data: []byte{250 - 1, 0, 0}, data: []byte{250 - 1, 0, 0},
}, },
{cmd: borderWaveformControl, data: []byte{0x03}},
{cmd: writeVcomRegister, data: []byte{0x55}},
{cmd: gateDrivingVoltageControl, data: []byte{gateDrivingVoltage19V}}, {cmd: gateDrivingVoltageControl, data: []byte{gateDrivingVoltage19V}},
{ {
cmd: sourceDrivingVoltageControl, cmd: sourceDrivingVoltageControl,
@ -62,48 +61,59 @@ func TestInitDisplayFull(t *testing.T) {
}, },
{cmd: setDummyLinePeriod, data: []byte{0x30}}, {cmd: setDummyLinePeriod, data: []byte{0x30}},
{cmd: setGateTime, data: []byte{0x0a}}, {cmd: setGateTime, data: []byte{0x0a}},
{cmd: writeLutRegister, data: EPD2in13v2.FullUpdate},
}, },
}, },
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
var got fakeController var got fakeController
initDisplayFull(&got, &tc.opts) initDisplay(&got, &tc.opts)
if diff := cmp.Diff([]record(got), tc.want, cmpopts.EquateEmpty(), cmp.AllowUnexported(record{})); diff != "" { if diff := cmp.Diff([]record(got), tc.want, cmpopts.EquateEmpty(), cmp.AllowUnexported(record{})); diff != "" {
t.Errorf("initDisplayFull() difference (-got +want):\n%s", diff) t.Errorf("initDisplay() difference (-got +want):\n%s", diff)
} }
}) })
} }
} }
func TestInitDisplayPartial(t *testing.T) { func TestConfigDisplayMode(t *testing.T) {
for _, tc := range []struct { for _, tc := range []struct {
name string name string
opts Opts mode PartialUpdate
lut LUT
want []record want []record
}{ }{
{ {
name: "epd2in13v2", name: "full",
opts: EPD2in13v2, mode: Full,
lut: bytes.Repeat([]byte{'F'}, 100),
want: []record{ want: []record{
{cmd: writeVcomRegister, data: []byte{0x26}}, {cmd: writeVcomRegister, data: []byte{0x55}},
{cmd: writeLutRegister, data: EPD2in13v2.PartialUpdate}, {cmd: borderWaveformControl, data: []byte{0x03}},
{cmd: writeLutRegister, data: bytes.Repeat([]byte{'F'}, 70)},
},
},
{
name: "partial",
mode: Partial,
lut: bytes.Repeat([]byte{'P'}, 70),
want: []record{
{cmd: writeVcomRegister, data: []byte{0x24}},
{cmd: borderWaveformControl, data: []byte{0x01}},
{cmd: writeLutRegister, data: bytes.Repeat([]byte{'P'}, 70)},
{cmd: 0x37, data: []byte{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00}}, {cmd: 0x37, data: []byte{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00}},
{cmd: displayUpdateControl2, data: []byte{0xc0}}, {cmd: displayUpdateControl2, data: []byte{0xc0}},
{cmd: masterActivation}, {cmd: masterActivation},
{cmd: borderWaveformControl, data: []byte{0x01}},
}, },
}, },
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
var got fakeController var got fakeController
initDisplayPartial(&got, &tc.opts) configDisplayMode(&got, tc.mode, tc.lut)
if diff := cmp.Diff([]record(got), tc.want, cmpopts.EquateEmpty(), cmp.AllowUnexported(record{})); diff != "" { if diff := cmp.Diff([]record(got), tc.want, cmpopts.EquateEmpty(), cmp.AllowUnexported(record{})); diff != "" {
t.Errorf("initDisplayPartial() difference (-got +want):\n%s", diff) t.Errorf("configDisplayMode() difference (-got +want):\n%s", diff)
} }
}) })
} }

@ -163,6 +163,18 @@ func NewHat(p spi.Port, opts *Opts) (*Dev, error) {
return New(p, dc, cs, rst, busy, opts) return New(p, dc, cs, rst, busy, opts)
} }
func (d *Dev) configMode(ctrl controller, mode PartialUpdate) {
var lut LUT
if mode == Full {
lut = d.opts.FullUpdate
} else {
lut = d.opts.PartialUpdate
}
configDisplayMode(ctrl, mode, lut)
}
// Init will initialize the display with the partial-update or full-update mode. // Init will initialize the display with the partial-update or full-update mode.
func (d *Dev) Init(partialUpdate PartialUpdate) error { func (d *Dev) Init(partialUpdate PartialUpdate) error {
// Hardware Reset // Hardware Reset
@ -172,10 +184,10 @@ func (d *Dev) Init(partialUpdate PartialUpdate) error {
eh := errorHandler{d: *d} eh := errorHandler{d: *d}
if partialUpdate { initDisplay(&eh, d.opts)
initDisplayPartial(&eh, d.opts)
} else { if eh.err == nil {
initDisplayFull(&eh, d.opts) d.configMode(&eh, partialUpdate)
} }
return eh.err return eh.err

Loading…
Cancel
Save