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
|
@ -27,8 +27,7 @@ type Adaptor struct {
|
|||
// NewAdaptor creates a Tinkerboard Adaptor
|
||||
func NewAdaptor() *Adaptor {
|
||||
c := &Adaptor{
|
||||
name: gobot.DefaultName("Tinker Board"),
|
||||
digitalPins: make(map[int]sysfs.DigitalPin),
|
||||
name: gobot.DefaultName("Tinker Board"),
|
||||
}
|
||||
|
||||
c.setPins()
|
||||
|
@ -43,7 +42,6 @@ func (c *Adaptor) SetName(n string) { c.name = n }
|
|||
|
||||
// Connect initializes the board
|
||||
func (c *Adaptor) Connect() (err error) {
|
||||
c.pwmPins = make(map[int]*sysfs.PWMPin)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -145,6 +143,8 @@ func (c *Adaptor) GetDefaultBus() int {
|
|||
}
|
||||
|
||||
func (c *Adaptor) setPins() {
|
||||
c.digitalPins = make(map[int]sysfs.DigitalPin)
|
||||
c.pwmPins = make(map[int]*sysfs.PWMPin)
|
||||
c.pinmap = fixedPins
|
||||
}
|
||||
|
||||
|
@ -179,30 +179,42 @@ func (c *Adaptor) digitalPin(pin string, dir string) (sysfsPin sysfs.DigitalPin,
|
|||
return c.digitalPins[i], nil
|
||||
}
|
||||
|
||||
// pwmPin returns matched pwmPin for specified pin number
|
||||
func (c *Adaptor) pwmPin(pin string) (sysfsPin *sysfs.PWMPin, err error) {
|
||||
sysPin := c.pinmap[pin]
|
||||
if sysPin.pwmPin != -1 {
|
||||
if c.pwmPins[sysPin.pwmPin] == nil {
|
||||
newPin := sysfs.NewPWMPin(sysPin.pwmPin)
|
||||
if err = newPin.Export(); err != nil {
|
||||
return
|
||||
}
|
||||
if err = newPin.Enable(true); err != nil {
|
||||
return
|
||||
}
|
||||
if err = newPin.SetPeriod(10000000); err != nil {
|
||||
return
|
||||
}
|
||||
if err = newPin.InvertPolarity(false); err != nil {
|
||||
return
|
||||
}
|
||||
c.pwmPins[sysPin.pwmPin] = newPin
|
||||
}
|
||||
|
||||
sysfsPin = c.pwmPins[sysPin.pwmPin]
|
||||
return
|
||||
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")
|
||||
}
|
||||
err = errors.New("Not a PWM pin")
|
||||
return
|
||||
}
|
||||
|
||||
// pwmPin returns matched pwmPin for specified pin number
|
||||
func (c *Adaptor) pwmPin(pin string) (sysfsPin *sysfs.PWMPin, err error) {
|
||||
i, err := c.translatePwmPin(pin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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 {
|
||||
return
|
||||
}
|
||||
if err = newPin.Enable(true); err != nil {
|
||||
return
|
||||
}
|
||||
if err = newPin.SetPeriod(10000000); err != nil {
|
||||
return
|
||||
}
|
||||
if err = newPin.InvertPolarity(false); err != nil {
|
||||
return
|
||||
}
|
||||
c.pwmPins[i] = newPin
|
||||
}
|
||||
|
||||
sysfsPin = c.pwmPins[i]
|
||||
return
|
||||
}
|
||||
|
|
|
@ -20,10 +20,25 @@ var _ gpio.PwmWriter = (*Adaptor)(nil)
|
|||
var _ gpio.ServoWriter = (*Adaptor)(nil)
|
||||
var _ i2c.Connector = (*Adaptor)(nil)
|
||||
|
||||
func initTestTinkerboardAdaptor() *Adaptor {
|
||||
func initTestTinkerboardAdaptor() (*Adaptor, *sysfs.MockFilesystem) {
|
||||
a := NewAdaptor()
|
||||
a.Connect()
|
||||
return a
|
||||
fs := sysfs.NewMockFilesystem([]string{
|
||||
"/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) {
|
||||
|
@ -34,17 +49,8 @@ func TestTinkerboardAdaptorName(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTinkerboardAdaptorDigitalIO(t *testing.T) {
|
||||
a := initTestTinkerboardAdaptor()
|
||||
fs := sysfs.NewMockFilesystem([]string{
|
||||
"/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, fs := initTestTinkerboardAdaptor()
|
||||
a.Connect()
|
||||
|
||||
a.DigitalWrite("7", 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"))
|
||||
}
|
||||
|
||||
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) {
|
||||
a := initTestTinkerboardAdaptor()
|
||||
a := NewAdaptor()
|
||||
fs := sysfs.NewMockFilesystem([]string{
|
||||
"/dev/i2c-1",
|
||||
})
|
||||
|
@ -76,28 +98,26 @@ func TestTinkerboardAdaptorI2c(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTinkerboardAdaptorInvalidPWMPin(t *testing.T) {
|
||||
a := initTestTinkerboardAdaptor()
|
||||
a, _ := initTestTinkerboardAdaptor()
|
||||
a.Connect()
|
||||
|
||||
err := a.PwmWrite("666", 42)
|
||||
gobottest.Refute(t, err, nil)
|
||||
|
||||
err = a.ServoWrite("666", 120)
|
||||
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) {
|
||||
a := 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)
|
||||
a, fs := initTestTinkerboardAdaptor()
|
||||
|
||||
err := a.PwmWrite("PWM0", 100)
|
||||
err := a.PwmWrite("33", 100)
|
||||
gobottest.Assert(t, err, nil)
|
||||
|
||||
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/polarity"].Contents, "normal")
|
||||
|
||||
err = a.ServoWrite("PWM0", 0)
|
||||
err = a.ServoWrite("33", 0)
|
||||
gobottest.Assert(t, err, nil)
|
||||
|
||||
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, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "2000000")
|
||||
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) {
|
||||
a := initTestTinkerboardAdaptor()
|
||||
a, _ := initTestTinkerboardAdaptor()
|
||||
gobottest.Assert(t, a.GetDefaultBus(), 1)
|
||||
}
|
||||
|
||||
func TestTinkerboardGetConnectionInvalidBus(t *testing.T) {
|
||||
a := initTestTinkerboardAdaptor()
|
||||
a, _ := initTestTinkerboardAdaptor()
|
||||
_, err := a.GetConnection(0x01, 99)
|
||||
gobottest.Assert(t, err, errors.New("Bus number 99 out of range"))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue