Skip to content

Commit 81f901f

Browse files
committed
Basic driver for Waveshare 7.5" e-ink
1 parent 6e04dec commit 81f901f

File tree

4 files changed

+292
-0
lines changed

4 files changed

+292
-0
lines changed

epd7in5v2/epd7in5v2.go

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
package epd7in5v2
2+
3+
import (
4+
"machine"
5+
"time"
6+
)
7+
8+
// Waveshare 7.5 inch e-ink display v2
9+
// https://www.waveshare.com/product/displays/e-paper/epaper-1/7.5inch-e-paper-hat.htm
10+
//
11+
// Currently only supporting 2 color display, and full display updates.
12+
//
13+
// https://files.waveshare.com/upload/6/60/7.5inch_e-Paper_V2_Specification.pdf
14+
// https://github.com/waveshareteam/e-Paper/tree/4822c075f5df714f88b02e10c336b4eeff7e603e/Arduino/epd7in5_V2
15+
16+
const WIDTH int = 800
17+
const HEIGHT int = 480
18+
const BYTE_WIDTH int = WIDTH / 8
19+
20+
type EPD7in5_V2 struct {
21+
cs machine.Pin
22+
rst machine.Pin
23+
dc machine.Pin
24+
bsy machine.Pin
25+
pwr machine.Pin
26+
bus machine.SPI
27+
}
28+
29+
func New(cs, rst, dc, bsy, pwr machine.Pin, bus machine.SPI) *EPD7in5_V2 {
30+
return &EPD7in5_V2{
31+
cs: cs,
32+
rst: rst,
33+
dc: dc,
34+
bsy: bsy,
35+
pwr: pwr,
36+
bus: bus,
37+
}
38+
}
39+
40+
func (e *EPD7in5_V2) Configure(sck, sdo machine.Pin) error {
41+
e.bsy.Configure(machine.PinConfig{Mode: machine.PinInput})
42+
e.cs.Configure(machine.PinConfig{Mode: machine.PinOutput})
43+
e.rst.Configure(machine.PinConfig{Mode: machine.PinOutput})
44+
e.dc.Configure(machine.PinConfig{Mode: machine.PinOutput})
45+
e.pwr.Configure(machine.PinConfig{Mode: machine.PinOutput})
46+
e.pwr.High()
47+
48+
return e.bus.Configure(machine.SPIConfig{
49+
Frequency: 2_000_000,
50+
SCK: sck,
51+
SDO: sdo,
52+
LSBFirst: false,
53+
Mode: 0,
54+
})
55+
}
56+
57+
func (e *EPD7in5_V2) Command(cmd byte, data []byte) error {
58+
e.dc.Low()
59+
e.cs.Low()
60+
_, err := e.bus.Transfer(cmd)
61+
e.cs.High()
62+
63+
if err != nil || data == nil {
64+
return err
65+
}
66+
67+
return e.Data(data)
68+
}
69+
70+
func (e *EPD7in5_V2) Data(data []byte) error {
71+
e.dc.High()
72+
e.cs.Low()
73+
err := e.bus.Tx(data, []byte{})
74+
e.cs.High()
75+
return err
76+
}
77+
78+
func (e *EPD7in5_V2) waitUntilIdle() error {
79+
var err error
80+
for {
81+
if err = e.Command(0x71, nil); err != nil {
82+
return err
83+
}
84+
if e.bsy.Get() {
85+
break
86+
}
87+
time.Sleep(10 * time.Millisecond)
88+
}
89+
time.Sleep(20 * time.Millisecond)
90+
return nil
91+
}
92+
93+
func (e *EPD7in5_V2) Reset() {
94+
e.rst.High()
95+
time.Sleep(20 * time.Millisecond)
96+
e.rst.Low()
97+
time.Sleep(20 * time.Millisecond)
98+
e.rst.High()
99+
time.Sleep(20 * time.Millisecond)
100+
}
101+
102+
func (e *EPD7in5_V2) Init() error {
103+
var err error
104+
105+
// power setting
106+
if err = e.Command(0x01, []byte{0x17, 0x17, 0x3F, 0x3F, 0x11}); err != nil {
107+
return err
108+
}
109+
110+
// VCOM DC setting
111+
if err = e.Command(0x82, []byte{0x24}); err != nil {
112+
return err
113+
}
114+
115+
// booster setting
116+
if err = e.Command(0x06, []byte{0x27, 0x27, 0x2F, 0x17}); err != nil {
117+
return err
118+
}
119+
120+
// OSC setting
121+
if err = e.Command(0x30, []byte{0x06}); err != nil {
122+
return err
123+
}
124+
125+
// power on
126+
if err = e.Command(0x04, nil); err != nil {
127+
return err
128+
}
129+
time.Sleep(100 * time.Millisecond)
130+
if err = e.waitUntilIdle(); err != nil {
131+
return err
132+
}
133+
134+
// panel setting
135+
if err = e.Command(0x00, []byte{0x3F}); err != nil {
136+
return err
137+
}
138+
139+
// resolution setting
140+
if err = e.Command(0x61, []byte{0x03, 0x20, 0x01, 0xE0}); err != nil {
141+
return err
142+
}
143+
144+
// dual SPI mode (off)
145+
if err = e.Command(0x15, []byte{0x00}); err != nil {
146+
return err
147+
}
148+
149+
// VCOM and data interval
150+
if err = e.Command(0x50, []byte{0x10, 0x00}); err != nil {
151+
return err
152+
}
153+
154+
// tcon setting
155+
if err = e.Command(0x60, []byte{0x22}); err != nil {
156+
return err
157+
}
158+
159+
// Gate/Source Start Setting
160+
if err = e.Command(0x65, []byte{0x00, 0x00, 0x00, 0x00}); err != nil {
161+
return err
162+
}
163+
164+
// Set LUT
165+
if err = e.Command(0x20, []byte{
166+
0x00, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x01, 0x0F, 0x01, 0x02, 0x00, 0x0F,
167+
0x0F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169+
}); err != nil {
170+
return err
171+
}
172+
173+
if err = e.Command(0x21, []byte{
174+
0x10, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x84, 0x0F, 0x01, 0x0F, 0x01, 0x02, 0x20, 0x0F,
175+
0x0F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177+
}); err != nil {
178+
return err
179+
}
180+
181+
if err = e.Command(0x22, []byte{
182+
0x10, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x84, 0x0F, 0x01, 0x0F, 0x01, 0x02, 0x20, 0x0F,
183+
0x0F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185+
}); err != nil {
186+
return err
187+
}
188+
189+
if err = e.Command(0x23, []byte{
190+
0x80, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x84, 0x0F, 0x01, 0x0F, 0x01, 0x02, 0x40, 0x0F,
191+
0x0F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193+
}); err != nil {
194+
return err
195+
}
196+
197+
return e.Command(0x24, []byte{
198+
0x80, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x84, 0x0F, 0x01, 0x0F, 0x01, 0x02, 0x40, 0x0F,
199+
0x0F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201+
})
202+
}
203+
204+
func (e *EPD7in5_V2) Draw(img []byte) error {
205+
var err error
206+
if err = e.Command(0x13, img); err != nil {
207+
return err
208+
}
209+
if err = e.Command(0x12, nil); err != nil {
210+
return err
211+
}
212+
time.Sleep(100 * time.Millisecond)
213+
return e.waitUntilIdle()
214+
}
215+
216+
func (e *EPD7in5_V2) Clear() error {
217+
return e.Draw(make([]byte, BYTE_WIDTH*HEIGHT))
218+
}
219+
220+
func (e *EPD7in5_V2) DeepSleep() error {
221+
return e.Command(0x07, nil)
222+
}
223+
224+
func NewImageBuffer() []byte {
225+
return make([]byte, BYTE_WIDTH*HEIGHT)
226+
}

