2014-04-28 09:54:41 +08:00
|
|
|
package i2c
|
2014-04-26 18:11:51 +08:00
|
|
|
|
2017-04-03 02:10:12 +08:00
|
|
|
import (
|
2017-04-12 17:47:42 +08:00
|
|
|
"errors"
|
2017-04-03 02:10:12 +08:00
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
)
|
2017-02-06 07:19:42 +08:00
|
|
|
|
2014-09-12 04:38:08 +08:00
|
|
|
var rgb = map[string]interface{}{
|
|
|
|
"red": 1.0,
|
|
|
|
"green": 1.0,
|
|
|
|
"blue": 1.0,
|
|
|
|
}
|
|
|
|
|
2014-06-16 08:22:50 +08:00
|
|
|
type i2cTestAdaptor struct {
|
2017-04-12 17:47:42 +08:00
|
|
|
name string
|
2021-03-12 02:43:17 +08:00
|
|
|
bus int
|
|
|
|
address int
|
2017-04-12 17:47:42 +08:00
|
|
|
written []byte
|
|
|
|
mtx sync.Mutex
|
|
|
|
i2cConnectErr bool
|
|
|
|
i2cReadImpl func([]byte) (int, error)
|
|
|
|
i2cWriteImpl func([]byte) (int, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *i2cTestAdaptor) Testi2cConnectErr(val bool) {
|
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
|
|
|
t.i2cConnectErr = val
|
2014-04-26 18:11:51 +08:00
|
|
|
}
|
|
|
|
|
2017-04-03 02:10:12 +08:00
|
|
|
func (t *i2cTestAdaptor) Testi2cReadImpl(f func([]byte) (int, error)) {
|
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
|
|
|
t.i2cReadImpl = f
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *i2cTestAdaptor) Testi2cWriteImpl(f func([]byte) (int, error)) {
|
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
|
|
|
t.i2cWriteImpl = f
|
|
|
|
}
|
|
|
|
|
2023-11-16 03:51:52 +08:00
|
|
|
func (t *i2cTestAdaptor) Read(b []byte) (int, error) {
|
2017-04-03 02:10:12 +08:00
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
2017-02-06 07:19:42 +08:00
|
|
|
return t.i2cReadImpl(b)
|
2014-12-23 05:36:52 +08:00
|
|
|
}
|
2017-01-20 07:17:41 +08:00
|
|
|
|
2023-11-16 03:51:52 +08:00
|
|
|
func (t *i2cTestAdaptor) Write(b []byte) (int, error) {
|
2017-04-03 02:10:12 +08:00
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
2017-02-06 07:19:42 +08:00
|
|
|
t.written = append(t.written, b...)
|
|
|
|
return t.i2cWriteImpl(b)
|
2014-12-23 05:36:52 +08:00
|
|
|
}
|
2017-01-20 07:17:41 +08:00
|
|
|
|
2017-02-06 07:19:42 +08:00
|
|
|
func (t *i2cTestAdaptor) Close() error {
|
|
|
|
return nil
|
2014-04-26 18:11:51 +08:00
|
|
|
}
|
2017-01-20 07:17:41 +08:00
|
|
|
|
2023-11-16 03:51:52 +08:00
|
|
|
func (t *i2cTestAdaptor) ReadByte() (byte, error) {
|
2017-04-03 02:10:12 +08:00
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
2017-02-06 07:19:42 +08:00
|
|
|
bytes := []byte{0}
|
2023-11-16 03:51:52 +08:00
|
|
|
if err := t.readBytes(bytes); err != nil {
|
|
|
|
return 0, err
|
2017-02-06 07:19:42 +08:00
|
|
|
}
|
2023-11-16 03:51:52 +08:00
|
|
|
val := bytes[0]
|
|
|
|
return val, nil
|
2017-01-20 07:17:41 +08:00
|
|
|
}
|
|
|
|
|
2023-11-16 03:51:52 +08:00
|
|
|
func (t *i2cTestAdaptor) ReadByteData(reg uint8) (uint8, error) {
|
2017-04-03 02:10:12 +08:00
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
2023-11-16 03:51:52 +08:00
|
|
|
if err := t.writeBytes([]byte{reg}); err != nil {
|
|
|
|
return 0, err
|
2017-02-06 07:19:42 +08:00
|
|
|
}
|
2022-09-07 01:55:05 +08:00
|
|
|
bytes := []byte{0}
|
2023-11-16 03:51:52 +08:00
|
|
|
if err := t.readBytes(bytes); err != nil {
|
|
|
|
return 0, err
|
2017-02-06 07:19:42 +08:00
|
|
|
}
|
2023-11-16 03:51:52 +08:00
|
|
|
val := bytes[0]
|
|
|
|
return val, nil
|
2017-01-20 07:17:41 +08:00
|
|
|
}
|
|
|
|
|
2023-11-16 03:51:52 +08:00
|
|
|
func (t *i2cTestAdaptor) ReadWordData(reg uint8) (uint16, error) {
|
2017-04-03 02:10:12 +08:00
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
2023-11-16 03:51:52 +08:00
|
|
|
if err := t.writeBytes([]byte{reg}); err != nil {
|
|
|
|
return 0, err
|
2022-09-07 01:55:05 +08:00
|
|
|
}
|
2017-02-06 07:19:42 +08:00
|
|
|
bytes := []byte{0, 0}
|
|
|
|
bytesRead, err := t.i2cReadImpl(bytes)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
if bytesRead != 2 {
|
|
|
|
return 0, fmt.Errorf("Buffer underrun")
|
|
|
|
}
|
|
|
|
low, high := bytes[0], bytes[1]
|
2023-11-16 03:51:52 +08:00
|
|
|
return (uint16(high) << 8) | uint16(low), nil
|
2017-01-20 07:17:41 +08:00
|
|
|
}
|
|
|
|
|
2023-11-16 03:51:52 +08:00
|
|
|
func (t *i2cTestAdaptor) ReadBlockData(reg uint8, b []byte) error {
|
2017-04-03 02:10:12 +08:00
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
2023-11-16 03:51:52 +08:00
|
|
|
if err := t.writeBytes([]byte{reg}); err != nil {
|
|
|
|
return err
|
2022-09-07 01:55:05 +08:00
|
|
|
}
|
|
|
|
return t.readBytes(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *i2cTestAdaptor) WriteByte(val byte) error {
|
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
|
|
|
return t.writeBytes([]byte{val})
|
2017-01-20 07:17:41 +08:00
|
|
|
}
|
|
|
|
|
2023-11-16 03:51:52 +08:00
|
|
|
func (t *i2cTestAdaptor) WriteByteData(reg uint8, val uint8) error {
|
2017-04-03 02:10:12 +08:00
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
2022-09-07 01:55:05 +08:00
|
|
|
bytes := []byte{reg, val}
|
|
|
|
|
|
|
|
return t.writeBytes(bytes)
|
2017-02-06 07:19:42 +08:00
|
|
|
}
|
|
|
|
|
2022-09-07 01:55:05 +08:00
|
|
|
func (t *i2cTestAdaptor) WriteWordData(reg uint8, val uint16) error {
|
2017-04-03 02:10:12 +08:00
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
2024-11-01 19:54:20 +08:00
|
|
|
low := uint8(val & 0xff) //nolint:gosec // ok here
|
|
|
|
high := uint8((val >> 8) & 0xff) //nolint:gosec // ok here
|
2022-09-07 01:55:05 +08:00
|
|
|
bytes := []byte{reg, low, high}
|
|
|
|
|
|
|
|
return t.writeBytes(bytes)
|
2017-01-20 07:17:41 +08:00
|
|
|
}
|
|
|
|
|
2022-09-07 01:55:05 +08:00
|
|
|
func (t *i2cTestAdaptor) WriteBlockData(reg uint8, b []byte) error {
|
2017-04-03 02:10:12 +08:00
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
2022-09-07 01:55:05 +08:00
|
|
|
if len(b) > 32 {
|
|
|
|
b = b[:32]
|
|
|
|
}
|
|
|
|
buf := make([]byte, len(b)+1)
|
|
|
|
copy(buf[1:], b)
|
|
|
|
buf[0] = reg
|
|
|
|
|
|
|
|
return t.writeBytes(buf)
|
2017-01-20 07:17:41 +08:00
|
|
|
}
|
|
|
|
|
2022-12-17 18:56:11 +08:00
|
|
|
func (t *i2cTestAdaptor) WriteBytes(b []byte) error {
|
|
|
|
t.mtx.Lock()
|
|
|
|
defer t.mtx.Unlock()
|
|
|
|
if len(b) > 32 {
|
|
|
|
b = b[:32]
|
|
|
|
}
|
|
|
|
return t.writeBytes(b)
|
|
|
|
}
|
|
|
|
|
2023-11-16 03:51:52 +08:00
|
|
|
func (t *i2cTestAdaptor) GetI2cConnection(address int, bus int) (Connection, error) {
|
2017-04-12 17:47:42 +08:00
|
|
|
if t.i2cConnectErr {
|
|
|
|
return nil, errors.New("Invalid i2c connection")
|
|
|
|
}
|
2021-03-12 02:43:17 +08:00
|
|
|
t.bus = bus
|
|
|
|
t.address = address
|
2017-01-20 07:17:41 +08:00
|
|
|
return t, nil
|
|
|
|
}
|
|
|
|
|
2022-12-10 20:10:23 +08:00
|
|
|
func (t *i2cTestAdaptor) DefaultI2cBus() int {
|
2017-02-06 07:19:42 +08:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2023-11-16 03:51:52 +08:00
|
|
|
func (t *i2cTestAdaptor) Name() string { return t.name }
|
|
|
|
func (t *i2cTestAdaptor) SetName(n string) { t.name = n }
|
|
|
|
func (t *i2cTestAdaptor) Connect() error { return nil }
|
|
|
|
func (t *i2cTestAdaptor) Finalize() error { return nil }
|
2014-04-26 18:11:51 +08:00
|
|
|
|
2016-09-25 20:08:18 +08:00
|
|
|
func newI2cTestAdaptor() *i2cTestAdaptor {
|
2014-06-16 08:22:50 +08:00
|
|
|
return &i2cTestAdaptor{
|
2017-04-12 17:47:42 +08:00
|
|
|
i2cConnectErr: false,
|
2022-03-20 04:16:31 +08:00
|
|
|
i2cReadImpl: func(b []byte) (int, error) {
|
|
|
|
return len(b), nil
|
2014-12-23 05:36:52 +08:00
|
|
|
},
|
2022-09-16 01:50:07 +08:00
|
|
|
i2cWriteImpl: func(b []byte) (int, error) {
|
|
|
|
return len(b), nil
|
2014-09-12 04:38:08 +08:00
|
|
|
},
|
2014-06-16 08:22:50 +08:00
|
|
|
}
|
2014-04-26 18:11:51 +08:00
|
|
|
}
|
2022-09-07 01:55:05 +08:00
|
|
|
|
|
|
|
func (t *i2cTestAdaptor) readBytes(b []byte) error {
|
|
|
|
n, err := t.i2cReadImpl(b)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if n != len(b) {
|
|
|
|
return fmt.Errorf("Read %v bytes from device by i2c helpers, expected %v", n, len(b))
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *i2cTestAdaptor) writeBytes(b []byte) error {
|
|
|
|
t.written = append(t.written, b...)
|
|
|
|
// evaluation of count can be done in test
|
|
|
|
_, err := t.i2cWriteImpl(b)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|