Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions apa102/apa102.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ package apa102 // import "tinygo.org/x/drivers/apa102"

import (
"image/color"
"machine"

"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy"
"tinygo.org/x/drivers/internal/pin"
)

const (
Expand Down Expand Up @@ -37,8 +38,11 @@ func New(b drivers.SPI) *Device {

// NewSoftwareSPI returns a new APA102 driver that will use a software based
// implementation of the SPI protocol.
func NewSoftwareSPI(sckPin, sdoPin machine.Pin, delay uint32) *Device {
return New(&bbSPI{SCK: sckPin, SDO: sdoPin, Delay: delay})
func NewSoftwareSPI(sckPin, sdoPin pin.Output, delay uint32) *Device {
return New(&bbSPI{SCK: sckPin.Set, SDO: sdoPin.Set, Delay: delay, configurePins: func() {
legacy.ConfigurePinOut(sckPin)
legacy.ConfigurePinOut(sdoPin)
}})
}

// WriteColors writes the given RGBA color slice out using the APA102 protocol.
Expand Down
18 changes: 12 additions & 6 deletions apa102/softspi.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
package apa102

import "machine"
import (
"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy"
)

// bbSPI is a dumb bit-bang implementation of SPI protocol that is hardcoded
// to mode 0 and ignores trying to receive data. Just enough for the APA102.
// Note: making this unexported for now because it is probable not suitable
// most purposes other than the APA102 package. It might be desirable to make
// this more generic and include it in the TinyGo "machine" package instead.
type bbSPI struct {
SCK machine.Pin
SDO machine.Pin
Delay uint32
SCK drivers.PinOutput
SDO drivers.PinOutput
Delay uint32
configurePins func()
}

// Configure sets up the SCK and SDO pins as outputs and sets them low
func (s *bbSPI) Configure() {
s.SCK.Configure(machine.PinConfig{Mode: machine.PinOutput})
s.SDO.Configure(machine.PinConfig{Mode: machine.PinOutput})
if s.configurePins == nil {
panic(legacy.ErrConfigBeforeInstantiated)
}
s.configurePins()
s.SCK.Low()
s.SDO.Low()
if s.Delay == 0 {
Expand Down
54 changes: 31 additions & 23 deletions bmi160/bmi160.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,48 @@
package bmi160

import (
"machine"
"time"

"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy"
"tinygo.org/x/drivers/internal/pin"
)

// DeviceSPI is the SPI interface to a BMI160 accelerometer/gyroscope. There is
// also an I2C interface, but it is not yet supported.
type DeviceSPI struct {
// Chip select pin
CSB machine.Pin
csb drivers.PinOutput

buf [7]byte

// SPI bus (requires chip select to be usable).
Bus drivers.SPI
bus drivers.SPI
configurePins func()
}

// NewSPI returns a new device driver. The pin and SPI interface are not
// touched, provide a fully configured SPI object and call Configure to start
// using this device.
func NewSPI(csb machine.Pin, spi drivers.SPI) *DeviceSPI {
func NewSPI(csb pin.Output, spi drivers.SPI) *DeviceSPI {
return &DeviceSPI{
CSB: csb, // chip select
Bus: spi,
csb: csb.Set, // chip select
bus: spi,
configurePins: func() {
legacy.ConfigurePinOut(csb)
},
}
}

// Configure configures the BMI160 for use. It configures the CSB pin and
// configures the BMI160, but it does not configure the SPI interface (it is
// assumed to be up and running).
func (d *DeviceSPI) Configure() error {
d.CSB.Configure(machine.PinConfig{Mode: machine.PinOutput})
d.CSB.High()
if d.configurePins == nil {
return legacy.ErrConfigBeforeInstantiated
}
d.configurePins()
d.csb.High()

// The datasheet recommends doing a register read from address 0x7F to get
// SPI communication going:
Expand Down Expand Up @@ -86,9 +94,9 @@ func (d *DeviceSPI) ReadTemperature() (temperature int32, err error) {
data[0] = 0x80 | reg_TEMPERATURE_0
data[1] = 0
data[2] = 0
d.CSB.Low()
err = d.Bus.Tx(data, data)
d.CSB.High()
d.csb.Low()
err = d.bus.Tx(data, data)
d.csb.High()
if err != nil {
return
}
Expand Down Expand Up @@ -123,9 +131,9 @@ func (d *DeviceSPI) ReadAcceleration() (x int32, y int32, z int32, err error) {
for i := 1; i < len(data); i++ {
data[i] = 0
}
d.CSB.Low()
err = d.Bus.Tx(data, data)
d.CSB.High()
d.csb.Low()
err = d.bus.Tx(data, data)
d.csb.High()
if err != nil {
return
}
Expand Down Expand Up @@ -153,9 +161,9 @@ func (d *DeviceSPI) ReadRotation() (x int32, y int32, z int32, err error) {
for i := 1; i < len(data); i++ {
data[i] = 0
}
d.CSB.Low()
err = d.Bus.Tx(data, data)
d.CSB.High()
d.csb.Low()
err = d.bus.Tx(data, data)
d.csb.High()
if err != nil {
return
}
Expand Down Expand Up @@ -201,9 +209,9 @@ func (d *DeviceSPI) readRegister(address uint8) uint8 {
data := d.buf[:2]
data[0] = 0x80 | address
data[1] = 0
d.CSB.Low()
d.Bus.Tx(data, data)
d.CSB.High()
d.csb.Low()
d.bus.Tx(data, data)
d.csb.High()
return data[1]
}

Expand All @@ -217,7 +225,7 @@ func (d *DeviceSPI) writeRegister(address, data uint8) {
buf[0] = address
buf[1] = data

d.CSB.Low()
d.Bus.Tx(buf, buf)
d.CSB.High()
d.csb.Low()
d.bus.Tx(buf, buf)
d.csb.High()
}
15 changes: 8 additions & 7 deletions buzzer/buzzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,38 @@
package buzzer // import "tinygo.org/x/drivers/buzzer"

import (
"machine"

"time"

"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/pin"
)

// Device wraps a GPIO connection to a buzzer.
type Device struct {
pin machine.Pin
pin drivers.PinOutput
High bool
BPM float64
}

// New returns a new buzzer driver given which pin to use
func New(pin machine.Pin) Device {
func New(pin pin.Output) Device {
return Device{
pin: pin,
pin: pin.Set,
High: false,
BPM: 96.0,
}
}

// On sets the buzzer to a high state.
func (l *Device) On() (err error) {
l.pin.Set(true)
l.pin.High()
l.High = true
return
}

// Off sets the buzzer to a low state.
func (l *Device) Off() (err error) {
l.pin.Set(false)
l.pin.Low()
l.High = false
return
}
Expand Down
71 changes: 4 additions & 67 deletions easystepper/easystepper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
package easystepper // import "tinygo.org/x/drivers/easystepper"

import (
"errors"
"machine"
"time"

"tinygo.org/x/drivers"
)

// StepMode determines the coil sequence used to perform a single step
Expand All @@ -30,28 +30,10 @@ func (sm StepMode) stepCount() uint {
}
}

// DeviceConfig contains the configuration data for a single easystepper driver
type DeviceConfig struct {
// Pin1 ... Pin4 determines the pins to configure and use for the device
Pin1, Pin2, Pin3, Pin4 machine.Pin
// StepCount is the number of steps required to perform a full revolution of the stepper motor
StepCount uint
// RPM determines the speed of the stepper motor in 'Revolutions per Minute'
RPM uint
// Mode determines the coil sequence used to perform a single step
Mode StepMode
}

// DualDeviceConfig contains the configuration data for a dual easystepper driver
type DualDeviceConfig struct {
DeviceConfig
// Pin5 ... Pin8 determines the pins to configure and use for the second device
Pin5, Pin6, Pin7, Pin8 machine.Pin
}

// Device holds the pins and the delay between steps
type Device struct {
pins [4]machine.Pin
pins [4]drivers.PinOutput
config func()
stepDelay time.Duration
stepNumber uint8
stepMode StepMode
Expand All @@ -62,51 +44,6 @@ type DualDevice struct {
devices [2]*Device
}

// New returns a new single easystepper driver given a DeviceConfig
func New(config DeviceConfig) (*Device, error) {
if config.StepCount == 0 || config.RPM == 0 {
return nil, errors.New("config.StepCount and config.RPM must be > 0")
}
return &Device{
pins: [4]machine.Pin{config.Pin1, config.Pin2, config.Pin3, config.Pin4},
stepDelay: time.Second * 60 / time.Duration((config.StepCount * config.RPM)),
stepMode: config.Mode,
}, nil
}

// Configure configures the pins of the Device
func (d *Device) Configure() {
for _, pin := range d.pins {
pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
}
}

// NewDual returns a new dual easystepper driver given 8 pins, number of steps and rpm
func NewDual(config DualDeviceConfig) (*DualDevice, error) {
// Create the first device
dev1, err := New(config.DeviceConfig)
if err != nil {
return nil, err
}
// Create the second device
config.DeviceConfig.Pin1 = config.Pin5
config.DeviceConfig.Pin2 = config.Pin6
config.DeviceConfig.Pin3 = config.Pin7
config.DeviceConfig.Pin4 = config.Pin8
dev2, err := New(config.DeviceConfig)
if err != nil {
return nil, err
}
// Return composite dual device
return &DualDevice{devices: [2]*Device{dev1, dev2}}, nil
}

// Configure configures the pins of the DualDevice
func (d *DualDevice) Configure() {
d.devices[0].Configure()
d.devices[1].Configure()
}

// Move rotates the motor the number of given steps
// (negative steps will rotate it the opposite direction)
func (d *Device) Move(steps int32) {
Expand Down
26 changes: 26 additions & 0 deletions easystepper/easystepper_go.go

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I understand this correctly, the related name for "pinhal_baremetal.go" is "pinhal_os.go" - so maybe we should name it accordingly to "easystepper_os.go"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point- will rename pinhal_os.go->pinhal_go.go, since there is no actual OS dependence here, what is more this is meant for other embedded go projects which likely don't use an OS.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package easystepper

import (
"errors"
"time"

"tinygo.org/x/drivers"
)

func NewCrossPlatform(stepcount, rpm uint, mode StepMode, pins [4]drivers.PinOutput) (*Device, error) {
if stepcount == 0 || rpm == 0 {
return nil, errors.New("zero rpm and/or stepcount")
}
for i := range pins {
if pins[i] == nil {
return nil, errors.New("nil pin")
}
}
d := &Device{
pins: pins,
stepDelay: time.Second * 60 / time.Duration((stepcount * rpm)),
stepMode: mode,
config: func() {},
}
return d, nil
}
Loading