mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-05-08 19:29:16 +08:00
tinkerboard: better handling of pwm pin initialization and more test coverage
Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
parent
610747b723
commit
9919168a66
@ -28,7 +28,6 @@ type Adaptor struct {
|
|||||||
func NewAdaptor() *Adaptor {
|
func NewAdaptor() *Adaptor {
|
||||||
c := &Adaptor{
|
c := &Adaptor{
|
||||||
name: gobot.DefaultName("Tinker Board"),
|
name: gobot.DefaultName("Tinker Board"),
|
||||||
digitalPins: make(map[int]sysfs.DigitalPin),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.setPins()
|
c.setPins()
|
||||||
@ -43,7 +42,6 @@ func (c *Adaptor) SetName(n string) { c.name = n }
|
|||||||
|
|
||||||
// Connect initializes the board
|
// Connect initializes the board
|
||||||
func (c *Adaptor) Connect() (err error) {
|
func (c *Adaptor) Connect() (err error) {
|
||||||
c.pwmPins = make(map[int]*sysfs.PWMPin)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +143,8 @@ func (c *Adaptor) GetDefaultBus() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Adaptor) setPins() {
|
func (c *Adaptor) setPins() {
|
||||||
|
c.digitalPins = make(map[int]sysfs.DigitalPin)
|
||||||
|
c.pwmPins = make(map[int]*sysfs.PWMPin)
|
||||||
c.pinmap = fixedPins
|
c.pinmap = fixedPins
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,12 +179,27 @@ func (c *Adaptor) digitalPin(pin string, dir string) (sysfsPin sysfs.DigitalPin,
|
|||||||
return c.digitalPins[i], nil
|
return c.digitalPins[i], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Adaptor) translatePwmPin(pin string) (i int, err error) {
|
||||||
|
if val, ok := c.pinmap[pin]; ok {
|
||||||
|
i = val.pwmPin
|
||||||
|
} else {
|
||||||
|
err = errors.New("Not a valid pin")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// pwmPin returns matched pwmPin for specified pin number
|
// pwmPin returns matched pwmPin for specified pin number
|
||||||
func (c *Adaptor) pwmPin(pin string) (sysfsPin *sysfs.PWMPin, err error) {
|
func (c *Adaptor) pwmPin(pin string) (sysfsPin *sysfs.PWMPin, err error) {
|
||||||
sysPin := c.pinmap[pin]
|
i, err := c.translatePwmPin(pin)
|
||||||
if sysPin.pwmPin != -1 {
|
if err != nil {
|
||||||
if c.pwmPins[sysPin.pwmPin] == nil {
|
return nil, err
|
||||||
newPin := sysfs.NewPWMPin(sysPin.pwmPin)
|
}
|
||||||
|
if i == -1 {
|
||||||
|
return nil, errors.New("Not a PWM pin")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.pwmPins[i] == nil {
|
||||||
|
newPin := sysfs.NewPWMPin(i)
|
||||||
if err = newPin.Export(); err != nil {
|
if err = newPin.Export(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -197,12 +212,9 @@ func (c *Adaptor) pwmPin(pin string) (sysfsPin *sysfs.PWMPin, err error) {
|
|||||||
if err = newPin.InvertPolarity(false); err != nil {
|
if err = newPin.InvertPolarity(false); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.pwmPins[sysPin.pwmPin] = newPin
|
c.pwmPins[i] = newPin
|
||||||
}
|
}
|
||||||
|
|
||||||
sysfsPin = c.pwmPins[sysPin.pwmPin]
|
sysfsPin = c.pwmPins[i]
|
||||||
return
|
|
||||||
}
|
|
||||||
err = errors.New("Not a PWM pin")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,25 @@ var _ gpio.PwmWriter = (*Adaptor)(nil)
|
|||||||
var _ gpio.ServoWriter = (*Adaptor)(nil)
|
var _ gpio.ServoWriter = (*Adaptor)(nil)
|
||||||
var _ i2c.Connector = (*Adaptor)(nil)
|
var _ i2c.Connector = (*Adaptor)(nil)
|
||||||
|
|
||||||
func initTestTinkerboardAdaptor() *Adaptor {
|
func initTestTinkerboardAdaptor() (*Adaptor, *sysfs.MockFilesystem) {
|
||||||
a := NewAdaptor()
|
a := NewAdaptor()
|
||||||
a.Connect()
|
fs := sysfs.NewMockFilesystem([]string{
|
||||||
return a
|
"/sys/class/gpio/export",
|
||||||
|
"/sys/class/gpio/unexport",
|
||||||
|
"/sys/class/gpio/gpio17/value",
|
||||||
|
"/sys/class/gpio/gpio17/direction",
|
||||||
|
"/sys/class/gpio/gpio160/value",
|
||||||
|
"/sys/class/gpio/gpio160/direction",
|
||||||
|
"/sys/class/pwm/pwmchip0/export",
|
||||||
|
"/sys/class/pwm/pwmchip0/unexport",
|
||||||
|
"/sys/class/pwm/pwmchip0/pwm0/enable",
|
||||||
|
"/sys/class/pwm/pwmchip0/pwm0/period",
|
||||||
|
"/sys/class/pwm/pwmchip0/pwm0/duty_cycle",
|
||||||
|
"/sys/class/pwm/pwmchip0/pwm0/polarity",
|
||||||
|
})
|
||||||
|
|
||||||
|
sysfs.SetFilesystem(fs)
|
||||||
|
return a, fs
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTinkerboardAdaptorName(t *testing.T) {
|
func TestTinkerboardAdaptorName(t *testing.T) {
|
||||||
@ -34,17 +49,8 @@ func TestTinkerboardAdaptorName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTinkerboardAdaptorDigitalIO(t *testing.T) {
|
func TestTinkerboardAdaptorDigitalIO(t *testing.T) {
|
||||||
a := initTestTinkerboardAdaptor()
|
a, fs := initTestTinkerboardAdaptor()
|
||||||
fs := sysfs.NewMockFilesystem([]string{
|
a.Connect()
|
||||||
"/sys/class/gpio/export",
|
|
||||||
"/sys/class/gpio/unexport",
|
|
||||||
"/sys/class/gpio/gpio17/value",
|
|
||||||
"/sys/class/gpio/gpio17/direction",
|
|
||||||
"/sys/class/gpio/gpio160/value",
|
|
||||||
"/sys/class/gpio/gpio160/direction",
|
|
||||||
})
|
|
||||||
|
|
||||||
sysfs.SetFilesystem(fs)
|
|
||||||
|
|
||||||
a.DigitalWrite("7", 1)
|
a.DigitalWrite("7", 1)
|
||||||
gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio17/value"].Contents, "1")
|
gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio17/value"].Contents, "1")
|
||||||
@ -56,8 +62,24 @@ func TestTinkerboardAdaptorDigitalIO(t *testing.T) {
|
|||||||
gobottest.Assert(t, a.DigitalWrite("99", 1), errors.New("Not a valid pin"))
|
gobottest.Assert(t, a.DigitalWrite("99", 1), errors.New("Not a valid pin"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAdaptorDigitalWriteError(t *testing.T) {
|
||||||
|
a, fs := initTestTinkerboardAdaptor()
|
||||||
|
fs.WithWriteError = true
|
||||||
|
|
||||||
|
err := a.DigitalWrite("7", 1)
|
||||||
|
gobottest.Assert(t, err, errors.New("write error"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAdaptorDigitalReadWriteError(t *testing.T) {
|
||||||
|
a, fs := initTestTinkerboardAdaptor()
|
||||||
|
fs.WithWriteError = true
|
||||||
|
|
||||||
|
_, err := a.DigitalRead("7")
|
||||||
|
gobottest.Assert(t, err, errors.New("write error"))
|
||||||
|
}
|
||||||
|
|
||||||
func TestTinkerboardAdaptorI2c(t *testing.T) {
|
func TestTinkerboardAdaptorI2c(t *testing.T) {
|
||||||
a := initTestTinkerboardAdaptor()
|
a := NewAdaptor()
|
||||||
fs := sysfs.NewMockFilesystem([]string{
|
fs := sysfs.NewMockFilesystem([]string{
|
||||||
"/dev/i2c-1",
|
"/dev/i2c-1",
|
||||||
})
|
})
|
||||||
@ -76,28 +98,26 @@ func TestTinkerboardAdaptorI2c(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTinkerboardAdaptorInvalidPWMPin(t *testing.T) {
|
func TestTinkerboardAdaptorInvalidPWMPin(t *testing.T) {
|
||||||
a := initTestTinkerboardAdaptor()
|
a, _ := initTestTinkerboardAdaptor()
|
||||||
|
a.Connect()
|
||||||
|
|
||||||
err := a.PwmWrite("666", 42)
|
err := a.PwmWrite("666", 42)
|
||||||
gobottest.Refute(t, err, nil)
|
gobottest.Refute(t, err, nil)
|
||||||
|
|
||||||
err = a.ServoWrite("666", 120)
|
err = a.ServoWrite("666", 120)
|
||||||
gobottest.Refute(t, err, nil)
|
gobottest.Refute(t, err, nil)
|
||||||
|
|
||||||
|
err = a.PwmWrite("3", 42)
|
||||||
|
gobottest.Refute(t, err, nil)
|
||||||
|
|
||||||
|
err = a.ServoWrite("3", 120)
|
||||||
|
gobottest.Refute(t, err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTinkerboardAdaptorPWM(t *testing.T) {
|
func TestTinkerboardAdaptorPWM(t *testing.T) {
|
||||||
a := initTestTinkerboardAdaptor()
|
a, fs := initTestTinkerboardAdaptor()
|
||||||
fs := sysfs.NewMockFilesystem([]string{
|
|
||||||
"/sys/class/pwm/pwmchip0/export",
|
|
||||||
"/sys/class/pwm/pwmchip0/unexport",
|
|
||||||
"/sys/class/pwm/pwmchip0/pwm0/enable",
|
|
||||||
"/sys/class/pwm/pwmchip0/pwm0/period",
|
|
||||||
"/sys/class/pwm/pwmchip0/pwm0/duty_cycle",
|
|
||||||
"/sys/class/pwm/pwmchip0/pwm0/polarity",
|
|
||||||
})
|
|
||||||
sysfs.SetFilesystem(fs)
|
|
||||||
|
|
||||||
err := a.PwmWrite("PWM0", 100)
|
err := a.PwmWrite("33", 100)
|
||||||
gobottest.Assert(t, err, nil)
|
gobottest.Assert(t, err, nil)
|
||||||
|
|
||||||
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/export"].Contents, "0")
|
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/export"].Contents, "0")
|
||||||
@ -105,25 +125,41 @@ func TestTinkerboardAdaptorPWM(t *testing.T) {
|
|||||||
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "3921568")
|
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "3921568")
|
||||||
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/polarity"].Contents, "normal")
|
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/polarity"].Contents, "normal")
|
||||||
|
|
||||||
err = a.ServoWrite("PWM0", 0)
|
err = a.ServoWrite("33", 0)
|
||||||
gobottest.Assert(t, err, nil)
|
gobottest.Assert(t, err, nil)
|
||||||
|
|
||||||
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "500000")
|
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "500000")
|
||||||
|
|
||||||
err = a.ServoWrite("PWM0", 180)
|
err = a.ServoWrite("33", 180)
|
||||||
gobottest.Assert(t, err, nil)
|
gobottest.Assert(t, err, nil)
|
||||||
|
|
||||||
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "2000000")
|
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "2000000")
|
||||||
gobottest.Assert(t, a.Finalize(), nil)
|
gobottest.Assert(t, a.Finalize(), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTinkerboardAdaptorPwmWriteError(t *testing.T) {
|
||||||
|
a, fs := initTestTinkerboardAdaptor()
|
||||||
|
fs.WithWriteError = true
|
||||||
|
|
||||||
|
err := a.PwmWrite("33", 100)
|
||||||
|
gobottest.Assert(t, err, errors.New("write error"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTinkerboardAdaptorPwmReadError(t *testing.T) {
|
||||||
|
a, fs := initTestTinkerboardAdaptor()
|
||||||
|
fs.WithReadError = true
|
||||||
|
|
||||||
|
err := a.PwmWrite("33", 100)
|
||||||
|
gobottest.Assert(t, err, errors.New("read error"))
|
||||||
|
}
|
||||||
|
|
||||||
func TestTinkerboardDefaultBus(t *testing.T) {
|
func TestTinkerboardDefaultBus(t *testing.T) {
|
||||||
a := initTestTinkerboardAdaptor()
|
a, _ := initTestTinkerboardAdaptor()
|
||||||
gobottest.Assert(t, a.GetDefaultBus(), 1)
|
gobottest.Assert(t, a.GetDefaultBus(), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTinkerboardGetConnectionInvalidBus(t *testing.T) {
|
func TestTinkerboardGetConnectionInvalidBus(t *testing.T) {
|
||||||
a := initTestTinkerboardAdaptor()
|
a, _ := initTestTinkerboardAdaptor()
|
||||||
_, err := a.GetConnection(0x01, 99)
|
_, err := a.GetConnection(0x01, 99)
|
||||||
gobottest.Assert(t, err, errors.New("Bus number 99 out of range"))
|
gobottest.Assert(t, err, errors.New("Bus number 99 out of range"))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user