ep0099: optionally read device state on init (#86)

pull/87/head
Shannon Wynter 1 year ago committed by GitHub
parent 72857e8c3f
commit cfd565d1ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -25,7 +25,15 @@ type Dev struct {
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
}
@ -34,7 +42,12 @@ func New(bus i2c.Bus, address uint16) (*Dev, error) {
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
}
@ -42,7 +55,7 @@ func New(bus i2c.Bus, address uint16) (*Dev, error) {
}
func (d *Dev) Halt() error {
return d.reset()
return d.Reset()
}
func (d *Dev) On(channel uint8) error {
@ -72,6 +85,20 @@ func (d *Dev) State(channel uint8) (State, error) {
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
}
d.state[i] = State(read[0])
}
return nil
}
func (d *Dev) AvailableChannels() []uint8 {
return []uint8{0x01, 0x02, 0x03, 0x04}
}
@ -83,7 +110,7 @@ func (s State) String() string {
return "on"
}
func (d *Dev) reset() error {
func (d *Dev) Reset() error {
for _, channel := range d.AvailableChannels() {
err := d.Off(channel)
if err != nil {

@ -12,6 +12,7 @@ import (
"testing"
"periph.io/x/conn/v3/i2c/i2ctest"
"periph.io/x/conn/v3/physic"
)
const (
@ -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)
@ -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…
Cancel
Save