mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-07-26 02:28:41 +00:00
* first commit: add HAL and uc8151 driver demo * unexport drivers.PinOutput/Input HAL * fix non-tinygo pin config build * change of heart * docs: corrected some comments that were not changed at the same time as recent renaming
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
package legacy
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"tinygo.org/x/drivers/internal/pin"
|
||||
)
|
||||
|
||||
// The pingconfig group of files serve to abstract away
|
||||
// pin configuration calls on the machine.Pin type.
|
||||
// It was observed this way of developing drivers was
|
||||
// non-portable and unusable on "big" Go projects so
|
||||
// future projects should NOT configure pins in driver code.
|
||||
// Users must configure pins before passing them as arguments
|
||||
// to drivers.
|
||||
|
||||
// ConfigurePinOut is a legacy function used to configure pins as outputs.
|
||||
//
|
||||
// Deprecated: Do not configure pins in drivers.
|
||||
// This is a legacy feature and should only be used by drivers that
|
||||
// previously configured pins in initialization to avoid breaking users.
|
||||
func ConfigurePinOut(po pin.Output) {
|
||||
configurePinOut(po)
|
||||
}
|
||||
|
||||
// ConfigurePinInput is a legacy function used to configure pins as inputs.
|
||||
//
|
||||
// Deprecated: Do not configure pins in drivers.
|
||||
// This is a legacy feature and should only be used by drivers that
|
||||
// previously configured pins in initialization to avoid breaking users.
|
||||
func ConfigurePinInputPulldown(pi pin.Input) {
|
||||
configurePinInputPulldown(pi)
|
||||
}
|
||||
|
||||
// ConfigurePinInput is a legacy function used to configure pins as inputs.
|
||||
//
|
||||
// Deprecated: Do not configure pins in drivers.
|
||||
// This is a legacy feature and should only be used by drivers that
|
||||
// previously configured pins in initialization to avoid breaking users.
|
||||
func ConfigurePinInput(pi pin.Input) {
|
||||
configurePinInput(pi)
|
||||
}
|
||||
|
||||
// ConfigurePinInput is a legacy function used to configure pins as inputs.
|
||||
//
|
||||
// Deprecated: Do not configure pins in drivers.
|
||||
// This is a legacy feature and should only be used by drivers that
|
||||
// previously configured pins in initialization to avoid breaking users.
|
||||
func ConfigurePinInputPullup(pi pin.Input) {
|
||||
configurePinInputPullup(pi)
|
||||
}
|
||||
|
||||
// PinIsNoPin returns true if the argument is a machine.Pin type and is the machine.NoPin predeclared type.
|
||||
//
|
||||
// Deprecated: Drivers do not require pin knowledge from now on.
|
||||
func PinIsNoPin(pin any) bool {
|
||||
return pinIsNoPin(pin)
|
||||
}
|
||||
|
||||
var (
|
||||
ErrConfigBeforeInstantiated = errors.New("device must be instantiated with New before calling Configure method")
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
//go:build !tinygo
|
||||
|
||||
package legacy
|
||||
|
||||
import "tinygo.org/x/drivers/internal/pin"
|
||||
|
||||
// This file compiles for non-tinygo builds
|
||||
// for use with "big" or "upstream" Go where
|
||||
// there is no machine package.
|
||||
|
||||
func configurePinOut(p pin.Output) {}
|
||||
func configurePinInput(p pin.Input) {}
|
||||
func configurePinInputPulldown(p pin.Input) {}
|
||||
func configurePinInputPullup(p pin.Input) {}
|
||||
func pinIsNoPin(a any) bool { return false }
|
||||
@@ -0,0 +1,10 @@
|
||||
//go:build baremetal && fe310
|
||||
|
||||
package legacy
|
||||
|
||||
import "machine"
|
||||
|
||||
const (
|
||||
pulldown = machine.PinInput
|
||||
pullup = machine.PinInput
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
//go:build baremetal && !fe310
|
||||
|
||||
package legacy
|
||||
|
||||
import "machine"
|
||||
|
||||
// If you are getting a build error here you then we missed adding
|
||||
// your CPU build tag to the list of CPUs that do not have pulldown/pullups.
|
||||
// Add it above and in pinhal_nopulls! You should also add a smoketest for it :)
|
||||
const (
|
||||
pulldown = machine.PinInputPulldown
|
||||
pullup = machine.PinInputPullup
|
||||
)
|
||||
@@ -0,0 +1,37 @@
|
||||
//go:build baremetal
|
||||
|
||||
package legacy
|
||||
|
||||
import (
|
||||
"machine"
|
||||
|
||||
"tinygo.org/x/drivers/internal/pin"
|
||||
)
|
||||
|
||||
func configurePinOut(po pin.Output) {
|
||||
configurePin(po, machine.PinOutput)
|
||||
}
|
||||
|
||||
func configurePinInputPulldown(pi pin.Input) {
|
||||
configurePin(pi, pulldown) // some chips do not have pull down, in which case pulldown==machine.PinInput.
|
||||
}
|
||||
|
||||
func configurePinInput(pi pin.Input) {
|
||||
configurePin(pi, machine.PinInput)
|
||||
}
|
||||
|
||||
func configurePinInputPullup(pi pin.Input) {
|
||||
configurePin(pi, pullup) // some chips do not have pull up, in which case pullup==machine.PinInput.
|
||||
}
|
||||
|
||||
func pinIsNoPin(a any) bool {
|
||||
p, ok := a.(machine.Pin)
|
||||
return ok && p == machine.NoPin
|
||||
}
|
||||
|
||||
func configurePin(p any, mode machine.PinMode) {
|
||||
machinePin, ok := p.(machine.Pin)
|
||||
if ok {
|
||||
machinePin.Configure(machine.PinConfig{Mode: mode})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// package pin implements a TinyGo Pin HAL.
|
||||
// It serves to eliminate machine.Pin from driver constructors
|
||||
// so that drivers can be used in "big" Go projects where
|
||||
// there is no machine package.
|
||||
// This file contains both function and interface-style Pin HAL definitions.
|
||||
package pin
|
||||
|
||||
// OutputFunc is hardware abstraction for a pin which outputs a
|
||||
// digital signal (high or low level).
|
||||
//
|
||||
// // Code conversion demo: from machine.Pin to pin.OutputFunc
|
||||
// led := machine.LED
|
||||
// led.Configure(machine.PinConfig{Mode: machine.Output})
|
||||
// var pin pin.OutputFunc = led.Set // Going from a machine.Pin to a pin.OutputFunc
|
||||
//
|
||||
// This is an alternative to [Output] which is an interface type.
|
||||
type OutputFunc func(level bool)
|
||||
|
||||
// High sets the underlying pin's level to high. This is equivalent to calling PinOutput(true).
|
||||
func (setPin OutputFunc) High() {
|
||||
setPin(true)
|
||||
}
|
||||
|
||||
// Low sets the underlying pin's level to low. This is equivalent to calling PinOutput(false).
|
||||
func (setPin OutputFunc) Low() {
|
||||
setPin(false)
|
||||
}
|
||||
|
||||
// InputFunc is hardware abstraction for a pin which receives a
|
||||
// digital signal and reads it (high or low level).
|
||||
//
|
||||
// // Code conversion demo: from machine.Pin to pin.InputFunc
|
||||
// input := machine.LED
|
||||
// input.Configure(machine.PinConfig{Mode: machine.PinInputPulldown}) // or use machine.PinInputPullup or machine.Input
|
||||
// var pin pin.InputFunc = input.Get // Going from a machine.Pin to a pin.InputFunc
|
||||
//
|
||||
// This is an alternative to [Input] which is an interface type.
|
||||
type InputFunc func() (level bool)
|
||||
|
||||
// // Below is an example on how to define a input/output pin HAL for a
|
||||
// // pin that must switch between input and output mode:
|
||||
//
|
||||
// var pinIsOutput bool
|
||||
// var po PinOutputFunc = func(b bool) {
|
||||
// if !pinIsOutput {
|
||||
// pin.Configure(outputMode)
|
||||
// pinIsOutput = true
|
||||
// }
|
||||
// pin.Set(b)
|
||||
// }
|
||||
//
|
||||
// var pi PinInputFunc = func() bool {
|
||||
// if pinIsOutput {
|
||||
// pin.Configure(inputMode)
|
||||
// pinIsOutput = false
|
||||
// }
|
||||
// return pin.Get()
|
||||
// }
|
||||
|
||||
// Output interface represents a pin hardware abstraction layer for a pin that can output a digital signal.
|
||||
//
|
||||
// This is an alternative to [OutputFunc] abstraction which is a function type.
|
||||
type Output interface {
|
||||
Set(level bool)
|
||||
}
|
||||
|
||||
// Input interface represents a pin hardware abstraction layer for a pin that can read a digital signal.
|
||||
//
|
||||
// This is an alternative to [InputFunc] abstraction which is a function type.
|
||||
type Input interface {
|
||||
Get() (level bool)
|
||||
}
|
||||
+23
-17
@@ -8,10 +8,11 @@ package uc8151 // import "tinygo.org/x/drivers/uc8151"
|
||||
import (
|
||||
"errors"
|
||||
"image/color"
|
||||
"machine"
|
||||
"time"
|
||||
|
||||
"tinygo.org/x/drivers"
|
||||
"tinygo.org/x/drivers/internal/legacy"
|
||||
"tinygo.org/x/drivers/internal/pin"
|
||||
"tinygo.org/x/drivers/pixel"
|
||||
)
|
||||
|
||||
@@ -31,10 +32,10 @@ type Config struct {
|
||||
|
||||
type Device struct {
|
||||
bus drivers.SPI
|
||||
cs machine.Pin
|
||||
dc machine.Pin
|
||||
rst machine.Pin
|
||||
busy machine.Pin
|
||||
cs pin.OutputFunc
|
||||
dc pin.OutputFunc
|
||||
rst pin.OutputFunc
|
||||
isBusy pin.InputFunc
|
||||
width int16
|
||||
height int16
|
||||
buffer []uint8
|
||||
@@ -49,17 +50,22 @@ type Device struct {
|
||||
type Speed uint8
|
||||
|
||||
// New returns a new uc8151 driver. Pass in a fully configured SPI bus.
|
||||
func New(bus drivers.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device {
|
||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
busyPin.Configure(machine.PinConfig{Mode: machine.PinInput})
|
||||
// Pins passed in must be configured beforehand.
|
||||
func New(bus drivers.SPI, csPin, dcPin, rstPin pin.Output, busyPin pin.Input) Device {
|
||||
// For backwards compatibility.
|
||||
// This driver used to configure pins,
|
||||
// so leave in to not break users.
|
||||
// May be removed in future so try not to depend on it!
|
||||
legacy.ConfigurePinOut(csPin)
|
||||
legacy.ConfigurePinOut(dcPin)
|
||||
legacy.ConfigurePinOut(rstPin)
|
||||
legacy.ConfigurePinInput(busyPin)
|
||||
return Device{
|
||||
bus: bus,
|
||||
cs: csPin,
|
||||
dc: dcPin,
|
||||
rst: rstPin,
|
||||
busy: busyPin,
|
||||
bus: bus,
|
||||
cs: csPin.Set,
|
||||
dc: dcPin.Set,
|
||||
rst: rstPin.Set,
|
||||
isBusy: busyPin.Get,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,14 +319,14 @@ func (d *Device) ClearDisplay() {
|
||||
|
||||
// WaitUntilIdle waits until the display is ready
|
||||
func (d *Device) WaitUntilIdle() {
|
||||
for !d.busy.Get() {
|
||||
for !d.isBusy() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
// IsBusy returns the busy status of the display
|
||||
func (d *Device) IsBusy() bool {
|
||||
return d.busy.Get()
|
||||
return d.isBusy()
|
||||
}
|
||||
|
||||
// ClearBuffer sets the buffer to 0xFF (white)
|
||||
|
||||
Reference in New Issue
Block a user