Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 164 additions & 18 deletions inky/impression.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ var (
{255, 255, 255, 0}, // Clear
}

dsc6 = []color.NRGBA{
{0, 0, 0, 255}, // Black
{255, 255, 255, 255}, // White
{255, 255, 0, 255}, // Yellow
{255, 0, 0, 255}, // Red
{0, 0, 255, 255}, // Blue
{0, 255, 0, 255}, // Green
{255, 255, 255, 0}, // Clear
}

sc = []color.NRGBA{
{57, 48, 57, 255}, // Black
{255, 255, 255, 255}, // White
Expand All @@ -60,6 +70,16 @@ var (
{239, 121, 44, 255}, // Orange
{255, 255, 255, 0}, // Clear
}

sc6 = []color.NRGBA{
{0, 0, 0, 255}, // Black
{161, 164, 165, 255}, // Gray
{208, 190, 71, 255}, // Yellow
{156, 72, 75, 255}, // Red
{61, 59, 94, 255}, // Blue
{58, 91, 70, 255}, // Green
{255, 255, 255, 0}, // Clear
}
)

const (
Expand Down Expand Up @@ -129,6 +149,26 @@ const (
ac073TC1CCSET = 0xE0
ac073TC1PWS = 0xE3
ac073TC1TSSET = 0xE6

el673PSR = 0x00
el673PWR = 0x01
el673POF = 0x02
el673POFS = 0x03
el673PON = 0x04
el673BTST1 = 0x05
el673BTST2 = 0x06
el673DSLP = 0x07
el673BTST3 = 0x08
el673DTM1 = 0x10
el673DSP = 0x11
el673DRF = 0x12
el673PLL = 0x30
el673CDI = 0x50
el673TCON = 0x60
el673TRES = 0x61
el673REV = 0x70
el673VDCS = 0x82
el673PWS = 0xE3
)

// DevImpression is a handle to an Inky Impression.
Expand Down Expand Up @@ -206,7 +246,7 @@ func NewImpression(p spi.Port, dc gpio.PinOut, reset gpio.PinOut, busy gpio.PinI
d.width = 600
d.height = 448
d.res = 0b11
case IMPRESSION73:
case IMPRESSION73, IMPRESSION73SPECTRA6:
d.width = 800
d.height = 480
d.res = 0b11
Expand All @@ -227,28 +267,38 @@ func NewImpression(p spi.Port, dc gpio.PinOut, reset gpio.PinOut, busy gpio.PinI
func (d *DevImpression) blend() color.Palette {
sat := float64(d.saturation) / 100.0

var satPalette []color.NRGBA
var dscPalette []color.NRGBA
switch d.Dev.model {
case IMPRESSION73:
satPalette = sc7
dscPalette = dsc
case IMPRESSION73SPECTRA6:
satPalette = sc6
dscPalette = dsc6
default:
satPalette = sc
dscPalette = dsc
}

pr := make([]color.Color, 0)
for i := 0; i < 7; i++ {
var rs, gs, bs uint8
if d.Dev.model == IMPRESSION73 {
rs, gs, bs =
uint8(float64(sc7[i].R)*sat),
uint8(float64(sc7[i].G)*sat),
uint8(float64(sc7[i].B)*sat)
} else {
rs, gs, bs =
uint8(float64(sc[i].R)*sat),
uint8(float64(sc[i].G)*sat),
uint8(float64(sc[i].B)*sat)
}
for i := range satPalette {
rs, gs, bs := uint8(float64(satPalette[i].R)*sat),
uint8(float64(satPalette[i].G)*sat),
uint8(float64(satPalette[i].B)*sat)

rd, gd, bd :=
uint8(float64(dsc[i].R)*(1.0-sat)),
uint8(float64(dsc[i].G)*(1.0-sat)),
uint8(float64(dsc[i].B)*(1.0-sat))
uint8(float64(dscPalette[i].R)*(1.0-sat)),
uint8(float64(dscPalette[i].G)*(1.0-sat)),
uint8(float64(dscPalette[i].B)*(1.0-sat))

pr = append(pr, color.RGBA{rs + rd, gs + gd, bs + bd, dscPalette[i].A})
}

pr = append(pr, color.RGBA{rs + rd, gs + gd, bs + bd, dsc[i].A})
if d.Dev.model == IMPRESSION73SPECTRA6 {
return pr
}

// Add Transparent color and return the result.
return append(pr, color.RGBA{255, 255, 255, 0})
}
Expand Down Expand Up @@ -293,6 +343,14 @@ func (d *DevImpression) Render() error {
}
}

// remap spectra6 pixels to correct color palette
if d.model == IMPRESSION73SPECTRA6 {
remap := []uint8{0, 1, 2, 3, 5, 6}
for i, pix := range d.Pix {
d.Pix[i] = remap[pix]
}
}

merged := make([]uint8, len(d.Pix)/2)
for i, offset := 0, 0; i < len(d.Pix)-1; i, offset = i+2, offset+1 {
merged[offset] = ((d.Pix[i] << 4) & 0xF0) | (d.Pix[i+1] & 0x0F)
Expand Down Expand Up @@ -486,9 +544,68 @@ func (d *DevImpression) resetAC() error {
return nil
}

func (d *DevImpression) resetEC() error {
// reference code: https://github.com/pimoroni/inky/blob/fef67aab73bb2b6def1eca6003a3f5a3ccec0741/inky/inky_e673.py#L204

if err := d.cycleResetGPIO(); err != nil {
return err
}
time.Sleep(30 * time.Millisecond)
if err := d.cycleResetGPIO(); err != nil {
return err
}
time.Sleep(30 * time.Millisecond)

d.wait(300 * time.Millisecond)

if err := d.sendCommand(0xAA, []byte{0x49, 0x55, 0x20, 0x08, 0x09, 0x18}); err != nil {
return err
}
if err := d.sendCommand(el673PWR, []byte{0x3F}); err != nil {
return err
}
if err := d.sendCommand(el673PSR, []byte{0x5F, 0x69}); err != nil {
return err
}
if err := d.sendCommand(el673BTST1, []byte{0x40, 0x1F, 0x1F, 0x2C}); err != nil {
return err
}
if err := d.sendCommand(el673BTST3, []byte{0x6F, 0x1F, 0x1F, 0x22}); err != nil {
return err
}
if err := d.sendCommand(el673BTST2, []byte{0x6F, 0x1F, 0x17, 0x17}); err != nil {
return err
}
if err := d.sendCommand(el673POFS, []byte{0x00, 0x54, 0x00, 0x44}); err != nil {
return err
}
if err := d.sendCommand(el673TCON, []byte{0x02, 0x00}); err != nil {
return err
}
if err := d.sendCommand(el673PLL, []byte{0x08}); err != nil {
return err
}
if err := d.sendCommand(el673CDI, []byte{0x3F}); err != nil {
return err
}
if err := d.sendCommand(el673TRES, []byte{0x03, 0x20, 0x01, 0xE0}); err != nil {
return err
}
if err := d.sendCommand(el673PWS, []byte{0x2F}); err != nil {
return err
}
if err := d.sendCommand(el673VDCS, []byte{0x01}); err != nil {
return err
}

return nil
}

func (d *DevImpression) update(pix []uint8) error {
if d.model == IMPRESSION73 {
return d.updateAC(pix)
} else if d.model == IMPRESSION73SPECTRA6 {
return d.updateEC(pix)
}
return d.updateUC(pix)
}
Expand Down Expand Up @@ -557,6 +674,35 @@ func (d *DevImpression) updateAC(pix []uint8) error {
return nil
}

func (d *DevImpression) updateEC(pix []uint8) error {
if err := d.resetEC(); err != nil {
return err
}

if err := d.sendCommand(el673DTM1, pix); err != nil {
return err
}
if err := d.sendCommand(el673PON, nil); err != nil {
return err
}
d.wait(300 * time.Millisecond)

if err := d.sendCommand(el673BTST2, []byte{0x6F, 0x1F, 0x17, 0x49}); err != nil {
return err
}
if err := d.sendCommand(el673DRF, []byte{0x00}); err != nil {
return err
}
d.wait(32 * time.Second)

if err := d.sendCommand(el673POF, []byte{0x00}); err != nil {
return err
}
d.wait(300 * time.Millisecond)

return nil
}

// Wait for busy/wait pin.
func (d *DevImpression) wait(dur time.Duration) {
// Set it as input, with a pull down and enable rising edge triggering.
Expand Down
5 changes: 4 additions & 1 deletion inky/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var (
"Red wHAT (SSD1683)",
"Yellow wHAT (SSD1683)",
"7-Colour 800x480 (AC073TC1A)",
"Spectra 6 7.3 800 x 480 (E673)",
}
)

Expand Down Expand Up @@ -78,7 +79,7 @@ func DetectOpts(bus i2c.Bus) (*Opts, error) {
case 3:
options.ModelColor = Yellow
options.BorderColor = Yellow
case 4:
case 4, 6:
options.ModelColor = Multi
options.BorderColor = Color(WhiteImpression)
default:
Expand All @@ -100,6 +101,8 @@ func DetectOpts(bus i2c.Bus) (*Opts, error) {
options.Model = IMPRESSION4
case 20:
options.Model = IMPRESSION73
case 22:
options.Model = IMPRESSION73SPECTRA6
default:
return nil, fmt.Errorf("failed to get ops: display type %v not supported", data[6])
}
Expand Down
5 changes: 4 additions & 1 deletion inky/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const (
IMPRESSION4
IMPRESSION57
IMPRESSION73
IMPRESSION73SPECTRA6
)

// Set sets the Model to a value represented by the string s. Set implements the [flag.Value] interface.
Expand All @@ -39,8 +40,10 @@ func (m *Model) Set(s string) error {
*m = IMPRESSION57
case "IMPRESSION73":
*m = IMPRESSION73
case "IMPRESSION73SPECTRA6":
*m = IMPRESSION73SPECTRA6
default:
return fmt.Errorf("unknown model %q: expected PHAT, PHAT2, WHAT, IMPRESSION4, IMPRESSION57 or IMPRESSION73", s)
return fmt.Errorf("unknown model %q: expected PHAT, PHAT2, WHAT, IMPRESSION4, IMPRESSION57, IMPRESSION73, or IMPRESSION73SPECTRA6", s)
}
return nil
}
Expand Down
5 changes: 3 additions & 2 deletions inky/types_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.