examples/epd7in5v2/.tool-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
golang 1.23.4

examples/epd7in5v2/main.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package main
2+
3+
import (
4+
"machine"
5+
"time"
6+
7+
"tinygo.org/x/drivers/epd7in5v2"
8+
)
9+
10+
// example for writing to a e-ink display
11+
func main() {
12+
// Pins are for an Adafruit Feather nRF52840 Express
13+
bus := machine.SPI0
14+
cs := machine.D5
15+
dc := machine.D6
16+
rst := machine.D9
17+
busy := machine.D10
18+
pwr := machine.D11
19+
20+
panel := epd7in5v2.New(cs, rst, dc, busy, pwr, bus)
21+
err := panel.Configure(machine.SPI0_SCK_PIN, machine.SPI0_SDO_PIN)
22+
if err != nil {
23+
panic(err)
24+
}
25+
26+
panel.Reset()
27+
28+
err = panel.Init()
29+
if err != nil {
30+
panic(err)
31+
}
32+
33+
buf := epd7in5v2.NewImageBuffer()
34+
35+
// Draw some stripes
36+
var color byte
37+
for y := 0; y < epd7in5v2.HEIGHT; y++ {
38+
if y/60%2 == 0 {
39+
color = 0xFF
40+
} else {
41+
color = 0x00
42+
}
43+
for x := 0; x < epd7in5v2.BYTE_WIDTH; x++ {
44+
buf[y*epd7in5v2.BYTE_WIDTH+x] = color
45+
}
46+
}
47+
48+
err = panel.Draw(buf)
49+
if err != nil {
50+
panic(err)
51+
}
52+
53+
time.Sleep(5 * time.Second)
54+
55+
err = panel.Clear()
56+
if err != nil {
57+
panic(err)
58+
}
59+
60+
err = panel.DeepSleep()
61+
if err != nil {
62+
panic(err)
63+
}
64+
}

smoketest.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/tmc2209/mai
140140
tinygo build -size short -o ./build/test.hex -target=pico ./examples/tmc5160/main.go
141141
tinygo build -size short -o ./build/test.uf2 -target=nicenano ./examples/sharpmem/main.go
142142
tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/max6675/main.go
143+
tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/epd7in5v2/main.go
143144
# network examples (espat)
144145
tinygo build -size short -o ./build/test.hex -target=challenger-rp2040 ./examples/net/ntpclient/
145146
# network examples (wifinina)

0 commit comments

Comments
 (0)