inky: fix blend precision, height quirk, and minor cleanups

- Fix color blending truncation in blend(): compute the full weighted
    sum as float64 before casting to uint8, avoiding double truncation
  - Fix UC8159 on IMPRESSION57 incorrectly reporting height as 447;
    correct it to 448 in DetectOpts
  - Add Opts.String() for human-readable option printing
  - Refactor update() if/else chain to a switch statement
  - Add TestDevImpression_BlendPrecision to cover the blend fix

Signed-off-by: Çağlar Onur <caglar@10ur.org>
pull/117/head
Çağlar Onur 3 weeks ago
parent 1752d1b57a
commit 89a9731dff
No known key found for this signature in database
GPG Key ID: 97DC0A9223E81DE4

@ -283,16 +283,11 @@ func (d *DevImpression) blend() color.Palette {
pr := make([]color.Color, 0)
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)
r := uint8(float64(satPalette[i].R)*sat + float64(dscPalette[i].R)*(1.0-sat))
g := uint8(float64(satPalette[i].G)*sat + float64(dscPalette[i].G)*(1.0-sat))
b := uint8(float64(satPalette[i].B)*sat + float64(dscPalette[i].B)*(1.0-sat))
rd, gd, bd :=
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{r, g, b, dscPalette[i].A})
}
if d.Dev.model == IMPRESSION73SPECTRA6 {
@ -567,6 +562,7 @@ func (d *DevImpression) resetEC() error {
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
}
@ -576,6 +572,7 @@ func (d *DevImpression) resetEC() error {
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
}
@ -602,12 +599,14 @@ func (d *DevImpression) resetEC() error {
}
func (d *DevImpression) update(pix []uint8) error {
if d.model == IMPRESSION73 {
switch d.model {
case IMPRESSION73:
return d.updateAC(pix)
} else if d.model == IMPRESSION73SPECTRA6 {
case IMPRESSION73SPECTRA6:
return d.updateEC(pix)
}
default:
return d.updateUC(pix)
}
}
func (d *DevImpression) updateUC(pix []uint8) error {
@ -710,10 +709,12 @@ func (d *DevImpression) wait(dur time.Duration) {
log.Printf("Err: %s", err)
return
}
if d.busy.Read() == gpio.High {
time.Sleep(dur)
return
}
// Wait for rising edges (Low -> High) or the timeout.
tEnd := time.Now().Add(dur)
edgeDur := dur

@ -0,0 +1,48 @@
// Copyright 2019 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
package inky
import (
"image/color"
"testing"
)
func TestDevImpression_BlendPrecision(t *testing.T) {
// Saturation level that triggers truncation if not handled correctly.
// For example, if rs=10.9 and rd=5.9:
// Old: uint8(10.9) + uint8(5.9) = 10 + 5 = 15
// New: uint8(10.9 + 5.9) = uint8(16.8) = 16
// We need to simulate this with real palette values and saturation.
// Let's use a simplified case.
// satPalette[0].R = 109, dscPalette[0].R = 59, saturation = 10%
// rs = 109 * 0.1 = 10.9
// rd = 59 * 0.9 = 53.1
// Old: 10 + 53 = 63
// New: uint8(10.9 + 53.1) = uint8(64.0) = 64
d := &DevImpression{
saturation: 10,
}
d.Dev.model = IMPRESSION73 // This uses sc7 and dsc
// Override sc7 and dsc for the test up to at least common length
oldSc7 := sc7
oldDsc := dsc
defer func() {
sc7 = oldSc7
dsc = oldDsc
}()
sc7 = []color.NRGBA{{R: 109, G: 0, B: 0, A: 255}}
dsc = []color.NRGBA{{R: 59, G: 0, B: 0, A: 255}}
p := d.blend()
c := p[0].(color.RGBA)
if c.R != 64 {
t.Errorf("Expected R=64, got %d. Precision loss detected!", c.R)
}
}

@ -97,6 +97,10 @@ func DetectOpts(bus i2c.Bus) (*Opts, error) {
options.Model = WHAT
case 14:
options.Model = IMPRESSION57
// Some UC8159's report Height as 447 so fix that.
if options.Height == 447 {
options.Height = 448
}
case 15, 16:
options.Model = IMPRESSION4
case 20:
@ -124,3 +128,7 @@ func readEep(bus i2c.Bus) ([]byte, error) {
return data, nil
}
func (o *Opts) String() string {
return fmt.Sprintf("Resolution: %dx%d Model: %s Model Color: %s Border Color: %s PCB Variant: %d Display Variant: %d", o.Width, o.Height, o.Model, o.ModelColor, o.BorderColor, o.PCBVariant, o.DisplayVariant)
}

Loading…
Cancel
Save