You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
devices/firmata/i2c.go

87 lines
1.4 KiB
Go

package firmata
import (
"errors"
"fmt"
"math"
"sync"
"periph.io/x/conn/v3/physic"
)
var (
Err10BitAddressingNotSupported = errors.New("10-bit addressing not supported")
)
type I2CBus struct {
c ClientI
mu sync.Mutex
}
func newI2CBus(c ClientI) (*I2CBus, error) {
b := &I2CBus{
c: c,
}
err := c.SendI2CConfig(0)
if err != nil {
return nil, err
}
return b, nil
}
func (b *I2CBus) Close() error {
panic("implement me")
}
func (b *I2CBus) String() string {
panic("implement me")
}
func (b *I2CBus) Tx(addr uint16, w, r []byte) error {
if addr >= 0b11111111 {
return fmt.Errorf("%w: 0x%04X", Err10BitAddressingNotSupported, addr)
}
if len(r) > math.MaxUint16 {
return fmt.Errorf("%w: cannot reach more than %d bytes", ErrValueOutOfRange, math.MaxUint16)
}
b.mu.Lock()
defer b.mu.Unlock()
ch := make(chan I2CPacket)
defer close(ch)
address := uint8(addr)
release, err := b.c.SetI2CAddressListener(address, ch)
if err != nil {
return err
}
defer release()
if len(w) > 0 {
if err := b.c.WriteI2CData(address, false, w); err != nil {
return err
}
}
if len(r) > 0 {
if err := b.c.ReadI2CData(address, false, uint16(len(r))); err != nil {
return err
}
pck := <-ch
copy(r, pck.Data)
}
return nil
}
func (b *I2CBus) SetSpeed(f physic.Frequency) error {
return fmt.Errorf("%w: firmata does not support setting bus frequency", ErrUnsupportedFeature)
}