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/tic/tic_test.go

487 lines
9.7 KiB
Go

// Copyright 2024 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 tic
import (
"errors"
"testing"
"periph.io/x/conn/v3/i2c"
"periph.io/x/conn/v3/i2c/i2ctest"
"periph.io/x/conn/v3/physic"
)
func TestNewI2C(t *testing.T) {
for _, test := range []struct {
name string
variant Variant
ops []i2ctest.IO
expectErr bool
}{
{
name: "success",
variant: TicT500,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x49}},
{Addr: I2CAddr, R: []byte{0x00}},
},
expectErr: false,
},
{
name: "invalid variant",
variant: Variant("periph"),
expectErr: true,
},
{
name: "connection failure",
variant: TicT500,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x49}},
},
expectErr: true,
},
} {
t.Run(test.name, func(t *testing.T) {
b := i2ctest.Playback{
Ops: test.ops,
DontPanic: true,
}
defer b.Close()
_, err := NewI2C(&b, test.variant, I2CAddr)
if test.expectErr && err == nil {
t.Fatalf("expected error, got: %v", err)
} else if !test.expectErr && err != nil {
t.Fatal(err)
}
})
}
}
func TestGetTargetPosition(t *testing.T) {
for _, test := range []struct {
name string
ops []i2ctest.IO
want int32
expectErr error
}{
{
name: "success",
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x09}},
{Addr: I2CAddr, R: []byte{byte(PlanningModeTargetPosition)}},
{Addr: I2CAddr, W: []byte{0xA1, 0x0A}},
{Addr: I2CAddr, R: []byte{0xEE, 0xDB, 0xEA, 0x0D}},
},
want: 0xDEADBEE,
expectErr: nil,
},
{
name: "incorrect planning mode",
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x09}},
{Addr: I2CAddr, R: []byte{byte(PlanningModeTargetVelocity)}},
{Addr: I2CAddr, W: []byte{0xA1, 0x0A}},
{Addr: I2CAddr, R: []byte{0xEE, 0xDB, 0xEA, 0x0D}},
},
expectErr: ErrIncorrectPlanningMode,
},
} {
t.Run(test.name, func(t *testing.T) {
b := i2ctest.Playback{
Ops: test.ops,
DontPanic: true,
}
defer b.Close()
dev := Dev{
c: &i2c.Dev{Bus: &b, Addr: I2CAddr},
variant: TicT825,
}
got, err := dev.GetTargetPosition()
if !errors.Is(err, test.expectErr) {
t.Fatalf("expected error: %v, got: %v", test.expectErr, err)
}
if got != test.want {
t.Fatalf("wanted: %d, got: %d", test.want, got)
}
})
}
}
func TestSetStepMode(t *testing.T) {
for _, test := range []struct {
name string
variant Variant
mode StepMode
ops []i2ctest.IO
expectErr error
}{
{
name: "success",
variant: TicT825,
mode: StepModeFull,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x94, 0x00}},
},
expectErr: nil,
},
{
name: "invalid step mode",
variant: TicT825,
mode: StepMode(0xFF),
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x94, 0xFF}},
},
expectErr: ErrInvalidSetting,
},
{
name: "unsupported variant",
variant: TicT500,
mode: StepModeMicrostep256,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x94, 0x09}},
},
expectErr: ErrUnsupportedVariant,
},
} {
t.Run(test.name, func(t *testing.T) {
b := i2ctest.Playback{
Ops: test.ops,
DontPanic: true,
}
defer b.Close()
dev := Dev{
c: &i2c.Dev{Bus: &b, Addr: I2CAddr},
variant: test.variant,
}
err := dev.SetStepMode(test.mode)
if !errors.Is(err, test.expectErr) {
t.Fatalf("expected error: %v, got: %v", test.expectErr, err)
}
})
}
}
func TestSetDecayMode(t *testing.T) {
for _, test := range []struct {
name string
variant Variant
mode DecayMode
ops []i2ctest.IO
expectErr error
}{
{
name: "success",
variant: TicT825,
mode: DecayModeMixed,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x92, 0x00}},
},
expectErr: nil,
},
{
name: "invalid decay mode",
variant: TicT825,
mode: DecayMode(0xFF),
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x94, 0xFF}},
},
expectErr: ErrInvalidSetting,
},
{
name: "unsupported decay mode",
variant: TicT825,
mode: DecayModeMixed75,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x94, 0x04}},
},
expectErr: ErrUnsupportedVariant,
},
{
name: "unsupported variant",
variant: TicT500,
mode: DecayModeMixed,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x94, 0x00}},
},
expectErr: ErrUnsupportedVariant,
},
} {
t.Run(test.name, func(t *testing.T) {
b := i2ctest.Playback{
Ops: test.ops,
DontPanic: true,
}
defer b.Close()
dev := Dev{
c: &i2c.Dev{Bus: &b, Addr: I2CAddr},
variant: test.variant,
}
err := dev.SetDecayMode(test.mode)
if !errors.Is(err, test.expectErr) {
t.Fatalf("expected error: %v, got: %v", test.expectErr, err)
}
})
}
}
func TestGetCurrentLimit(t *testing.T) {
for _, test := range []struct {
name string
variant Variant
ops []i2ctest.IO
want physic.ElectricCurrent
}{
{
name: "T500 success",
variant: TicT500,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x4A}},
{Addr: I2CAddr, R: []byte{0x09}},
},
want: 1092 * physic.MilliAmpere,
},
{
name: "T249 success",
variant: TicT249,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x4A}},
{Addr: I2CAddr, R: []byte{0x0A}},
},
want: 400 * physic.MilliAmpere,
},
{
name: "36v4 success",
variant: Tic36v4,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x4A}},
{Addr: I2CAddr, R: []byte{0x0A}},
},
want: 716 * physic.MilliAmpere,
},
{
name: "T825 success",
variant: TicT825,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x4A}},
{Addr: I2CAddr, R: []byte{0x0A}},
},
want: 320 * physic.MilliAmpere,
},
} {
t.Run(test.name, func(t *testing.T) {
b := i2ctest.Playback{
Ops: test.ops,
DontPanic: true,
}
defer b.Close()
dev := Dev{
c: &i2c.Dev{Bus: &b, Addr: I2CAddr},
variant: test.variant,
}
got, err := dev.GetCurrentLimit()
if err != nil {
t.Fatal(err)
}
if got != test.want {
t.Fatalf("wanted: %v, got: %v", test.want, got)
}
})
}
}
func TestSetCurrentLimit(t *testing.T) {
for _, test := range []struct {
name string
variant Variant
limit physic.ElectricCurrent
ops []i2ctest.IO
want int32
}{
{
name: "T500 success",
variant: TicT500,
limit: 500 * physic.MilliAmpere,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x91, 0x04}},
},
},
{
name: "36v4 success",
variant: Tic36v4,
limit: 500 * physic.MilliAmpere,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x91, 0x06}},
},
},
{
name: "36v4 lower limit",
variant: Tic36v4,
limit: 10 * physic.NanoAmpere,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x91, 0x00}},
},
},
{
name: "36v4 upper limit",
variant: Tic36v4,
limit: 10 * physic.Ampere,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0x91, 0x7F}},
},
},
} {
t.Run(test.name, func(t *testing.T) {
b := i2ctest.Playback{
Ops: test.ops,
DontPanic: true,
}
defer b.Close()
dev := Dev{
c: &i2c.Dev{Bus: &b, Addr: I2CAddr},
variant: test.variant,
}
err := dev.SetCurrentLimit(test.limit)
if err != nil {
t.Fatal(err)
}
})
}
}
func TestGetEnergized(t *testing.T) {
for _, test := range []struct {
name string
ops []i2ctest.IO
want bool
}{
{
name: "device energized",
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x01}},
{Addr: I2CAddr, R: []byte{0x01}},
},
want: true,
},
{
name: "device not energized",
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x01}},
{Addr: I2CAddr, R: []byte{0x00}},
},
want: false,
},
} {
t.Run(test.name, func(t *testing.T) {
b := i2ctest.Playback{
Ops: test.ops,
DontPanic: true,
}
defer b.Close()
dev := Dev{
c: &i2c.Dev{Bus: &b, Addr: I2CAddr},
variant: Tic36v4,
}
got, err := dev.IsEnergized()
if err != nil {
t.Fatal(err)
}
if got != test.want {
t.Fatalf("wanted: %t, got: %t", test.want, got)
}
})
}
}
func TestGetErrorsOccurred(t *testing.T) {
const want uint32 = 0xAABBCCDD
b := i2ctest.Playback{
Ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA2, 0x04}},
{Addr: I2CAddr, R: []byte{0xDD, 0xCC, 0xBB, 0xAA}},
},
DontPanic: true,
}
defer b.Close()
dev := Dev{
c: &i2c.Dev{Bus: &b, Addr: I2CAddr},
variant: Tic36v4,
}
got, err := dev.GetErrorsOccurred()
if err != nil {
t.Error(err)
}
if got != want {
t.Errorf("wanted: %d, got: %d", want, got)
}
}
func TestGetPinState(t *testing.T) {
for _, test := range []struct {
name string
pin Pin
ops []i2ctest.IO
want PinState
expectErr error
}{
{
name: "success",
pin: PinRX,
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x48}},
{Addr: I2CAddr, R: []byte{0x80}},
},
want: PinStateOutputLow,
expectErr: nil,
},
{
name: "invalid pin",
pin: Pin(0xFF),
ops: []i2ctest.IO{
{Addr: I2CAddr, W: []byte{0xA1, 0x48}},
},
expectErr: ErrInvalidSetting,
},
} {
t.Run(test.name, func(t *testing.T) {
b := i2ctest.Playback{
Ops: test.ops,
DontPanic: true,
}
defer b.Close()
dev := Dev{
c: &i2c.Dev{Bus: &b, Addr: I2CAddr},
variant: Tic36v4,
}
got, err := dev.GetPinState(test.pin)
if !errors.Is(err, test.expectErr) {
t.Fatalf("expected error: %v, got: %v", test.expectErr, err)
}
if got != test.want {
t.Fatalf("wanted: %d, got: %d", test.want, got)
}
})
}
}