Skip to content

Commit 55d75a3

Browse files
authored
inky: Add Impression 7.3 Spectra6 support (#110)
* add inky impression 7.3 spectra6 support * run go generate
1 parent 01409c1 commit 55d75a3

File tree

4 files changed

+175
-22
lines changed

4 files changed

+175
-22
lines changed

inky/impression.go

Lines changed: 164 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ var (
3939
{255, 255, 255, 0}, // Clear
4040
}
4141

42+
dsc6 = []color.NRGBA{
43+
{0, 0, 0, 255}, // Black
44+
{255, 255, 255, 255}, // White
45+
{255, 255, 0, 255}, // Yellow
46+
{255, 0, 0, 255}, // Red
47+
{0, 0, 255, 255}, // Blue
48+
{0, 255, 0, 255}, // Green
49+
{255, 255, 255, 0}, // Clear
50+
}
51+
4252
sc = []color.NRGBA{
4353
{57, 48, 57, 255}, // Black
4454
{255, 255, 255, 255}, // White
@@ -60,6 +70,16 @@ var (
6070
{239, 121, 44, 255}, // Orange
6171
{255, 255, 255, 0}, // Clear
6272
}
73+
74+
sc6 = []color.NRGBA{
75+
{0, 0, 0, 255}, // Black
76+
{161, 164, 165, 255}, // Gray
77+
{208, 190, 71, 255}, // Yellow
78+
{156, 72, 75, 255}, // Red
79+
{61, 59, 94, 255}, // Blue
80+
{58, 91, 70, 255}, // Green
81+
{255, 255, 255, 0}, // Clear
82+
}
6383
)
6484

6585
const (
@@ -129,6 +149,26 @@ const (
129149
ac073TC1CCSET = 0xE0
130150
ac073TC1PWS = 0xE3
131151
ac073TC1TSSET = 0xE6
152+
153+
el673PSR = 0x00
154+
el673PWR = 0x01
155+
el673POF = 0x02
156+
el673POFS = 0x03
157+
el673PON = 0x04
158+
el673BTST1 = 0x05
159+
el673BTST2 = 0x06
160+
el673DSLP = 0x07
161+
el673BTST3 = 0x08
162+
el673DTM1 = 0x10
163+
el673DSP = 0x11
164+
el673DRF = 0x12
165+
el673PLL = 0x30
166+
el673CDI = 0x50
167+
el673TCON = 0x60
168+
el673TRES = 0x61
169+
el673REV = 0x70
170+
el673VDCS = 0x82
171+
el673PWS = 0xE3
132172
)
133173

134174
// DevImpression is a handle to an Inky Impression.
@@ -206,7 +246,7 @@ func NewImpression(p spi.Port, dc gpio.PinOut, reset gpio.PinOut, busy gpio.PinI
206246
d.width = 600
207247
d.height = 448
208248
d.res = 0b11
209-
case IMPRESSION73:
249+
case IMPRESSION73, IMPRESSION73SPECTRA6:
210250
d.width = 800
211251
d.height = 480
212252
d.res = 0b11
@@ -227,28 +267,38 @@ func NewImpression(p spi.Port, dc gpio.PinOut, reset gpio.PinOut, busy gpio.PinI
227267
func (d *DevImpression) blend() color.Palette {
228268
sat := float64(d.saturation) / 100.0
229269

270+
var satPalette []color.NRGBA
271+
var dscPalette []color.NRGBA
272+
switch d.Dev.model {
273+
case IMPRESSION73:
274+
satPalette = sc7
275+
dscPalette = dsc
276+
case IMPRESSION73SPECTRA6:
277+
satPalette = sc6
278+
dscPalette = dsc6
279+
default:
280+
satPalette = sc
281+
dscPalette = dsc
282+
}
283+
230284
pr := make([]color.Color, 0)
231-
for i := 0; i < 7; i++ {
232-
var rs, gs, bs uint8
233-
if d.Dev.model == IMPRESSION73 {
234-
rs, gs, bs =
235-
uint8(float64(sc7[i].R)*sat),
236-
uint8(float64(sc7[i].G)*sat),
237-
uint8(float64(sc7[i].B)*sat)
238-
} else {
239-
rs, gs, bs =
240-
uint8(float64(sc[i].R)*sat),
241-
uint8(float64(sc[i].G)*sat),
242-
uint8(float64(sc[i].B)*sat)
243-
}
285+
for i := range satPalette {
286+
rs, gs, bs := uint8(float64(satPalette[i].R)*sat),
287+
uint8(float64(satPalette[i].G)*sat),
288+
uint8(float64(satPalette[i].B)*sat)
244289

245290
rd, gd, bd :=
246-
uint8(float64(dsc[i].R)*(1.0-sat)),
247-
uint8(float64(dsc[i].G)*(1.0-sat)),
248-
uint8(float64(dsc[i].B)*(1.0-sat))
291+
uint8(float64(dscPalette[i].R)*(1.0-sat)),
292+
uint8(float64(dscPalette[i].G)*(1.0-sat)),
293+
uint8(float64(dscPalette[i].B)*(1.0-sat))
294+
295+
pr = append(pr, color.RGBA{rs + rd, gs + gd, bs + bd, dscPalette[i].A})
296+
}
249297

250-
pr = append(pr, color.RGBA{rs + rd, gs + gd, bs + bd, dsc[i].A})
298+
if d.Dev.model == IMPRESSION73SPECTRA6 {
299+
return pr
251300
}
301+
252302
// Add Transparent color and return the result.
253303
return append(pr, color.RGBA{255, 255, 255, 0})
254304
}
@@ -293,6 +343,14 @@ func (d *DevImpression) Render() error {
293343
}
294344
}
295345

346+
// remap spectra6 pixels to correct color palette
347+
if d.model == IMPRESSION73SPECTRA6 {
348+
remap := []uint8{0, 1, 2, 3, 5, 6}
349+
for i, pix := range d.Pix {
350+
d.Pix[i] = remap[pix]
351+
}
352+
}
353+
296354
merged := make([]uint8, len(d.Pix)/2)
297355
for i, offset := 0, 0; i < len(d.Pix)-1; i, offset = i+2, offset+1 {
298356
merged[offset] = ((d.Pix[i] << 4) & 0xF0) | (d.Pix[i+1] & 0x0F)
@@ -486,9 +544,68 @@ func (d *DevImpression) resetAC() error {
486544
return nil
487545
}
488546

547+
func (d *DevImpression) resetEC() error {
548+
// reference code: https://github.com/pimoroni/inky/blob/fef67aab73bb2b6def1eca6003a3f5a3ccec0741/inky/inky_e673.py#L204
549+
550+
if err := d.cycleResetGPIO(); err != nil {
551+
return err
552+
}
553+
time.Sleep(30 * time.Millisecond)
554+
if err := d.cycleResetGPIO(); err != nil {
555+
return err
556+
}
557+
time.Sleep(30 * time.Millisecond)
558+
559+
d.wait(300 * time.Millisecond)
560+
561+
if err := d.sendCommand(0xAA, []byte{0x49, 0x55, 0x20, 0x08, 0x09, 0x18}); err != nil {
562+
return err
563+
}
564+
if err := d.sendCommand(el673PWR, []byte{0x3F}); err != nil {
565+
return err
566+
}
567+
if err := d.sendCommand(el673PSR, []byte{0x5F, 0x69}); err != nil {
568+
return err
569+
}
570+
if err := d.sendCommand(el673BTST1, []byte{0x40, 0x1F, 0x1F, 0x2C}); err != nil {
571+
return err
572+
}
573+
if err := d.sendCommand(el673BTST3, []byte{0x6F, 0x1F, 0x1F, 0x22}); err != nil {
574+
return err
575+
}
576+
if err := d.sendCommand(el673BTST2, []byte{0x6F, 0x1F, 0x17, 0x17}); err != nil {
577+
return err
578+
}
579+
if err := d.sendCommand(el673POFS, []byte{0x00, 0x54, 0x00, 0x44}); err != nil {
580+
return err
581+
}
582+
if err := d.sendCommand(el673TCON, []byte{0x02, 0x00}); err != nil {
583+
return err
584+
}
585+
if err := d.sendCommand(el673PLL, []byte{0x08}); err != nil {
586+
return err
587+
}
588+
if err := d.sendCommand(el673CDI, []byte{0x3F}); err != nil {
589+
return err
590+
}
591+
if err := d.sendCommand(el673TRES, []byte{0x03, 0x20, 0x01, 0xE0}); err != nil {
592+
return err
593+
}
594+
if err := d.sendCommand(el673PWS, []byte{0x2F}); err != nil {
595+
return err
596+
}
597+
if err := d.sendCommand(el673VDCS, []byte{0x01}); err != nil {
598+
return err
599+
}
600+
601+
return nil
602+
}
603+
489604
func (d *DevImpression) update(pix []uint8) error {
490605
if d.model == IMPRESSION73 {
491606
return d.updateAC(pix)
607+
} else if d.model == IMPRESSION73SPECTRA6 {
608+
return d.updateEC(pix)
492609
}
493610
return d.updateUC(pix)
494611
}
@@ -557,6 +674,35 @@ func (d *DevImpression) updateAC(pix []uint8) error {
557674
return nil
558675
}
559676

677+
func (d *DevImpression) updateEC(pix []uint8) error {
678+
if err := d.resetEC(); err != nil {
679+
return err
680+
}
681+
682+
if err := d.sendCommand(el673DTM1, pix); err != nil {
683+
return err
684+
}
685+
if err := d.sendCommand(el673PON, nil); err != nil {
686+
return err
687+
}
688+
d.wait(300 * time.Millisecond)
689+
690+
if err := d.sendCommand(el673BTST2, []byte{0x6F, 0x1F, 0x17, 0x49}); err != nil {
691+
return err
692+
}
693+
if err := d.sendCommand(el673DRF, []byte{0x00}); err != nil {
694+
return err
695+
}
696+
d.wait(32 * time.Second)
697+
698+
if err := d.sendCommand(el673POF, []byte{0x00}); err != nil {
699+
return err
700+
}
701+
d.wait(300 * time.Millisecond)
702+
703+
return nil
704+
}
705+
560706
// Wait for busy/wait pin.
561707
func (d *DevImpression) wait(dur time.Duration) {
562708
// Set it as input, with a pull down and enable rising edge triggering.

inky/opts.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ var (
3434
"Red wHAT (SSD1683)",
3535
"Yellow wHAT (SSD1683)",
3636
"7-Colour 800x480 (AC073TC1A)",
37+
"Spectra 6 7.3 800 x 480 (E673)",
3738
}
3839
)
3940

@@ -78,7 +79,7 @@ func DetectOpts(bus i2c.Bus) (*Opts, error) {
7879
case 3:
7980
options.ModelColor = Yellow
8081
options.BorderColor = Yellow
81-
case 4:
82+
case 4, 6:
8283
options.ModelColor = Multi
8384
options.BorderColor = Color(WhiteImpression)
8485
default:
@@ -100,6 +101,8 @@ func DetectOpts(bus i2c.Bus) (*Opts, error) {
100101
options.Model = IMPRESSION4
101102
case 20:
102103
options.Model = IMPRESSION73
104+
case 22:
105+
options.Model = IMPRESSION73SPECTRA6
103106
default:
104107
return nil, fmt.Errorf("failed to get ops: display type %v not supported", data[6])
105108
}

inky/types.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const (
2222
IMPRESSION4
2323
IMPRESSION57
2424
IMPRESSION73
25+
IMPRESSION73SPECTRA6
2526
)
2627

2728
// Set sets the Model to a value represented by the string s. Set implements the [flag.Value] interface.
@@ -39,8 +40,10 @@ func (m *Model) Set(s string) error {
3940
*m = IMPRESSION57
4041
case "IMPRESSION73":
4142
*m = IMPRESSION73
43+
case "IMPRESSION73SPECTRA6":
44+
*m = IMPRESSION73SPECTRA6
4245
default:
43-
return fmt.Errorf("unknown model %q: expected PHAT, PHAT2, WHAT, IMPRESSION4, IMPRESSION57 or IMPRESSION73", s)
46+
return fmt.Errorf("unknown model %q: expected PHAT, PHAT2, WHAT, IMPRESSION4, IMPRESSION57, IMPRESSION73, or IMPRESSION73SPECTRA6", s)
4447
}
4548
return nil
4649
}

inky/types_string.go

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)