Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ep0099: optionally read device state on new #86

Merged
merged 1 commit into from
Dec 20, 2024
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
33 changes: 30 additions & 3 deletions ep0099/ep0099.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@
state [4]State
}

type Opts struct {
ReadStates bool // ReadStates from the device on startup instead of resetting the device.
}

func New(bus i2c.Bus, address uint16) (*Dev, error) {
return NewWithOpts(bus, address, nil)
}

func NewWithOpts(bus i2c.Bus, address uint16, opts *Opts) (*Dev, error) {
if err := isValidAddress(address); err != nil {
return nil, err
}
Expand All @@ -34,15 +42,20 @@
i2c: i2c.Dev{Bus: bus, Addr: address},
}

if err := d.reset(); err != nil {
bootFn := d.Reset
if opts != nil && opts.ReadStates {
bootFn = d.ReadStates
}

if err := bootFn(); err != nil {
return nil, err
}

return d, nil
}

func (d *Dev) Halt() error {
return d.reset()
return d.Reset()
}

func (d *Dev) On(channel uint8) error {
Expand Down Expand Up @@ -72,6 +85,20 @@
return d.state[channel-1], nil
}

func (d *Dev) ReadStates() error {
for i, channel := range d.AvailableChannels() {
read := make([]byte, 1)

if err := d.i2c.Tx([]byte{channel}, read); err != nil {
return err
}

Check warning on line 94 in ep0099/ep0099.go

View check run for this annotation

Codecov / codecov/patch

ep0099/ep0099.go#L93-L94

Added lines #L93 - L94 were not covered by tests

d.state[i] = State(read[0])
}

return nil
}

func (d *Dev) AvailableChannels() []uint8 {
return []uint8{0x01, 0x02, 0x03, 0x04}
}
Expand All @@ -83,7 +110,7 @@
return "on"
}

func (d *Dev) reset() error {
func (d *Dev) Reset() error {
for _, channel := range d.AvailableChannels() {
err := d.Off(channel)
if err != nil {
Expand Down
41 changes: 41 additions & 0 deletions ep0099/ep0099_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"testing"

"periph.io/x/conn/v3/i2c/i2ctest"
"periph.io/x/conn/v3/physic"
)

const (
Expand Down Expand Up @@ -90,6 +91,22 @@ func TestOff(t *testing.T) {
checkChannelState(t, dev, 4, StateOff)
}

func TestReadState(t *testing.T) {
bus := initTestBus()
bus.Bus = &testBus{states: [4]State{StateOff, StateOn, StateOff, StateOn}}

dev, err := NewWithOpts(bus, testDefaultValidAddress, &Opts{ReadStates: true})

if err != nil {
t.Fatal("Failed to create dev with ReadStates, got ", err)
}

checkChannelState(t, dev, 1, StateOff)
checkChannelState(t, dev, 2, StateOn)
checkChannelState(t, dev, 3, StateOff)
checkChannelState(t, dev, 4, StateOn)
}

func TestReturnErrorForInvalidChannel(t *testing.T) {
bus := initTestBus()
dev, _ := New(bus, testDefaultValidAddress)
Expand Down Expand Up @@ -153,3 +170,27 @@ func checkDevReset(t *testing.T, dev *Dev, bus *i2ctest.Record) {
checkBusHasWrite(t, bus, []byte{4, byte(StateOff)})
checkChannelState(t, dev, 4, StateOff)
}

type testBus struct {
states [4]State
}

func (b *testBus) String() string {
return "ep0099 test i2c bus"
}

func (b *testBus) Tx(addr uint16, w, r []byte) error {
if len(w) == 1 && len(r) == 1 {
if w[0] < 1 || w[0] > 4 {
return errors.New("Invalid port")
}

r[0] = byte(b.states[w[0]-1])
}

return nil
}

func (b *testBus) SetSpeed(f physic.Frequency) error {
return nil
}
Loading