waveshare2in13v2: Add constants, add missing init to example (#25)

Avoid using strconv.Itoa
fmt.Sprintf() can format numbers directly using the "%d" format
specifier.

Call Dev.Init in example code
Without initializing the hardware nothing is shown on the display.

Add constants for commands
Translate the command names from the datasheet into constant names,
similar to `epd/epd.go`. These names make it easier to understand what
the driver does.

One command, 0x37, is not documented in any of the datasheets available
(Waveshare 2.13inch e-Paper, Good Display GDEH0213B72).

Signed-off-by: Michael Hanselmann <public@hansmi.ch>
pull/28/head
hansmi 5 years ago committed by GitHub
parent 7836991f22
commit d92a4ed45d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -38,7 +38,12 @@ func Example() {
dev, err := waveshare2in13v2.NewHat(b, &waveshare2in13v2.EPD2in13v2) // Display config and size
if err != nil {
log.Fatalf("failed to initialize epd: %v", err)
log.Fatalf("Failed to initialize driver: %v", err)
}
err = dev.Init(false)
if err != nil {
log.Fatalf("Failed to initialize display: %v", err)
}
// Draw on it. Black text on a white background.
@ -73,7 +78,12 @@ func Example_other() {
dev, err := waveshare2in13v2.NewHat(b, &waveshare2in13v2.EPD2in13v2) // Display config and size
if err != nil {
log.Fatalf("failed to initialize epd: %v", err)
log.Fatalf("Failed to initialize driver: %v", err)
}
err = dev.Init(false)
if err != nil {
log.Fatalf("Failed to initialize display: %v", err)
}
var img image.Image

@ -9,7 +9,6 @@ import (
"image"
"image/color"
"image/draw"
"strconv"
"time"
"periph.io/x/conn/v3"
@ -21,6 +20,31 @@ import (
"periph.io/x/host/v3/rpi"
)
// Commands
const (
driverOutputControl byte = 0x01
gateDrivingVoltageControl byte = 0x03
sourceDrivingVoltageControl byte = 0x04
dataEntryModeSetting byte = 0x11
swReset byte = 0x12
masterActivation byte = 0x20
displayUpdateControl1 byte = 0x21
displayUpdateControl2 byte = 0x22
writeRAMBW byte = 0x24
writeRAMRed byte = 0x26
writeVcomRegister byte = 0x2C
writeLutRegister byte = 0x32
setDummyLinePeriod byte = 0x3A
setGateTime byte = 0x3B
borderWaveformControl byte = 0x3C
setRAMXAddressStartEndPosition byte = 0x44
setRAMYAddressStartEndPosition byte = 0x45
setRAMXAddressCounter byte = 0x4E
setRAMYAddressCounter byte = 0x4F
setAnalogBlockControl byte = 0x74
setDigitalBlockControl byte = 0x7E
)
// Dev defines the handler which is used to access the display.
type Dev struct {
c conn.Conn
@ -184,12 +208,12 @@ func (d *Dev) Init(partialUpdate PartialUpdate) error {
// Partital Update Mode
// VCOM Voltage
eh.sendCommand([]byte{0x2C})
eh.sendCommand([]byte{writeVcomRegister})
eh.sendData([]byte{0x26})
d.waitUntilIdle()
eh.sendCommand([]byte{0x32})
eh.sendCommand([]byte{writeLutRegister})
for i := range [70]int{} {
eh.sendData([]byte{d.opts.PartialUpdate[i]})
}
@ -197,15 +221,15 @@ func (d *Dev) Init(partialUpdate PartialUpdate) error {
eh.sendCommand([]byte{0x37})
eh.sendData([]byte{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00})
eh.sendCommand([]byte{0x22})
eh.sendCommand([]byte{displayUpdateControl2})
eh.sendData([]byte{0xC0})
eh.sendCommand([]byte{0x20})
eh.sendCommand([]byte{masterActivation})
d.waitUntilIdle()
// Border Waveform
eh.sendCommand([]byte{0x3C})
eh.sendCommand([]byte{borderWaveformControl})
eh.sendData([]byte{0x01})
} else {
@ -213,66 +237,66 @@ func (d *Dev) Init(partialUpdate PartialUpdate) error {
// Software Reset
d.waitUntilIdle()
eh.sendCommand([]byte{0x12})
eh.sendCommand([]byte{swReset})
d.waitUntilIdle()
// Set analog block control
eh.sendCommand([]byte{0x74})
eh.sendCommand([]byte{setAnalogBlockControl})
eh.sendData([]byte{0x54})
// Set digital block control
eh.sendCommand([]byte{0x7E})
eh.sendCommand([]byte{setDigitalBlockControl})
eh.sendData([]byte{0x3B})
// Driver output control
eh.sendCommand([]byte{0x01})
eh.sendCommand([]byte{driverOutputControl})
eh.sendData([]byte{0xF9, 0x00, 0x00})
// Data entry mode
eh.sendCommand([]byte{0x11})
eh.sendCommand([]byte{dataEntryModeSetting})
eh.sendData([]byte{0x01})
// Set Ram-X address start/end position
eh.sendCommand([]byte{0x44})
eh.sendCommand([]byte{setRAMXAddressStartEndPosition})
eh.sendData([]byte{0x00, 0x0F})
// Set Ram-Y address start/end position
eh.sendCommand([]byte{0x45})
eh.sendCommand([]byte{setRAMYAddressStartEndPosition})
eh.sendData([]byte{0xF9, 0x00, 0x00, 0x00}) //0xF9-->(249+1)=250
// Border Waveform
eh.sendCommand([]byte{0x3C})
eh.sendCommand([]byte{borderWaveformControl})
eh.sendData([]byte{0x03})
// VCOM Voltage
eh.sendCommand([]byte{0x2C})
eh.sendCommand([]byte{writeVcomRegister})
eh.sendData([]byte{0x55})
eh.sendCommand([]byte{0x03})
eh.sendCommand([]byte{gateDrivingVoltageControl})
eh.sendData([]byte{d.opts.FullUpdate[70]})
eh.sendCommand([]byte{0x04})
eh.sendCommand([]byte{sourceDrivingVoltageControl})
eh.sendData([]byte{d.opts.FullUpdate[71], d.opts.FullUpdate[72], d.opts.FullUpdate[73]})
// Dummy Line
eh.sendCommand([]byte{0x3A})
eh.sendCommand([]byte{setDummyLinePeriod})
eh.sendData([]byte{d.opts.FullUpdate[74]})
// Gate Time
eh.sendCommand([]byte{0x3B})
eh.sendCommand([]byte{setGateTime})
eh.sendData([]byte{d.opts.FullUpdate[75]})
eh.sendCommand([]byte{0x32})
eh.sendCommand([]byte{writeLutRegister})
for i := range [70]int{} {
eh.sendData([]byte{d.opts.FullUpdate[i]})
}
// Set RAM x address count to 0
eh.sendCommand([]byte{0x4E})
eh.sendCommand([]byte{setRAMXAddressCounter})
eh.sendData([]byte{0x00})
// Set RAM y address count to 0X127
eh.sendCommand([]byte{0x4F})
eh.sendCommand([]byte{setRAMYAddressCounter})
eh.sendData([]byte{0xF9, 0x00})
d.waitUntilIdle()
@ -289,7 +313,7 @@ func (d *Dev) Clear(color byte) error {
} else {
linewidth = d.opts.Width/8 + 1
}
if err := d.sendCommand([]byte{0x24}); err != nil {
if err := d.sendCommand([]byte{writeRAMBW}); err != nil {
return err
}
@ -324,7 +348,7 @@ func (d *Dev) Draw(dstRect image.Rectangle, src image.Image, srcPts image.Point)
if err := d.setMemoryPointer(0, y); err != nil {
return err
}
if err := d.sendCommand([]byte{0x24}); err != nil {
if err := d.sendCommand([]byte{writeRAMBW}); err != nil {
return err
}
for x := 0; x <= d.opts.Width; x++ {
@ -353,7 +377,7 @@ func (d *Dev) DrawPartial(dstRect image.Rectangle, src image.Image, srcPts image
if err := d.setMemoryPointer(0, y); err != nil {
return err
}
if err := d.sendCommand([]byte{0x24}); err != nil {
if err := d.sendCommand([]byte{writeRAMBW}); err != nil {
return err
}
for x := 0; x < d.opts.Width; x++ {
@ -375,7 +399,7 @@ func (d *Dev) DrawPartial(dstRect image.Rectangle, src image.Image, srcPts image
if err := d.setMemoryPointer(0, y); err != nil {
return err
}
if err := d.sendCommand([]byte{0x26}); err != nil {
if err := d.sendCommand([]byte{writeRAMRed}); err != nil {
return err
}
for x := 0; x < d.opts.Width; x++ {
@ -402,7 +426,7 @@ func (d *Dev) Halt() error {
// String returns a string containing configuration information.
func (d *Dev) String() string {
return fmt.Sprintf("epd.Dev{%s, %s, Height: %s, Width: %s}", d.c, d.dc, strconv.Itoa(d.opts.Height), strconv.Itoa(d.opts.Width))
return fmt.Sprintf("epd.Dev{%s, %s, Height: %d, Width: %d}", d.c, d.dc, d.opts.Height, d.opts.Width)
}
func (d *Dev) sendData(c []byte) error {
@ -430,9 +454,9 @@ func (d *Dev) sendCommand(c []byte) error {
func (d *Dev) turnOnDisplay() error {
eh := errorHandler{d: *d}
eh.sendCommand([]byte{0x22})
eh.sendCommand([]byte{displayUpdateControl2})
eh.sendData([]byte{0xC7})
eh.sendCommand([]byte{0x20})
eh.sendCommand([]byte{masterActivation})
d.waitUntilIdle()
@ -451,7 +475,6 @@ func (d *Dev) reset() error {
time.Sleep(200 * time.Millisecond)
return eh.err
}
func (d *Dev) waitUntilIdle() {
@ -463,9 +486,9 @@ func (d *Dev) waitUntilIdle() {
func (d *Dev) setMemoryPointer(x, y int) error {
eh := errorHandler{d: *d}
eh.sendCommand([]byte{0x4E})
eh.sendCommand([]byte{setRAMXAddressCounter})
eh.sendData([]byte{byte((x >> 3) & 0xFF)})
eh.sendCommand([]byte{0x4F})
eh.sendCommand([]byte{setRAMYAddressCounter})
eh.sendData([]byte{byte(y & 0xFF)})
eh.sendData([]byte{byte((y >> 8) & 0xFF)})

Loading…
Cancel
Save