mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-04-24 13:48:49 +08:00
up2: initial work on support for UP2 board
Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
parent
3f8bd5afd4
commit
715ab299e8
@ -219,6 +219,7 @@ Gobot has a extensible system for connecting to hardware devices. The following
|
||||
- [Sphero Ollie](http://www.sphero.com/ollie) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/sphero/ollie)
|
||||
- [Sphero SPRK+](http://www.sphero.com/sprk-plus) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/sphero/sprkplus)
|
||||
- [Tinker Board](https://www.asus.com/us/Single-Board-Computer/Tinker-Board/) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/tinkerboard)
|
||||
- [UP2](http://www.up-board.org/upsquared/) <=> [Package](https://github.com/hybridgroup/gobot/tree/master/platforms/upboard/up2)
|
||||
|
||||
Support for many devices that use General Purpose Input/Output (GPIO) have
|
||||
a shared set of drivers provided using the `gobot/drivers/gpio` package:
|
||||
|
6
platforms/upboard/README.md
Normal file
6
platforms/upboard/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Upboard
|
||||
|
||||
This package contains the Gobot adaptor for the [UP2]() IoT platforms.
|
||||
|
||||
This package currently supports the following hardware:
|
||||
- UP2 (Squared)
|
13
platforms/upboard/up2/LICENSE
Normal file
13
platforms/upboard/up2/LICENSE
Normal file
@ -0,0 +1,13 @@
|
||||
Copyright (c) 2014-2017 The Hybrid Group
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
41
platforms/upboard/up2/README.md
Normal file
41
platforms/upboard/up2/README.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Tinker Board
|
||||
|
||||
The UP2 Board is a single board SoC computer based on the Intel Apollo Lake processor. It has built-in GPIO, PWM, SPI, and I2C interfaces.
|
||||
|
||||
For more info about the UP2 Board, go to [http://www.up-board.org/upsquared/](http://www.up-board.org/upsquared/).
|
||||
|
||||
## How to Install
|
||||
|
||||
We recommend updating to the latest Ubuntu when using the UP2.
|
||||
|
||||
You would normally install Go and Gobot on your workstation. Once installed, cross compile your program on your workstation, transfer the final executable to your UP2, and run the program on the UP2 as documented here.
|
||||
|
||||
```
|
||||
go get -d -u gobot.io/x/gobot/...
|
||||
```
|
||||
|
||||
## How to Use
|
||||
|
||||
The pin numbering used by your Gobot program should match the way your board is labeled right on the board itself.
|
||||
|
||||
```go
|
||||
r := up2.NewAdaptor()
|
||||
led := gpio.NewLedDriver(r, "13")
|
||||
```
|
||||
|
||||
## How to Connect
|
||||
|
||||
### Compiling
|
||||
|
||||
Compile your Gobot program on your workstation like this:
|
||||
|
||||
```bash
|
||||
$ GOARCH=386 GOOS=linux go build examples/up2_blink.go
|
||||
```
|
||||
|
||||
Once you have compiled your code, you can you can upload your program and execute it on the UP2 from your workstation using the `scp` and `ssh` commands like this:
|
||||
|
||||
```bash
|
||||
$ scp up2_blink ubuntu@192.168.1.xxx:/home/ubuntu/
|
||||
$ ssh -t ubuntu@192.168.1.xxx "./up2_blink"
|
||||
```
|
239
platforms/upboard/up2/adaptor.go
Normal file
239
platforms/upboard/up2/adaptor.go
Normal file
@ -0,0 +1,239 @@
|
||||
package up2
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"gobot.io/x/gobot"
|
||||
"gobot.io/x/gobot/drivers/i2c"
|
||||
"gobot.io/x/gobot/sysfs"
|
||||
)
|
||||
|
||||
type sysfsPin struct {
|
||||
pin int
|
||||
pwmPin int
|
||||
}
|
||||
|
||||
// Adaptor represents a Gobot Adaptor for the Upboard UP2
|
||||
type Adaptor struct {
|
||||
name string
|
||||
pinmap map[string]sysfsPin
|
||||
digitalPins map[int]*sysfs.DigitalPin
|
||||
pwmPins map[int]*sysfs.PWMPin
|
||||
i2cBuses [2]i2c.I2cDevice
|
||||
mutex *sync.Mutex
|
||||
}
|
||||
|
||||
// NewAdaptor creates a UP2 Adaptor
|
||||
func NewAdaptor() *Adaptor {
|
||||
c := &Adaptor{
|
||||
name: gobot.DefaultName("UP2"),
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
|
||||
c.setPins()
|
||||
return c
|
||||
}
|
||||
|
||||
// Name returns the name of the Adaptor
|
||||
func (c *Adaptor) Name() string { return c.name }
|
||||
|
||||
// SetName sets the name of the Adaptor
|
||||
func (c *Adaptor) SetName(n string) { c.name = n }
|
||||
|
||||
// Connect initializes the board
|
||||
func (c *Adaptor) Connect() (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Finalize closes connection to board and pins
|
||||
func (c *Adaptor) Finalize() (err error) {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
for _, pin := range c.digitalPins {
|
||||
if pin != nil {
|
||||
if e := pin.Unexport(); e != nil {
|
||||
err = multierror.Append(err, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, pin := range c.pwmPins {
|
||||
if pin != nil {
|
||||
if errs := pin.Enable(false); errs != nil {
|
||||
err = multierror.Append(err, errs)
|
||||
}
|
||||
if errs := pin.Unexport(); errs != nil {
|
||||
err = multierror.Append(err, errs)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, bus := range c.i2cBuses {
|
||||
if bus != nil {
|
||||
if e := bus.Close(); e != nil {
|
||||
err = multierror.Append(err, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DigitalRead reads digital value from the specified pin.
|
||||
func (c *Adaptor) DigitalRead(pin string) (val int, err error) {
|
||||
sysfsPin, err := c.DigitalPin(pin, sysfs.IN)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return sysfsPin.Read()
|
||||
}
|
||||
|
||||
// DigitalWrite writes digital value to the specified pin.
|
||||
func (c *Adaptor) DigitalWrite(pin string, val byte) (err error) {
|
||||
sysfsPin, err := c.DigitalPin(pin, sysfs.OUT)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sysfsPin.Write(int(val))
|
||||
}
|
||||
|
||||
// PwmWrite writes a PWM signal to the specified pin
|
||||
func (c *Adaptor) PwmWrite(pin string, val byte) (err error) {
|
||||
pwmPin, err := c.PWMPin(pin)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
period, err := pwmPin.Period()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
duty := gobot.FromScale(float64(val), 0, 255.0)
|
||||
return pwmPin.SetDutyCycle(uint32(float64(period) * duty))
|
||||
}
|
||||
|
||||
// TODO: take into account the actual period setting, not just assume default
|
||||
const pwmPeriod = 10000000
|
||||
|
||||
// ServoWrite writes a servo signal to the specified pin
|
||||
func (c *Adaptor) ServoWrite(pin string, angle byte) (err error) {
|
||||
pwmPin, err := c.PWMPin(pin)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 0.5 ms => -90
|
||||
// 1.5 ms => 0
|
||||
// 2.0 ms => 90
|
||||
const minDuty = 100 * 0.0005 * pwmPeriod
|
||||
const maxDuty = 100 * 0.0020 * pwmPeriod
|
||||
duty := uint32(gobot.ToScale(gobot.FromScale(float64(angle), 0, 180), minDuty, maxDuty))
|
||||
return pwmPin.SetDutyCycle(duty)
|
||||
}
|
||||
|
||||
// DigitalPin returns matched digitalPin for specified values
|
||||
func (c *Adaptor) DigitalPin(pin string, dir string) (sysfsPin sysfs.DigitalPinner, err error) {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
i, err := c.translatePin(pin)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if c.digitalPins[i] == nil {
|
||||
c.digitalPins[i] = sysfs.NewDigitalPin(i)
|
||||
if err = c.digitalPins[i].Export(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = c.digitalPins[i].Direction(dir); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return c.digitalPins[i], nil
|
||||
}
|
||||
|
||||
// PWMPin returns matched pwmPin for specified pin number
|
||||
func (c *Adaptor) PWMPin(pin string) (sysfsPin sysfs.PWMPinner, err error) {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
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
|
||||
}
|
||||
// Make sure pwm is disabled when setting polarity
|
||||
if err = newPin.Enable(false); err != nil {
|
||||
return
|
||||
}
|
||||
if err = newPin.InvertPolarity(false); err != nil {
|
||||
return
|
||||
}
|
||||
if err = newPin.Enable(true); err != nil {
|
||||
return
|
||||
}
|
||||
if err = newPin.SetPeriod(10000000); err != nil {
|
||||
return
|
||||
}
|
||||
c.pwmPins[i] = newPin
|
||||
}
|
||||
|
||||
sysfsPin = c.pwmPins[i]
|
||||
return
|
||||
}
|
||||
|
||||
// GetConnection returns a connection to a device on a specified bus.
|
||||
// Valid bus number is [0..1] which corresponds to /dev/i2c-0 through /dev/i2c-1.
|
||||
func (c *Adaptor) GetConnection(address int, bus int) (connection i2c.Connection, err error) {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
if (bus < 0) || (bus > 1) {
|
||||
return nil, fmt.Errorf("Bus number %d out of range", bus)
|
||||
}
|
||||
if c.i2cBuses[bus] == nil {
|
||||
c.i2cBuses[bus], err = sysfs.NewI2cDevice(fmt.Sprintf("/dev/i2c-%d", bus))
|
||||
}
|
||||
return i2c.NewConnection(c.i2cBuses[bus], address), err
|
||||
}
|
||||
|
||||
// GetDefaultBus returns the default i2c bus for this platform
|
||||
func (c *Adaptor) GetDefaultBus() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *Adaptor) setPins() {
|
||||
c.digitalPins = make(map[int]*sysfs.DigitalPin)
|
||||
c.pwmPins = make(map[int]*sysfs.PWMPin)
|
||||
c.pinmap = fixedPins
|
||||
}
|
||||
|
||||
func (c *Adaptor) translatePin(pin string) (i int, err error) {
|
||||
if val, ok := c.pinmap[pin]; ok {
|
||||
i = val.pin
|
||||
} else {
|
||||
err = errors.New("Not a valid pin")
|
||||
}
|
||||
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")
|
||||
}
|
||||
return
|
||||
}
|
192
platforms/upboard/up2/adaptor_test.go
Normal file
192
platforms/upboard/up2/adaptor_test.go
Normal file
@ -0,0 +1,192 @@
|
||||
package up2
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gobot.io/x/gobot"
|
||||
"gobot.io/x/gobot/drivers/gpio"
|
||||
"gobot.io/x/gobot/drivers/i2c"
|
||||
"gobot.io/x/gobot/gobottest"
|
||||
"gobot.io/x/gobot/sysfs"
|
||||
)
|
||||
|
||||
// make sure that this Adaptor fullfills all the required interfaces
|
||||
var _ gobot.Adaptor = (*Adaptor)(nil)
|
||||
var _ gpio.DigitalReader = (*Adaptor)(nil)
|
||||
var _ gpio.DigitalWriter = (*Adaptor)(nil)
|
||||
var _ gpio.PwmWriter = (*Adaptor)(nil)
|
||||
var _ gpio.ServoWriter = (*Adaptor)(nil)
|
||||
var _ sysfs.DigitalPinnerProvider = (*Adaptor)(nil)
|
||||
var _ sysfs.PWMPinnerProvider = (*Adaptor)(nil)
|
||||
var _ i2c.Connector = (*Adaptor)(nil)
|
||||
|
||||
func initTestUP2Adaptor() (*Adaptor, *sysfs.MockFilesystem) {
|
||||
a := NewAdaptor()
|
||||
fs := sysfs.NewMockFilesystem([]string{
|
||||
"/sys/class/gpio/export",
|
||||
"/sys/class/gpio/unexport",
|
||||
"/sys/class/gpio/gpio462/value",
|
||||
"/sys/class/gpio/gpio462/direction",
|
||||
"/sys/class/gpio/gpio432/value",
|
||||
"/sys/class/gpio/gpio432/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 TestUP2AdaptorName(t *testing.T) {
|
||||
a := NewAdaptor()
|
||||
gobottest.Assert(t, strings.HasPrefix(a.Name(), "UP2"), true)
|
||||
a.SetName("NewName")
|
||||
gobottest.Assert(t, a.Name(), "NewName")
|
||||
}
|
||||
|
||||
func TestUP2AdaptorDigitalIO(t *testing.T) {
|
||||
a, fs := initTestUP2Adaptor()
|
||||
a.Connect()
|
||||
|
||||
a.DigitalWrite("7", 1)
|
||||
gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio462/value"].Contents, "1")
|
||||
|
||||
fs.Files["/sys/class/gpio/gpio432/value"].Contents = "1"
|
||||
i, _ := a.DigitalRead("13")
|
||||
gobottest.Assert(t, i, 1)
|
||||
|
||||
gobottest.Assert(t, a.DigitalWrite("99", 1), errors.New("Not a valid pin"))
|
||||
gobottest.Assert(t, a.Finalize(), nil)
|
||||
}
|
||||
|
||||
func TestAdaptorDigitalWriteError(t *testing.T) {
|
||||
a, fs := initTestUP2Adaptor()
|
||||
fs.WithWriteError = true
|
||||
|
||||
err := a.DigitalWrite("7", 1)
|
||||
gobottest.Assert(t, err, errors.New("write error"))
|
||||
}
|
||||
|
||||
func TestAdaptorDigitalReadWriteError(t *testing.T) {
|
||||
a, fs := initTestUP2Adaptor()
|
||||
fs.WithWriteError = true
|
||||
|
||||
_, err := a.DigitalRead("7")
|
||||
gobottest.Assert(t, err, errors.New("write error"))
|
||||
}
|
||||
|
||||
func TestUP2AdaptorI2c(t *testing.T) {
|
||||
a := NewAdaptor()
|
||||
fs := sysfs.NewMockFilesystem([]string{
|
||||
"/dev/i2c-0",
|
||||
})
|
||||
sysfs.SetFilesystem(fs)
|
||||
sysfs.SetSyscall(&sysfs.MockSyscall{})
|
||||
|
||||
con, err := a.GetConnection(0xff, 0)
|
||||
gobottest.Assert(t, err, nil)
|
||||
|
||||
con.Write([]byte{0x00, 0x01})
|
||||
data := []byte{42, 42}
|
||||
con.Read(data)
|
||||
gobottest.Assert(t, data, []byte{0x00, 0x01})
|
||||
|
||||
gobottest.Assert(t, a.Finalize(), nil)
|
||||
}
|
||||
|
||||
func TestUP2AdaptorInvalidPWMPin(t *testing.T) {
|
||||
a, _ := initTestUP2Adaptor()
|
||||
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 TestUP2AdaptorPWM(t *testing.T) {
|
||||
a, fs := initTestUP2Adaptor()
|
||||
|
||||
err := a.PwmWrite("32", 100)
|
||||
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/pwm0/enable"].Contents, "1")
|
||||
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("32", 0)
|
||||
gobottest.Assert(t, err, nil)
|
||||
|
||||
gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "500000")
|
||||
|
||||
err = a.ServoWrite("32", 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 TestUP2AdaptorPwmWriteError(t *testing.T) {
|
||||
a, fs := initTestUP2Adaptor()
|
||||
fs.WithWriteError = true
|
||||
|
||||
err := a.PwmWrite("32", 100)
|
||||
gobottest.Assert(t, err, errors.New("write error"))
|
||||
}
|
||||
|
||||
func TestUP2AdaptorPwmReadError(t *testing.T) {
|
||||
a, fs := initTestUP2Adaptor()
|
||||
fs.WithReadError = true
|
||||
|
||||
err := a.PwmWrite("32", 100)
|
||||
gobottest.Assert(t, err, errors.New("read error"))
|
||||
}
|
||||
|
||||
func TestUP2DefaultBus(t *testing.T) {
|
||||
a, _ := initTestUP2Adaptor()
|
||||
gobottest.Assert(t, a.GetDefaultBus(), 0)
|
||||
}
|
||||
|
||||
func TestUP2GetConnectionInvalidBus(t *testing.T) {
|
||||
a, _ := initTestUP2Adaptor()
|
||||
_, err := a.GetConnection(0x01, 99)
|
||||
gobottest.Assert(t, err, errors.New("Bus number 99 out of range"))
|
||||
}
|
||||
|
||||
func TestUP2FinalizeErrorAfterGPIO(t *testing.T) {
|
||||
a, fs := initTestUP2Adaptor()
|
||||
|
||||
gobottest.Assert(t, a.Connect(), nil)
|
||||
gobottest.Assert(t, a.DigitalWrite("7", 1), nil)
|
||||
|
||||
fs.WithWriteError = true
|
||||
|
||||
err := a.Finalize()
|
||||
gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true)
|
||||
}
|
||||
|
||||
func TestUP2FinalizeErrorAfterPWM(t *testing.T) {
|
||||
a, fs := initTestUP2Adaptor()
|
||||
|
||||
gobottest.Assert(t, a.Connect(), nil)
|
||||
gobottest.Assert(t, a.PwmWrite("32", 1), nil)
|
||||
|
||||
fs.WithWriteError = true
|
||||
|
||||
err := a.Finalize()
|
||||
gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true)
|
||||
}
|
7
platforms/upboard/up2/doc.go
Normal file
7
platforms/upboard/up2/doc.go
Normal file
@ -0,0 +1,7 @@
|
||||
/*
|
||||
Package up2 contains the Gobot adaptor for the Upboard UP2.
|
||||
|
||||
For further information refer to the UP2 README:
|
||||
https://github.com/hybridgroup/gobot/blob/master/platforms/upboard/up2/README.md
|
||||
*/
|
||||
package up2 // import "gobot.io/x/gobot/platforms/upboard/up2"
|
48
platforms/upboard/up2/pin_map.go
Normal file
48
platforms/upboard/up2/pin_map.go
Normal file
@ -0,0 +1,48 @@
|
||||
package up2
|
||||
|
||||
var fixedPins = map[string]sysfsPin{
|
||||
"7": {
|
||||
pin: 462, // GPIO4
|
||||
pwmPin: -1,
|
||||
},
|
||||
"13": {
|
||||
pin: 432, // GPIO27
|
||||
pwmPin: -1,
|
||||
},
|
||||
"15": {
|
||||
pin: 431, // GPIO22
|
||||
pwmPin: -1,
|
||||
},
|
||||
"16": {
|
||||
pin: 471, // PWM3
|
||||
pwmPin: 3,
|
||||
},
|
||||
"18": {
|
||||
pin: 405, // GPIO24
|
||||
pwmPin: -1,
|
||||
},
|
||||
"22": {
|
||||
pin: 402, // GPIO25
|
||||
pwmPin: -1,
|
||||
},
|
||||
"29": {
|
||||
pin: 430, // GPIO5
|
||||
pwmPin: -1,
|
||||
},
|
||||
"31": {
|
||||
pin: 404, // GPIO6
|
||||
pwmPin: -1,
|
||||
},
|
||||
"32": {
|
||||
pin: 468, // PWM0
|
||||
pwmPin: 0,
|
||||
},
|
||||
"33": {
|
||||
pin: 469, // PWM1
|
||||
pwmPin: 1,
|
||||
},
|
||||
"37": {
|
||||
pin: 403, // GPIO26
|
||||
pwmPin: -1,
|
||||
},
|
||||
}
|
10
platforms/upboard/upboard.go
Normal file
10
platforms/upboard/upboard.go
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
Package upboard contains Gobot adaptors for the Upboard SoC boards.
|
||||
|
||||
This package currently supports the following hardware:
|
||||
- UP2 (Squared)
|
||||
|
||||
For further information refer to the Upboard README:
|
||||
https://gobot.io/x/gobot/blob/master/platforms/upboard/README.md
|
||||
*/
|
||||
package upboard
|
Loading…
x
Reference in New Issue
Block a user