Replace Safe functions with legacy.PinOutput

This commit is contained in:
Yurii Soldak
2025-09-21 10:04:20 +02:00
parent c6d83b783f
commit 453ff96a66
16 changed files with 112 additions and 108 deletions
+2 -1
View File
@@ -4,6 +4,7 @@ import (
"time"
"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy"
)
// DeviceSPI is the SPI interface to a BMI160 accelerometer/gyroscope. There is
@@ -23,7 +24,7 @@ type DeviceSPI struct {
// using this device.
func NewSPI(csb drivers.PinOutput, spi drivers.SPI) *DeviceSPI {
return &DeviceSPI{
CSB: drivers.SafePinOutput(csb), // chip select
CSB: legacy.PinOutput(csb), // chip select
Bus: spi,
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ type Device struct {
// New returns a new buzzer driver given which pin to use
func New(pin drivers.PinOutput) Device {
return Device{
set: drivers.SafePinOutput(pin).Set,
set: pin.Set,
High: false,
BPM: 96.0,
}
+2 -4
View File
@@ -45,9 +45,7 @@ type device struct {
func (t *device) ReadMeasurements() error {
// initial waiting
state := powerUp(t.pin)
defer func() {
t.pin.Set(state)
}()
defer t.pin.Set(state)
err := t.read()
if err == nil {
t.initialized = true
@@ -213,7 +211,7 @@ func waitForDataTransmission(p drivers.PinInput) error {
func NewDummyDevice(pin drivers.Pin, deviceType DeviceType) DummyDevice {
pin.Set(true)
return &device{
pin: drivers.SafePin(pin),
pin: pin,
measurements: deviceType,
initialized: false,
temperature: 0,
+2 -2
View File
@@ -129,7 +129,7 @@ func New(pin drivers.Pin, deviceType DeviceType) Device {
pin.Set(true)
return &managedDevice{
t: device{
pin: drivers.SafePin(pin),
pin: pin,
measurements: deviceType,
initialized: false,
},
@@ -146,7 +146,7 @@ func NewWithPolicy(pin drivers.Pin, deviceType DeviceType, updatePolicy UpdatePo
pin.Set(true)
result := &managedDevice{
t: device{
pin: drivers.SafePin(pin),
pin: pin,
measurements: deviceType,
initialized: false,
},
+5 -1
View File
@@ -1,14 +1,18 @@
//go:build baremetal && tinygo
package main
import (
"fmt"
"machine"
"time"
"tinygo.org/x/drivers/dht"
"tinygo.org/x/drivers/tinygo"
)
func main() {
pin := machine.D6
pin := tinygo.New(machine.D6)
dhtSensor := dht.New(pin, dht.DHT11)
for {
temp, hum, err := dhtSensor.Measurements()
+4 -1
View File
@@ -5,10 +5,13 @@ import (
"time"
"tinygo.org/x/drivers/hcsr04"
"tinygo.org/x/drivers/tinygo"
)
func main() {
sensor := hcsr04.New(machine.D10, machine.D9)
trigger := tinygo.New(machine.D10) // automatically configures pin as output
echo := tinygo.New(machine.D9) // automatically configures pin as input
sensor := hcsr04.New(trigger, echo)
sensor.Configure()
println("Ultrasonic starts")
+11 -10
View File
@@ -5,20 +5,22 @@
package hcsr04
import (
"machine"
"time"
"tinygo.org/x/drivers"
)
const TIMEOUT = 23324 // max sensing distance (4m)
// Device holds the pins
type Device struct {
trigger machine.Pin
echo machine.Pin
trigger drivers.PinOutput
echo drivers.PinInput
}
// New returns a new ultrasonic driver given 2 pins
func New(trigger, echo machine.Pin) Device {
// New returns a new ultrasonic driver given 2 pins.
// Pins must be configured as output (trigger) and input (echo).
func New(trigger drivers.PinOutput, echo drivers.PinInput) Device {
return Device{
trigger: trigger,
echo: echo,
@@ -27,8 +29,7 @@ func New(trigger, echo machine.Pin) Device {
// Configure configures the pins of the Device
func (d *Device) Configure() {
d.trigger.Configure(machine.PinConfig{Mode: machine.PinOutput})
d.echo.Configure(machine.PinConfig{Mode: machine.PinInput})
// no-op, left for API compatibility
}
// ReadDistance returns the distance of the object in mm
@@ -45,11 +46,11 @@ func (d *Device) ReadDistance() int32 {
// ReadPulse returns the time of the pulse (roundtrip) in microseconds
func (d *Device) ReadPulse() int32 {
t := time.Now()
d.trigger.Low()
d.trigger.Set(false)
time.Sleep(2 * time.Microsecond)
d.trigger.High()
d.trigger.Set(true)
time.Sleep(10 * time.Microsecond)
d.trigger.Low()
d.trigger.Set(false)
i := uint8(0)
for {
if d.echo.Get() {
+9
View File
@@ -0,0 +1,9 @@
//go:build !(baremetal && tinygo)
package legacy
import "tinygo.org/x/drivers"
func PinOutput(pin drivers.PinOutput) drivers.PinOutput {
return pin
}
+16
View File
@@ -0,0 +1,16 @@
//go:build baremetal && tinygo
package legacy
import (
"machine"
"tinygo.org/x/drivers"
)
func PinOutput(pin drivers.PinOutput) drivers.PinOutput {
if p, ok := pin.(machine.Pin); ok {
p.Configure(machine.PinConfig{Mode: machine.PinOutput})
}
return pin
}
+10 -6
View File
@@ -4,13 +4,17 @@ package drivers
// allowing the use of different hardware or libraries without changing driver code.
//
// Note, pin mode functionality is not part of the Pin interface.
// Implementations must ensure correct pin mode is set when Get or Set methods are called.
// Client code is responsible for configuring pin modes correctly.
// This can be done either before passing the pin to a driver constructor
// or by ensuring correct pin mode is set when Get or Set methods are called.
// See rpio package for an example of a pin implementation that does this.
//
// Drivers must use SafePin(), SafePinInput() and SafePinOutput() wrappers in constructors.
// The client code can pass either machine.Pin or a custom implementation of the Pin interface.
// Wrappers for TinyGo's machine.Pin are provided in pin_tinygo.go.
// It's custom implementation's responsibility to configure the pin modes correctly as
// Wrappers in pin_generic.go are no-ops.
// Drivers that used to configure output pin mode in their constructors can use
// legacy.PinOutput() wrapper to keep the same behavior for machine.Pin.
// See internal/legacy/pinlegacy_tinygo.go and internal/legacy/pinlegacy_generic.go for details.
//
// All new drivers are encouraged to not configure pin modes in their constructors and
// do not depend on either machine package or legacy wrappers.
// PinInput is an interface for reading the state of a pin.
type PinInput interface {
-18
View File
@@ -1,18 +0,0 @@
//go:build !tinygo
// Generic no-op implementations of SafePin, SafePinInput and SafePinOutput.
// It's custom implementation's responsibility to configure the pin modes correctly when needed.
package drivers
func SafePinInput(pin PinInput) PinInput {
return pin
}
func SafePinOutput(pin PinOutput) PinOutput {
return pin
}
func SafePin(pin Pin) Pin {
return pin
}
-57
View File
@@ -1,57 +0,0 @@
//go:build tinygo
// Implementation of the Pin interface for tinygo (baremetal), depends on "machine" package.
// SafePin, SafePinInput and SafePinOutput wrappers must be used in constructors of drivers.
package drivers
import (
"machine"
)
// MachinePin wraps machine.Pin to ensure correct pin mode is set when Get or Set methods are called.
type MachinePin struct {
pin machine.Pin
mode machine.PinMode
modeSet bool
}
func (p *MachinePin) Get() bool {
if !p.modeSet || p.mode != machine.PinInput {
p.pin.Configure(machine.PinConfig{Mode: machine.PinInput})
p.mode = machine.PinInput
}
return p.pin.Get()
}
func (p *MachinePin) Set(high bool) {
if !p.modeSet || p.mode != machine.PinOutput {
p.pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
p.mode = machine.PinOutput
}
p.pin.Set(high)
}
// Wrappers for Pin, PinInput and PinOutput interfaces that convert machine.Pin to safe MachinePin.
func SafePinInput(pin PinInput) PinInput {
if p, ok := pin.(machine.Pin); ok {
return &MachinePin{pin: p}
}
return pin
}
func SafePinOutput(pin PinOutput) PinOutput {
if p, ok := pin.(machine.Pin); ok {
return &MachinePin{pin: p}
}
return pin
}
func SafePin(pin Pin) Pin {
if p, ok := pin.(machine.Pin); ok {
return &MachinePin{pin: p}
}
return pin
}
+2
View File
@@ -1,4 +1,6 @@
// Implementation of the Pin interface for the Raspberry Pi GPIO pins.
// Depends on the go-rpio library.
// Configures pin modes automatically when Get or Set methods are called.
package rpio // import "tinygo.org/x/drivers/rpio"
+4 -3
View File
@@ -4,6 +4,7 @@ import (
"time"
"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy"
)
type SPIBus struct {
@@ -19,9 +20,9 @@ func NewSPI(bus drivers.SPI, dcPin, resetPin, csPin drivers.PinOutput) *Device {
return &Device{
bus: &SPIBus{
wire: bus,
dcPin: drivers.SafePinOutput(dcPin),
resetPin: drivers.SafePinOutput(resetPin),
csPin: drivers.SafePinOutput(csPin),
dcPin: legacy.PinOutput(dcPin),
resetPin: legacy.PinOutput(resetPin),
csPin: legacy.PinOutput(csPin),
},
}
}
+5 -4
View File
@@ -10,6 +10,7 @@ import (
"errors"
"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy"
"tinygo.org/x/drivers/pixel"
)
@@ -73,10 +74,10 @@ func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin drivers.PinOutput) Devic
func NewOf[T Color](bus drivers.SPI, resetPin, dcPin, csPin, blPin drivers.PinOutput) DeviceOf[T] {
return DeviceOf[T]{
bus: bus,
dcPin: drivers.SafePinOutput(dcPin),
resetPin: drivers.SafePinOutput(resetPin),
csPin: drivers.SafePinOutput(csPin),
blPin: drivers.SafePinOutput(blPin),
dcPin: legacy.PinOutput(dcPin),
resetPin: legacy.PinOutput(resetPin),
csPin: legacy.PinOutput(csPin),
blPin: legacy.PinOutput(blPin),
}
}
+39
View File
@@ -0,0 +1,39 @@
//go:build baremetal && tinygo
package tinygo // import "tinygo.org/x/drivers/tinygo"
import "machine"
// tinygo.Pin wraps machine.Pin to ensure correct pin mode is set when Get or Set methods are called.
type Pin struct {
pin machine.Pin
mode machine.PinMode
modeSet bool
inputMode machine.PinMode
}
func New(pin machine.Pin) *Pin {
return &Pin{pin: pin, inputMode: machine.PinInput}
}
func NewWithInputMode(pin machine.Pin, inputMode machine.PinMode) *Pin {
return &Pin{pin: pin, inputMode: inputMode}
}
func (p *Pin) Get() bool {
if !p.modeSet || p.mode != p.inputMode {
p.pin.Configure(machine.PinConfig{Mode: p.inputMode})
p.mode = machine.PinInput
}
return p.pin.Get()
}
func (p *Pin) Set(high bool) {
if !p.modeSet || p.mode != machine.PinOutput {
p.pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
p.mode = machine.PinOutput
}
p.pin.Set(high)
}