-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rock64: introduce adaptor for PINE64-ROCK64
- Loading branch information
1 parent
4e9c832
commit 2b2a951
Showing
7 changed files
with
443 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//go:build example | ||
// +build example | ||
|
||
// | ||
// Do not build by default. | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"gobot.io/x/gobot/v2" | ||
"gobot.io/x/gobot/v2/drivers/gpio" | ||
"gobot.io/x/gobot/v2/platforms/adaptors" | ||
"gobot.io/x/gobot/v2/platforms/pine64/rock64" | ||
) | ||
|
||
// Wiring | ||
// PWR ROCK64: 1, P5_1 (+3.3V, VCC); 2, 4, P5_2 (+5V, VDD); 6, 9, 14, 20, P5_7, P5_8, P5_15, P5_16 (GND) | ||
// GPIO ROCK64: second header P5+BUS pin 3 is input, pin 4 is normal output, pin 5 is inverted output | ||
// Button: the input pin is wired with a button to GND, the internal pull up resistor is used | ||
// LED's: the output pins are wired to the cathode of the LED, the anode is wired with a resistor (70-130Ohm for 20mA) | ||
// to VCC | ||
// Expected behavior: always one LED is on, the other in opposite state, if button is pressed for >2 seconds the state | ||
// changes | ||
func main() { | ||
const ( | ||
inPinNum = "P5_3" | ||
outPinNum = "P5_4" | ||
outPinInvertedNum = "P5_5" | ||
debounceTime = 2 * time.Second | ||
) | ||
// note: WithGpiosOpenDrain() is optional, if using WithGpiosOpenSource() the LED's will not light up | ||
board := rock64.NewAdaptor(adaptors.WithGpiosActiveLow(outPinInvertedNum), | ||
adaptors.WithGpiosOpenDrain(outPinNum, outPinInvertedNum), | ||
adaptors.WithGpiosPullUp(inPinNum), | ||
adaptors.WithGpioDebounce(inPinNum, debounceTime)) | ||
|
||
inPin := gpio.NewDirectPinDriver(board, inPinNum) | ||
outPin := gpio.NewDirectPinDriver(board, outPinNum) | ||
outPinInverted := gpio.NewDirectPinDriver(board, outPinInvertedNum) | ||
|
||
work := func() { | ||
level := byte(1) | ||
|
||
gobot.Every(500*time.Millisecond, func() { | ||
read, err := inPin.DigitalRead() | ||
fmt.Printf("pin %s state is %d\n", inPinNum, read) | ||
if err != nil { | ||
fmt.Println(err) | ||
if level == 1 { | ||
level = 0 | ||
} else { | ||
level = 1 | ||
} | ||
} else { | ||
level = byte(read) | ||
} | ||
|
||
err = outPin.DigitalWrite(level) | ||
fmt.Printf("pin %s is now %d\n", outPinNum, level) | ||
if err != nil { | ||
fmt.Println(err) | ||
} | ||
|
||
err = outPinInverted.DigitalWrite(level) | ||
fmt.Printf("pin %s is now not %d\n", outPinInvertedNum, level) | ||
if err != nil { | ||
fmt.Println(err) | ||
} | ||
}) | ||
} | ||
|
||
robot := gobot.NewRobot("pinBot", | ||
[]gobot.Connection{board}, | ||
[]gobot.Device{inPin, outPin, outPinInverted}, | ||
work, | ||
) | ||
|
||
if err := robot.Start(); err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
//go:build example | ||
// +build example | ||
|
||
// | ||
// Do not build by default. | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"gobot.io/x/gobot/v2" | ||
"gobot.io/x/gobot/v2/drivers/i2c" | ||
"gobot.io/x/gobot/v2/platforms/pine64/rock64" | ||
) | ||
|
||
func main() { | ||
// Wiring | ||
// PWR ROCK64: 1, P5_1 (+3.3V, VCC), 6, 9, 14, 20, P5_7, P5_8, P5_15, P5_16 (GND) | ||
// I2C0 ROCK64: 3 (SDA), 5 (SCL) | ||
// I2C1 ROCK64: 27 (SDA), 28 (SCL) | ||
// YL-40 module: wire AOUT --> AIN2 for this example | ||
// | ||
// Note: temperature measurement is often buggy, because sensor is not properly grounded | ||
// fix it by soldering a small bridge to the adjacent ground pin of brightness sensor | ||
board := rock64.NewAdaptor() | ||
yl := i2c.NewYL40Driver(board, i2c.WithBus(1)) | ||
|
||
work := func() { | ||
// the LED light is visible above ~1.7V | ||
writeVal, _ := yl.AOUT() | ||
|
||
gobot.Every(1000*time.Millisecond, func() { | ||
if err := yl.Write(writeVal); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
log.Printf(" %.1f V written", writeVal) | ||
writeVal = writeVal + 0.1 | ||
if writeVal > 3.3 { | ||
writeVal = 0 | ||
} | ||
} | ||
|
||
if brightness, err := yl.ReadBrightness(); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
log.Printf("Brightness: %.0f [0..1000]", brightness) | ||
} | ||
|
||
if temperature, err := yl.ReadTemperature(); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
log.Printf("Temperature: %.1f °C", temperature) | ||
} | ||
|
||
if ain2, err := yl.ReadAIN2(); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
log.Printf("Read back AOUT: %.1f [0..3.3]", ain2) | ||
} | ||
|
||
if potiState, err := yl.ReadPotentiometer(); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
log.Printf("Resistor: %.0f %% [-100..+100]", potiState) | ||
} | ||
}) | ||
} | ||
|
||
robot := gobot.NewRobot("yl40Bot", | ||
[]gobot.Connection{board}, | ||
[]gobot.Device{yl}, | ||
work, | ||
) | ||
|
||
if err := robot.Start(); err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Copyright (c) 2025 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Pine ROCK64 | ||
|
||
The Pine ROCK64 is a single board SoC computer based on the Rockchip RK3328 arm64 processor. It has built-in GPIO and | ||
I2C interfaces. SPI is most likely not usable, because access of SPI FLASH 128M memory chip use it. | ||
|
||
For more info about the Pine ROCK64, go to [https://pine64.org/documentation/ROCK64/](https://pine64.org/documentation/ROCK64/). | ||
|
||
## How to Install | ||
|
||
Please refer to the main [README.md](https://github.com/hybridgroup/gobot/blob/release/README.md) | ||
|
||
Tested OS: | ||
|
||
* [armbian](https://www.armbian.com/rock64/) with Debian | ||
|
||
## Configuration steps for the OS | ||
|
||
### System access and configuration basics | ||
|
||
```sh | ||
ssh <user>@192.168.1.xxx | ||
``` | ||
|
||
### Enabling hardware drivers | ||
|
||
Not all drivers are enabled by default. You can have a look at the configuration file, to find out what is enabled at | ||
your system: | ||
|
||
```sh | ||
cat /boot/armbianEnv.txt | ||
``` | ||
|
||
```sh | ||
sudo apt install armbian-config | ||
sudo armbian-config | ||
``` | ||
|
||
## 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 := rock64.NewAdaptor() | ||
led := gpio.NewLedDriver(r, "7") | ||
``` | ||
|
||
## How to Connect | ||
|
||
### Compiling | ||
|
||
Compile your Gobot program on your workstation like this: | ||
|
||
```sh | ||
GOARCH=arm64 GOOS=linux go build -o output/ examples/rock64_blink.go | ||
``` | ||
|
||
Once you have compiled your code, you can upload your program and execute it on the board from your workstation | ||
using the `scp` and `ssh` commands like this: | ||
|
||
```sh | ||
scp rock64_blink <user>@192.168.1.xxx:~ | ||
ssh -t <user>@192.168.1.xxx "./rock64_blink" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package rock64 | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
|
||
multierror "github.com/hashicorp/go-multierror" | ||
|
||
"gobot.io/x/gobot/v2" | ||
"gobot.io/x/gobot/v2/platforms/adaptors" | ||
"gobot.io/x/gobot/v2/system" | ||
) | ||
|
||
const ( | ||
defaultI2cBusNumber = 1 | ||
|
||
defaultSpiBusNumber = 0 | ||
defaultSpiChipNumber = 0 | ||
defaultSpiMode = 0 | ||
defaultSpiBitsNumber = 8 | ||
defaultSpiMaxSpeed = 500000 | ||
) | ||
|
||
// Adaptor represents a Gobot Adaptor for the PINE64 ROCK64 | ||
type Adaptor struct { | ||
name string | ||
sys *system.Accesser // used for unit tests only | ||
mutex *sync.Mutex | ||
*adaptors.AnalogPinsAdaptor | ||
*adaptors.DigitalPinsAdaptor | ||
*adaptors.I2cBusAdaptor | ||
*adaptors.SpiBusAdaptor | ||
*adaptors.OneWireBusAdaptor | ||
} | ||
|
||
// NewAdaptor creates a ROCK64 Adaptor | ||
// | ||
// Optional parameters: | ||
// | ||
// adaptors.WithGpioSysfsAccess(): use legacy sysfs driver instead of default character device driver | ||
// adaptors.WithSpiGpioAccess(sclk, ncs, sdo, sdi): use GPIO's instead of /dev/spidev#.# | ||
// adaptors.WithGpiosActiveLow(pin's): invert the pin behavior | ||
// adaptors.WithGpiosPullUp/Down(pin's): sets the internal pull resistor | ||
// | ||
// Optional parameters for PWM, see [adaptors.NewPWMPinsAdaptor] | ||
func NewAdaptor(opts ...interface{}) *Adaptor { | ||
sys := system.NewAccesser() | ||
a := &Adaptor{ | ||
name: gobot.DefaultName("ROCK64"), | ||
sys: sys, | ||
mutex: &sync.Mutex{}, | ||
} | ||
|
||
var digitalPinsOpts []adaptors.DigitalPinsOptionApplier | ||
var spiBusOpts []adaptors.SpiBusOptionApplier | ||
for _, opt := range opts { | ||
switch o := opt.(type) { | ||
case adaptors.DigitalPinsOptionApplier: | ||
digitalPinsOpts = append(digitalPinsOpts, o) | ||
case adaptors.SpiBusOptionApplier: | ||
spiBusOpts = append(spiBusOpts, o) | ||
default: | ||
panic(fmt.Sprintf("'%s' can not be applied on adaptor '%s'", opt, a.name)) | ||
} | ||
} | ||
|
||
analogPinTranslator := adaptors.NewAnalogPinTranslator(sys, analogPinDefinitions) | ||
digitalPinTranslator := adaptors.NewDigitalPinTranslator(sys, gpioPinDefinitions) | ||
// Valid bus numbers are [0,1] which corresponds to /dev/i2c-0, /dev/i2c-1. | ||
// We don't support "/dev/i2c-4 DesignWare HDMI". | ||
i2cBusNumberValidator := adaptors.NewBusNumberValidator([]int{0, 1}) | ||
// Valid bus number is 0 which corresponds to /dev/spidev0.x | ||
// x is the chip number <255 | ||
spiBusNumberValidator := adaptors.NewBusNumberValidator([]int{0}) | ||
|
||
a.AnalogPinsAdaptor = adaptors.NewAnalogPinsAdaptor(sys, analogPinTranslator.Translate) | ||
a.DigitalPinsAdaptor = adaptors.NewDigitalPinsAdaptor(sys, digitalPinTranslator.Translate, digitalPinsOpts...) | ||
a.I2cBusAdaptor = adaptors.NewI2cBusAdaptor(sys, i2cBusNumberValidator.Validate, defaultI2cBusNumber) | ||
a.SpiBusAdaptor = adaptors.NewSpiBusAdaptor(sys, spiBusNumberValidator.Validate, defaultSpiBusNumber, | ||
defaultSpiChipNumber, defaultSpiMode, defaultSpiBitsNumber, defaultSpiMaxSpeed, a.DigitalPinsAdaptor, spiBusOpts...) | ||
a.OneWireBusAdaptor = adaptors.NewOneWireBusAdaptor(sys) | ||
|
||
return a | ||
} | ||
|
||
// Name returns the name of the Adaptor | ||
func (a *Adaptor) Name() string { return a.name } | ||
|
||
// SetName sets the name of the Adaptor | ||
func (a *Adaptor) SetName(n string) { a.name = n } | ||
|
||
// Connect create new connection to board and pins. | ||
func (a *Adaptor) Connect() error { | ||
a.mutex.Lock() | ||
defer a.mutex.Unlock() | ||
|
||
if err := a.OneWireBusAdaptor.Connect(); err != nil { | ||
return err | ||
} | ||
|
||
if err := a.SpiBusAdaptor.Connect(); err != nil { | ||
return err | ||
} | ||
|
||
if err := a.I2cBusAdaptor.Connect(); err != nil { | ||
return err | ||
} | ||
|
||
if err := a.AnalogPinsAdaptor.Connect(); err != nil { | ||
return err | ||
} | ||
|
||
return a.DigitalPinsAdaptor.Connect() | ||
} | ||
|
||
// Finalize closes connection to board, pins and bus | ||
func (a *Adaptor) Finalize() error { | ||
a.mutex.Lock() | ||
defer a.mutex.Unlock() | ||
|
||
err := a.DigitalPinsAdaptor.Finalize() | ||
|
||
if e := a.AnalogPinsAdaptor.Finalize(); e != nil { | ||
err = multierror.Append(err, e) | ||
} | ||
|
||
if e := a.I2cBusAdaptor.Finalize(); e != nil { | ||
err = multierror.Append(err, e) | ||
} | ||
|
||
if e := a.SpiBusAdaptor.Finalize(); e != nil { | ||
err = multierror.Append(err, e) | ||
} | ||
|
||
if e := a.OneWireBusAdaptor.Finalize(); e != nil { | ||
err = multierror.Append(err, e) | ||
} | ||
|
||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/* | ||
Package rock64 contains the Gobot adaptor for the PINE64 ROCK64. | ||
For further information refer to the boards README: | ||
https://github.com/hybridgroup/gobot/blob/release/platforms/pine64/rock64/README.md | ||
*/ | ||
package rock64 // import "gobot.io/x/gobot/v2/platforms/rock64" |
Oops, something went wrong.