mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-05 23:43:41 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25eecd27d1 | |||
| 293de2b61a | |||
| 3183013cbb | |||
| 876a3150f3 | |||
| 8b6e8c81e3 | |||
| 1f37a1398c | |||
| 8d3cac8322 | |||
| 3cd6afb84c | |||
| db544f4ca7 | |||
| 9fb57e22fb | |||
| 3681452097 | |||
| 8f0fbaa945 | |||
| f3945b1d58 | |||
| 06e4c0267f |
@@ -1,30 +1,3 @@
|
|||||||
0.32.0
|
|
||||||
---
|
|
||||||
- **enhancements**
|
|
||||||
- **bmp280**
|
|
||||||
- remove alloc on read sensor data
|
|
||||||
- **ws2812**
|
|
||||||
- add 200MHz support for the Cortex-M0/rp2040
|
|
||||||
|
|
||||||
- **bugfixes**
|
|
||||||
- **ssd1306**
|
|
||||||
- remove time.Sleep from SSD1306 SPI transfer code
|
|
||||||
- **tmc2209**
|
|
||||||
- tmc2209 bug fixes (#755)
|
|
||||||
|
|
||||||
- **docs**
|
|
||||||
- **contributing**
|
|
||||||
- add driver design pointer to CONTRIBUTING.md
|
|
||||||
|
|
||||||
|
|
||||||
0.31.0
|
|
||||||
---
|
|
||||||
---
|
|
||||||
- **enhancements**
|
|
||||||
- **spi**
|
|
||||||
- update all SPI usage to use either *machine.SPI or drivers.SPI
|
|
||||||
|
|
||||||
|
|
||||||
0.30.0
|
0.30.0
|
||||||
---
|
---
|
||||||
- **new devices**
|
- **new devices**
|
||||||
|
|||||||
@@ -8,9 +8,6 @@ We would like your help to make this project better, so we appreciate any contri
|
|||||||
|
|
||||||
We'd love to get your feedback on getting started with TinyGo. Run into any difficulty, confusion, or anything else? You are not alone. We want to know about your experience, so we can help the next people. Please open a Github issue with your questions, or you can also get in touch directly with us on our Slack channel at [https://gophers.slack.com/messages/CDJD3SUP6](https://gophers.slack.com/messages/CDJD3SUP6).
|
We'd love to get your feedback on getting started with TinyGo. Run into any difficulty, confusion, or anything else? You are not alone. We want to know about your experience, so we can help the next people. Please open a Github issue with your questions, or you can also get in touch directly with us on our Slack channel at [https://gophers.slack.com/messages/CDJD3SUP6](https://gophers.slack.com/messages/CDJD3SUP6).
|
||||||
|
|
||||||
### Driver design
|
|
||||||
Before porting or writing a driver from scratch please read **[Driver Design for TinyGo](https://tinygo.org/docs/guides/driver-design)**.
|
|
||||||
|
|
||||||
### One of the TinyGo drivers is not working as you expect
|
### One of the TinyGo drivers is not working as you expect
|
||||||
|
|
||||||
Please open a Github issue with your problem, and we will be happy to assist.
|
Please open a Github issue with your problem, and we will be happy to assist.
|
||||||
|
|||||||
+7
-3
@@ -5,9 +5,10 @@ package apa102 // import "tinygo.org/x/drivers/apa102"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -37,8 +38,11 @@ func New(b drivers.SPI) *Device {
|
|||||||
|
|
||||||
// NewSoftwareSPI returns a new APA102 driver that will use a software based
|
// NewSoftwareSPI returns a new APA102 driver that will use a software based
|
||||||
// implementation of the SPI protocol.
|
// implementation of the SPI protocol.
|
||||||
func NewSoftwareSPI(sckPin, sdoPin machine.Pin, delay uint32) *Device {
|
func NewSoftwareSPI(sckPin, sdoPin pin.Output, delay uint32) *Device {
|
||||||
return New(&bbSPI{SCK: sckPin, SDO: sdoPin, Delay: delay})
|
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.
|
// WriteColors writes the given RGBA color slice out using the APA102 protocol.
|
||||||
|
|||||||
+12
-6
@@ -1,6 +1,9 @@
|
|||||||
package apa102
|
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
|
// 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.
|
// to mode 0 and ignores trying to receive data. Just enough for the APA102.
|
||||||
@@ -8,15 +11,18 @@ import "machine"
|
|||||||
// most purposes other than the APA102 package. It might be desirable to make
|
// 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.
|
// this more generic and include it in the TinyGo "machine" package instead.
|
||||||
type bbSPI struct {
|
type bbSPI struct {
|
||||||
SCK machine.Pin
|
SCK drivers.PinOutput
|
||||||
SDO machine.Pin
|
SDO drivers.PinOutput
|
||||||
Delay uint32
|
Delay uint32
|
||||||
|
configurePins func()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure sets up the SCK and SDO pins as outputs and sets them low
|
// Configure sets up the SCK and SDO pins as outputs and sets them low
|
||||||
func (s *bbSPI) Configure() {
|
func (s *bbSPI) Configure() {
|
||||||
s.SCK.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
if s.configurePins == nil {
|
||||||
s.SDO.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
panic(legacy.ErrConfigBeforeInstantiated)
|
||||||
|
}
|
||||||
|
s.configurePins()
|
||||||
s.SCK.Low()
|
s.SCK.Low()
|
||||||
s.SDO.Low()
|
s.SDO.Low()
|
||||||
if s.Delay == 0 {
|
if s.Delay == 0 {
|
||||||
|
|||||||
+31
-23
@@ -1,31 +1,36 @@
|
|||||||
package bmi160
|
package bmi160
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"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
|
// DeviceSPI is the SPI interface to a BMI160 accelerometer/gyroscope. There is
|
||||||
// also an I2C interface, but it is not yet supported.
|
// also an I2C interface, but it is not yet supported.
|
||||||
type DeviceSPI struct {
|
type DeviceSPI struct {
|
||||||
// Chip select pin
|
// Chip select pin
|
||||||
CSB machine.Pin
|
csb drivers.PinOutput
|
||||||
|
|
||||||
buf [7]byte
|
buf [7]byte
|
||||||
|
|
||||||
// SPI bus (requires chip select to be usable).
|
// 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
|
// 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
|
// touched, provide a fully configured SPI object and call Configure to start
|
||||||
// using this device.
|
// using this device.
|
||||||
func NewSPI(csb machine.Pin, spi drivers.SPI) *DeviceSPI {
|
func NewSPI(csb pin.Output, spi drivers.SPI) *DeviceSPI {
|
||||||
return &DeviceSPI{
|
return &DeviceSPI{
|
||||||
CSB: csb, // chip select
|
csb: csb.Set, // chip select
|
||||||
Bus: spi,
|
bus: spi,
|
||||||
|
configurePins: func() {
|
||||||
|
legacy.ConfigurePinOut(csb)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,8 +38,11 @@ func NewSPI(csb machine.Pin, spi drivers.SPI) *DeviceSPI {
|
|||||||
// configures the BMI160, but it does not configure the SPI interface (it is
|
// configures the BMI160, but it does not configure the SPI interface (it is
|
||||||
// assumed to be up and running).
|
// assumed to be up and running).
|
||||||
func (d *DeviceSPI) Configure() error {
|
func (d *DeviceSPI) Configure() error {
|
||||||
d.CSB.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
if d.configurePins == nil {
|
||||||
d.CSB.High()
|
return legacy.ErrConfigBeforeInstantiated
|
||||||
|
}
|
||||||
|
d.configurePins()
|
||||||
|
d.csb.High()
|
||||||
|
|
||||||
// The datasheet recommends doing a register read from address 0x7F to get
|
// The datasheet recommends doing a register read from address 0x7F to get
|
||||||
// SPI communication going:
|
// SPI communication going:
|
||||||
@@ -86,9 +94,9 @@ func (d *DeviceSPI) ReadTemperature() (temperature int32, err error) {
|
|||||||
data[0] = 0x80 | reg_TEMPERATURE_0
|
data[0] = 0x80 | reg_TEMPERATURE_0
|
||||||
data[1] = 0
|
data[1] = 0
|
||||||
data[2] = 0
|
data[2] = 0
|
||||||
d.CSB.Low()
|
d.csb.Low()
|
||||||
err = d.Bus.Tx(data, data)
|
err = d.bus.Tx(data, data)
|
||||||
d.CSB.High()
|
d.csb.High()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -123,9 +131,9 @@ func (d *DeviceSPI) ReadAcceleration() (x int32, y int32, z int32, err error) {
|
|||||||
for i := 1; i < len(data); i++ {
|
for i := 1; i < len(data); i++ {
|
||||||
data[i] = 0
|
data[i] = 0
|
||||||
}
|
}
|
||||||
d.CSB.Low()
|
d.csb.Low()
|
||||||
err = d.Bus.Tx(data, data)
|
err = d.bus.Tx(data, data)
|
||||||
d.CSB.High()
|
d.csb.High()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -153,9 +161,9 @@ func (d *DeviceSPI) ReadRotation() (x int32, y int32, z int32, err error) {
|
|||||||
for i := 1; i < len(data); i++ {
|
for i := 1; i < len(data); i++ {
|
||||||
data[i] = 0
|
data[i] = 0
|
||||||
}
|
}
|
||||||
d.CSB.Low()
|
d.csb.Low()
|
||||||
err = d.Bus.Tx(data, data)
|
err = d.bus.Tx(data, data)
|
||||||
d.CSB.High()
|
d.csb.High()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -201,9 +209,9 @@ func (d *DeviceSPI) readRegister(address uint8) uint8 {
|
|||||||
data := d.buf[:2]
|
data := d.buf[:2]
|
||||||
data[0] = 0x80 | address
|
data[0] = 0x80 | address
|
||||||
data[1] = 0
|
data[1] = 0
|
||||||
d.CSB.Low()
|
d.csb.Low()
|
||||||
d.Bus.Tx(data, data)
|
d.bus.Tx(data, data)
|
||||||
d.CSB.High()
|
d.csb.High()
|
||||||
return data[1]
|
return data[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +225,7 @@ func (d *DeviceSPI) writeRegister(address, data uint8) {
|
|||||||
buf[0] = address
|
buf[0] = address
|
||||||
buf[1] = data
|
buf[1] = data
|
||||||
|
|
||||||
d.CSB.Low()
|
d.csb.Low()
|
||||||
d.Bus.Tx(buf, buf)
|
d.bus.Tx(buf, buf)
|
||||||
d.CSB.High()
|
d.csb.High()
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-7
@@ -23,7 +23,6 @@ type Filter uint
|
|||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.I2C
|
bus drivers.I2C
|
||||||
Address uint16
|
Address uint16
|
||||||
buf [6]byte
|
|
||||||
cali calibrationCoefficients
|
cali calibrationCoefficients
|
||||||
Temperature Oversampling
|
Temperature Oversampling
|
||||||
Pressure Oversampling
|
Pressure Oversampling
|
||||||
@@ -135,8 +134,8 @@ func (d *Device) PrintCali() {
|
|||||||
|
|
||||||
// ReadTemperature returns the temperature in celsius milli degrees (°C/1000).
|
// ReadTemperature returns the temperature in celsius milli degrees (°C/1000).
|
||||||
func (d *Device) ReadTemperature() (temperature int32, err error) {
|
func (d *Device) ReadTemperature() (temperature int32, err error) {
|
||||||
data := d.buf[:3]
|
data, err := d.readData(REG_TEMP, 3)
|
||||||
if err = d.readData(REG_TEMP, data); err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,8 +158,8 @@ func (d *Device) ReadTemperature() (temperature int32, err error) {
|
|||||||
// ReadPressure returns the pressure in milli pascals (mPa).
|
// ReadPressure returns the pressure in milli pascals (mPa).
|
||||||
func (d *Device) ReadPressure() (pressure int32, err error) {
|
func (d *Device) ReadPressure() (pressure int32, err error) {
|
||||||
// First 3 bytes are Pressure, last 3 bytes are Temperature
|
// First 3 bytes are Pressure, last 3 bytes are Temperature
|
||||||
data := d.buf[:6]
|
data, err := d.readData(REG_PRES, 6)
|
||||||
if err = d.readData(REG_PRES, data); err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +203,7 @@ func (d *Device) ReadPressure() (pressure int32, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// readData reads n number of bytes of the specified register
|
// readData reads n number of bytes of the specified register
|
||||||
func (d *Device) readData(register int, data []byte) error {
|
func (d *Device) readData(register int, n int) ([]byte, error) {
|
||||||
// If not in normal mode, set the mode to FORCED mode, to prevent incorrect measurements
|
// If not in normal mode, set the mode to FORCED mode, to prevent incorrect measurements
|
||||||
// After the measurement in FORCED mode, the sensor will return to SLEEP mode
|
// After the measurement in FORCED mode, the sensor will return to SLEEP mode
|
||||||
if d.Mode != MODE_NORMAL {
|
if d.Mode != MODE_NORMAL {
|
||||||
@@ -219,7 +218,9 @@ func (d *Device) readData(register int, data []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the requested register
|
// Read the requested register
|
||||||
return legacy.ReadRegister(d.bus, uint8(d.Address), uint8(register), data[:])
|
data := make([]byte, n)
|
||||||
|
err := legacy.ReadRegister(d.bus, uint8(d.Address), uint8(register), data[:])
|
||||||
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert3Bytes converts three bytes to int32
|
// convert3Bytes converts three bytes to int32
|
||||||
|
|||||||
+8
-7
@@ -2,22 +2,23 @@
|
|||||||
package buzzer // import "tinygo.org/x/drivers/buzzer"
|
package buzzer // import "tinygo.org/x/drivers/buzzer"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"machine"
|
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Device wraps a GPIO connection to a buzzer.
|
// Device wraps a GPIO connection to a buzzer.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
pin machine.Pin
|
pin drivers.PinOutput
|
||||||
High bool
|
High bool
|
||||||
BPM float64
|
BPM float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new buzzer driver given which pin to use
|
// 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{
|
return Device{
|
||||||
pin: pin,
|
pin: pin.Set,
|
||||||
High: false,
|
High: false,
|
||||||
BPM: 96.0,
|
BPM: 96.0,
|
||||||
}
|
}
|
||||||
@@ -25,14 +26,14 @@ func New(pin machine.Pin) Device {
|
|||||||
|
|
||||||
// On sets the buzzer to a high state.
|
// On sets the buzzer to a high state.
|
||||||
func (l *Device) On() (err error) {
|
func (l *Device) On() (err error) {
|
||||||
l.pin.Set(true)
|
l.pin.High()
|
||||||
l.High = true
|
l.High = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Off sets the buzzer to a low state.
|
// Off sets the buzzer to a low state.
|
||||||
func (l *Device) Off() (err error) {
|
func (l *Device) Off() (err error) {
|
||||||
l.pin.Set(false)
|
l.pin.Low()
|
||||||
l.High = false
|
l.High = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
package easystepper // import "tinygo.org/x/drivers/easystepper"
|
package easystepper // import "tinygo.org/x/drivers/easystepper"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StepMode determines the coil sequence used to perform a single step
|
// StepMode determines the coil sequence used to perform a single step
|
||||||
@@ -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
|
// Device holds the pins and the delay between steps
|
||||||
type Device struct {
|
type Device struct {
|
||||||
pins [4]machine.Pin
|
pins [4]drivers.PinOutput
|
||||||
|
config func()
|
||||||
stepDelay time.Duration
|
stepDelay time.Duration
|
||||||
stepNumber uint8
|
stepNumber uint8
|
||||||
stepMode StepMode
|
stepMode StepMode
|
||||||
@@ -62,51 +44,6 @@ type DualDevice struct {
|
|||||||
devices [2]*Device
|
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
|
// Move rotates the motor the number of given steps
|
||||||
// (negative steps will rotate it the opposite direction)
|
// (negative steps will rotate it the opposite direction)
|
||||||
func (d *Device) Move(steps int32) {
|
func (d *Device) Move(steps int32) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
//go:build baremetal
|
||||||
|
|
||||||
|
package easystepper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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]drivers.PinOutput{config.Pin1.Set, config.Pin2.Set, config.Pin3.Set, config.Pin4.Set},
|
||||||
|
stepDelay: time.Second * 60 / time.Duration((config.StepCount * config.RPM)),
|
||||||
|
stepMode: config.Mode,
|
||||||
|
config: func() {
|
||||||
|
legacy.ConfigurePinOut(config.Pin1)
|
||||||
|
legacy.ConfigurePinOut(config.Pin2)
|
||||||
|
legacy.ConfigurePinOut(config.Pin3)
|
||||||
|
legacy.ConfigurePinOut(config.Pin4)
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure configures the pins of the Device
|
||||||
|
func (d *Device) Configure() {
|
||||||
|
if d.config == nil {
|
||||||
|
panic(legacy.ErrConfigBeforeInstantiated)
|
||||||
|
}
|
||||||
|
d.config()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure configures the pins of the DualDevice
|
||||||
|
func (d *DualDevice) Configure() {
|
||||||
|
d.devices[0].Configure()
|
||||||
|
d.devices[1].Configure()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
println("GPS I2C Example")
|
println("GPS I2C Example")
|
||||||
machine.I2C0.Configure(machine.I2CConfig{})
|
machine.I2C0.Configure(machine.I2CConfig{})
|
||||||
ublox := gps.NewI2CWithAddress(machine.I2C0, gps.UBLOX_I2C_ADDRESS)
|
ublox := gps.NewI2C(machine.I2C0)
|
||||||
parser := gps.NewParser()
|
parser := gps.NewParser()
|
||||||
var fix gps.Fix
|
var fix gps.Fix
|
||||||
for {
|
for {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
"image/color"
|
"image/color"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -8,21 +10,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Thumby will have preset size.
|
machine.I2C0.Configure(machine.I2CConfig{
|
||||||
// If not compiling for thumby the width and height will be whatever we suggest
|
Frequency: machine.TWI_FREQ_400KHZ,
|
||||||
const suggestHeight = 32
|
})
|
||||||
const suggestWidth = 128
|
|
||||||
var display *ssd1306.Device
|
display := ssd1306.NewI2C(machine.I2C0)
|
||||||
var err error
|
display.Configure(ssd1306.Config{
|
||||||
display, err = makeSSD1306(suggestWidth, suggestHeight)
|
Address: ssd1306.Address_128_32,
|
||||||
if err != nil {
|
Width: 128,
|
||||||
panic(err)
|
Height: 32,
|
||||||
}
|
})
|
||||||
|
|
||||||
display.ClearDisplay()
|
display.ClearDisplay()
|
||||||
|
|
||||||
width, height := display.Size()
|
x := int16(0)
|
||||||
x := int16(width)
|
y := int16(0)
|
||||||
y := int16(height)
|
|
||||||
deltaX := int16(1)
|
deltaX := int16(1)
|
||||||
deltaY := int16(1)
|
deltaY := int16(1)
|
||||||
for {
|
for {
|
||||||
@@ -37,11 +39,11 @@ func main() {
|
|||||||
x += deltaX
|
x += deltaX
|
||||||
y += deltaY
|
y += deltaY
|
||||||
|
|
||||||
if x == 0 || x == width-1 {
|
if x == 0 || x == 127 {
|
||||||
deltaX = -deltaX
|
deltaX = -deltaX
|
||||||
}
|
}
|
||||||
|
|
||||||
if y == 0 || y == height-1 {
|
if y == 0 || y == 31 {
|
||||||
deltaY = -deltaY
|
deltaY = -deltaY
|
||||||
}
|
}
|
||||||
time.Sleep(1 * time.Millisecond)
|
time.Sleep(1 * time.Millisecond)
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
// This example shows how to use 128x64 display over I2C
|
||||||
|
// Tested on Seeeduino XIAO Expansion Board https://wiki.seeedstudio.com/Seeeduino-XIAO-Expansion-Board/
|
||||||
|
//
|
||||||
|
// According to manual, I2C address of the display is 0x78, but that's 8-bit address.
|
||||||
|
// TinyGo operates on 7-bit addresses and respective 7-bit address would be 0x3C, which we use below.
|
||||||
|
//
|
||||||
|
// To learn more about different types of I2C addresses, please see following page
|
||||||
|
// https://www.totalphase.com/support/articles/200349176-7-bit-8-bit-and-10-bit-I2C-Slave-Addressing
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"image/color"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/ssd1306"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
machine.I2C0.Configure(machine.I2CConfig{
|
||||||
|
Frequency: machine.TWI_FREQ_400KHZ,
|
||||||
|
})
|
||||||
|
|
||||||
|
display := ssd1306.NewI2C(machine.I2C0)
|
||||||
|
display.Configure(ssd1306.Config{
|
||||||
|
Address: 0x3C,
|
||||||
|
Width: 128,
|
||||||
|
Height: 64,
|
||||||
|
})
|
||||||
|
|
||||||
|
display.ClearDisplay()
|
||||||
|
|
||||||
|
x := int16(0)
|
||||||
|
y := int16(0)
|
||||||
|
deltaX := int16(1)
|
||||||
|
deltaY := int16(1)
|
||||||
|
for {
|
||||||
|
pixel := display.GetPixel(x, y)
|
||||||
|
c := color.RGBA{255, 255, 255, 255}
|
||||||
|
if pixel {
|
||||||
|
c = color.RGBA{0, 0, 0, 255}
|
||||||
|
}
|
||||||
|
display.SetPixel(x, y, c)
|
||||||
|
display.Display()
|
||||||
|
|
||||||
|
x += deltaX
|
||||||
|
y += deltaY
|
||||||
|
|
||||||
|
if x == 0 || x == 127 {
|
||||||
|
deltaX = -deltaX
|
||||||
|
}
|
||||||
|
|
||||||
|
if y == 0 || y == 63 {
|
||||||
|
deltaY = -deltaY
|
||||||
|
}
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
//go:build !thumby
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ssd1306"
|
|
||||||
)
|
|
||||||
|
|
||||||
func makeSSD1306(width, height int16) (*ssd1306.Device, error) {
|
|
||||||
err := machine.I2C0.Configure(machine.I2CConfig{
|
|
||||||
Frequency: 400 * machine.KHz,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
address := uint16(ssd1306.Address)
|
|
||||||
if width == 128 && (height == 32 || height == 64) {
|
|
||||||
address = ssd1306.Address_128_32
|
|
||||||
}
|
|
||||||
display := ssd1306.NewI2C(machine.I2C0)
|
|
||||||
display.Configure(ssd1306.Config{
|
|
||||||
Address: address,
|
|
||||||
Width: width,
|
|
||||||
Height: height,
|
|
||||||
})
|
|
||||||
return &display, nil
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
//go:build thumby
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ssd1306"
|
|
||||||
)
|
|
||||||
|
|
||||||
func makeSSD1306(_, _ int16) (*ssd1306.Device, error) {
|
|
||||||
// width and height are known for thumby.
|
|
||||||
machine.SPI0.Configure(machine.SPIConfig{})
|
|
||||||
display := ssd1306.NewSPI(machine.SPI0, machine.THUMBY_DC_PIN, machine.THUMBY_RESET_PIN, machine.THUMBY_CS_PIN)
|
|
||||||
display.Configure(ssd1306.Config{
|
|
||||||
Width: 72,
|
|
||||||
Height: 40,
|
|
||||||
ResetCol: ssd1306.ResetValue{28, 99},
|
|
||||||
ResetPage: ssd1306.ResetValue{0, 5},
|
|
||||||
})
|
|
||||||
return &display, nil
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/ssd1306"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
machine.SPI0.Configure(machine.SPIConfig{
|
||||||
|
Frequency: 8000000,
|
||||||
|
})
|
||||||
|
display := ssd1306.NewSPI(machine.SPI0, machine.P8, machine.P7, machine.P9)
|
||||||
|
display.Configure(ssd1306.Config{
|
||||||
|
Width: 128,
|
||||||
|
Height: 64,
|
||||||
|
})
|
||||||
|
|
||||||
|
display.ClearDisplay()
|
||||||
|
|
||||||
|
x := int16(64)
|
||||||
|
y := int16(32)
|
||||||
|
deltaX := int16(1)
|
||||||
|
deltaY := int16(1)
|
||||||
|
for {
|
||||||
|
pixel := display.GetPixel(x, y)
|
||||||
|
c := color.RGBA{255, 255, 255, 255}
|
||||||
|
if pixel {
|
||||||
|
c = color.RGBA{0, 0, 0, 255}
|
||||||
|
}
|
||||||
|
display.SetPixel(x, y, c)
|
||||||
|
display.Display()
|
||||||
|
|
||||||
|
x += deltaX
|
||||||
|
y += deltaY
|
||||||
|
|
||||||
|
if x == 0 || x == 127 {
|
||||||
|
deltaX = -deltaX
|
||||||
|
}
|
||||||
|
|
||||||
|
if y == 0 || y == 63 {
|
||||||
|
deltaY = -deltaY
|
||||||
|
}
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
// This example using the SSD1306 OLED display over SPI on the Thumby board
|
||||||
|
// A very tiny 72x40 display.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/ssd1306"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
machine.SPI0.Configure(machine.SPIConfig{})
|
||||||
|
display := ssd1306.NewSPI(machine.SPI0, machine.THUMBY_DC_PIN, machine.THUMBY_RESET_PIN, machine.THUMBY_CS_PIN)
|
||||||
|
display.Configure(ssd1306.Config{
|
||||||
|
Width: 72,
|
||||||
|
Height: 40,
|
||||||
|
ResetCol: ssd1306.ResetValue{28, 99},
|
||||||
|
ResetPage: ssd1306.ResetValue{0, 5},
|
||||||
|
})
|
||||||
|
|
||||||
|
display.ClearDisplay()
|
||||||
|
|
||||||
|
x := int16(36)
|
||||||
|
y := int16(20)
|
||||||
|
deltaX := int16(1)
|
||||||
|
deltaY := int16(1)
|
||||||
|
for {
|
||||||
|
pixel := display.GetPixel(x, y)
|
||||||
|
c := color.RGBA{255, 255, 255, 255}
|
||||||
|
if pixel {
|
||||||
|
c = color.RGBA{0, 0, 0, 255}
|
||||||
|
}
|
||||||
|
display.SetPixel(x, y, c)
|
||||||
|
display.Display()
|
||||||
|
|
||||||
|
x += deltaX
|
||||||
|
y += deltaY
|
||||||
|
|
||||||
|
if x == 0 || x == 71 {
|
||||||
|
deltaX = -deltaX
|
||||||
|
}
|
||||||
|
|
||||||
|
if y == 0 || y == 39 {
|
||||||
|
deltaY = -deltaY
|
||||||
|
}
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
-9
@@ -5,28 +5,29 @@
|
|||||||
package ft6336
|
package ft6336
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
"tinygo.org/x/drivers/internal/legacy"
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
"tinygo.org/x/drivers/touch"
|
"tinygo.org/x/drivers/touch"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Device wraps FT6336 I2C Self-Capacitive touch
|
// Device wraps FT6336 I2C Self-Capacitive touch
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.I2C
|
bus drivers.I2C
|
||||||
buf []byte
|
buf []byte
|
||||||
Address uint8
|
Address uint8
|
||||||
intPin machine.Pin
|
configurePins func()
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns FT6336 device for the provided I2C bus using default address.
|
// New returns FT6336 device for the provided I2C bus using default address.
|
||||||
func New(i2c drivers.I2C, intPin machine.Pin) *Device {
|
func New(i2c drivers.I2C, intPin pin.Input) *Device {
|
||||||
return &Device{
|
return &Device{
|
||||||
bus: i2c,
|
bus: i2c,
|
||||||
buf: make([]byte, 11),
|
buf: make([]byte, 11),
|
||||||
Address: Address,
|
Address: Address,
|
||||||
intPin: intPin,
|
configurePins: func() {
|
||||||
|
legacy.ConfigurePinInputPulldown(intPin)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,8 +37,11 @@ type Config struct {
|
|||||||
|
|
||||||
// Configure the FT6336 device.
|
// Configure the FT6336 device.
|
||||||
func (d *Device) Configure(config Config) error {
|
func (d *Device) Configure(config Config) error {
|
||||||
|
if d.configurePins == nil {
|
||||||
|
return legacy.ErrConfigBeforeInstantiated
|
||||||
|
}
|
||||||
d.write1Byte(0xA4, 0x00)
|
d.write1Byte(0xA4, 0x00)
|
||||||
d.intPin.Configure(machine.PinConfig{Mode: machine.PinInputPulldown})
|
d.configurePins()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-15
@@ -5,12 +5,13 @@ package gc9a01 // import "tinygo.org/x/drivers/gc9a01"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Rotation controls the rotation used by the display.
|
// Rotation controls the rotation used by the display.
|
||||||
@@ -22,10 +23,10 @@ type FrameRate uint8
|
|||||||
// Device wraps an SPI connection.
|
// Device wraps an SPI connection.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
dcPin machine.Pin
|
dcPin drivers.PinOutput
|
||||||
resetPin machine.Pin
|
resetPin drivers.PinOutput
|
||||||
csPin machine.Pin
|
csPin drivers.PinOutput
|
||||||
blPin machine.Pin
|
blPin drivers.PinOutput
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
columnOffsetCfg int16
|
columnOffsetCfg int16
|
||||||
@@ -52,17 +53,17 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new ST7789 connection. The SPI wire must already be configured.
|
// New creates a new ST7789 connection. The SPI wire must already be configured.
|
||||||
func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin machine.Pin) Device {
|
func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin pin.Output) Device {
|
||||||
resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(resetPin)
|
||||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(dcPin)
|
||||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(csPin)
|
||||||
blPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(blPin)
|
||||||
return Device{
|
return Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
resetPin: resetPin,
|
resetPin: resetPin.Set,
|
||||||
dcPin: dcPin,
|
dcPin: dcPin.Set,
|
||||||
csPin: csPin,
|
csPin: csPin.Set,
|
||||||
blPin: blPin,
|
blPin: blPin.Set,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +227,7 @@ func (d *Device) Data(data uint8) {
|
|||||||
|
|
||||||
// Tx sends data to the display
|
// Tx sends data to the display
|
||||||
func (d *Device) Tx(data []byte, isCommand bool) {
|
func (d *Device) Tx(data []byte, isCommand bool) {
|
||||||
d.dcPin.Set(!isCommand)
|
d.dcPin(!isCommand)
|
||||||
d.bus.Tx(data, nil)
|
d.bus.Tx(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-7
@@ -69,16 +69,10 @@ func NewUART(uart drivers.UART) Device {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewI2C creates a new I2C GPS connection.
|
// NewI2C creates a new I2C GPS connection.
|
||||||
// Uses the default i2c address (0x42) for backward compatibility reasons.
|
|
||||||
func NewI2C(bus drivers.I2C) Device {
|
func NewI2C(bus drivers.I2C) Device {
|
||||||
return NewI2CWithAddress(bus, I2C_ADDRESS)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewI2CWithAddress creates a new I2C GPS connection on the provided address
|
|
||||||
func NewI2CWithAddress(bus drivers.I2C, i2cAddress uint16) Device {
|
|
||||||
return Device{
|
return Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
address: i2cAddress,
|
address: I2C_ADDRESS,
|
||||||
buffer: make([]byte, bufferSize),
|
buffer: make([]byte, bufferSize),
|
||||||
bufIdx: bufferSize,
|
bufIdx: bufferSize,
|
||||||
sentence: strings.Builder{},
|
sentence: strings.Builder{},
|
||||||
|
|||||||
+1
-5
@@ -4,11 +4,7 @@ package gps
|
|||||||
|
|
||||||
// The I2C address which this device listens to.
|
// The I2C address which this device listens to.
|
||||||
const (
|
const (
|
||||||
// To ensure backward compatibility
|
I2C_ADDRESS = 0x42
|
||||||
I2C_ADDRESS = UBLOX_I2C_ADDRESS
|
|
||||||
|
|
||||||
UBLOX_I2C_ADDRESS = 0x42
|
|
||||||
PA1010D_I2C_ADDRESS = 0x10
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
+20
-10
@@ -5,30 +5,40 @@
|
|||||||
package hcsr04
|
package hcsr04
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
const TIMEOUT = 23324 // max sensing distance (4m)
|
const TIMEOUT = 23324 // max sensing distance (4m)
|
||||||
|
|
||||||
// Device holds the pins
|
// Device holds the pins
|
||||||
type Device struct {
|
type Device struct {
|
||||||
trigger machine.Pin
|
trigger drivers.PinOutput
|
||||||
echo machine.Pin
|
echo drivers.PinInput
|
||||||
|
configurePins func()
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new ultrasonic driver given 2 pins
|
// New returns a new ultrasonic driver given 2 pins
|
||||||
func New(trigger, echo machine.Pin) Device {
|
func New(trigger pin.Output, echo pin.Input) Device {
|
||||||
return Device{
|
return Device{
|
||||||
trigger: trigger,
|
trigger: trigger.Set,
|
||||||
echo: echo,
|
echo: echo.Get,
|
||||||
|
configurePins: func() {
|
||||||
|
legacy.ConfigurePinOut(trigger)
|
||||||
|
legacy.ConfigurePinInput(echo)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure configures the pins of the Device
|
// Configure configures the pins of the Device
|
||||||
func (d *Device) Configure() {
|
func (d *Device) Configure() {
|
||||||
d.trigger.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
if d.configurePins == nil {
|
||||||
d.echo.Configure(machine.PinConfig{Mode: machine.PinInput})
|
panic(legacy.ErrConfigBeforeInstantiated)
|
||||||
|
}
|
||||||
|
d.configurePins()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadDistance returns the distance of the object in mm
|
// ReadDistance returns the distance of the object in mm
|
||||||
@@ -52,7 +62,7 @@ func (d *Device) ReadPulse() int32 {
|
|||||||
d.trigger.Low()
|
d.trigger.Low()
|
||||||
i := uint8(0)
|
i := uint8(0)
|
||||||
for {
|
for {
|
||||||
if d.echo.Get() {
|
if d.echo() {
|
||||||
t = time.Now()
|
t = time.Now()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -66,7 +76,7 @@ func (d *Device) ReadPulse() int32 {
|
|||||||
}
|
}
|
||||||
i = 0
|
i = 0
|
||||||
for {
|
for {
|
||||||
if !d.echo.Get() {
|
if !d.echo() {
|
||||||
return int32(time.Since(t).Microseconds())
|
return int32(time.Since(t).Microseconds())
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
|
|||||||
+5
-5
@@ -210,7 +210,7 @@ func (d *Device) SendCommand(command byte) {
|
|||||||
d.bus.SetCommandMode(true)
|
d.bus.SetCommandMode(true)
|
||||||
d.bus.Write([]byte{command})
|
d.bus.Write([]byte{command})
|
||||||
|
|
||||||
for d.busy(command == DISPLAY_CLEAR || command == CURSOR_HOME) {
|
for d.isBusy(command == DISPLAY_CLEAR || command == CURSOR_HOME) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ func (d *Device) sendData(data byte) {
|
|||||||
d.bus.SetCommandMode(false)
|
d.bus.SetCommandMode(false)
|
||||||
d.bus.Write([]byte{data})
|
d.bus.Write([]byte{data})
|
||||||
|
|
||||||
for d.busy(false) {
|
for d.isBusy(false) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,9 +231,9 @@ func (d *Device) CreateCharacter(cgramAddr uint8, data []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// busy returns true when hd447890 is busy
|
// isBusy returns true when hd447890 is isBusy
|
||||||
// or after the timeout specified
|
// or after the timeout specified
|
||||||
func (d *Device) busy(longDelay bool) bool {
|
func (d *Device) isBusy(longDelay bool) bool {
|
||||||
if d.bus.WriteOnly() {
|
if d.bus.WriteOnly() {
|
||||||
// Can't read busy flag if write only, so sleep a bit then return
|
// Can't read busy flag if write only, so sleep a bit then return
|
||||||
if longDelay {
|
if longDelay {
|
||||||
@@ -261,7 +261,7 @@ func (d *Device) busy(longDelay bool) bool {
|
|||||||
|
|
||||||
// Busy returns true when hd447890 is busy
|
// Busy returns true when hd447890 is busy
|
||||||
func (d *Device) Busy() bool {
|
func (d *Device) Busy() bool {
|
||||||
return d.busy(false)
|
return d.isBusy(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns the current size of the display.
|
// Size returns the current size of the display.
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package legacy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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,11 @@
|
|||||||
|
//go:build !baremetal
|
||||||
|
|
||||||
|
package legacy
|
||||||
|
|
||||||
|
import "tinygo.org/x/drivers/internal/pin"
|
||||||
|
|
||||||
|
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,23 @@
|
|||||||
|
package pin
|
||||||
|
|
||||||
|
import "tinygo.org/x/drivers"
|
||||||
|
|
||||||
|
// Here to aid relevant documentation links of [drivers.PinOutput] and [drivers.PinInput].
|
||||||
|
var _ drivers.PinOutput
|
||||||
|
|
||||||
|
// Output represents a pin hardware abstraction layer for a pin that can output a digital signal.
|
||||||
|
//
|
||||||
|
// This is an alternative to [drivers.PinOutput] abstraction which is a function type and has
|
||||||
|
// not been standardized as of yet as a standard HAL in the drivers package,
|
||||||
|
// [discussion ongoing here].
|
||||||
|
//
|
||||||
|
// [discussion ongoing here]: https://github.com/orgs/tinygo-org/discussions/5043
|
||||||
|
type Output interface {
|
||||||
|
Set(level bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input represents a pin hardware abstraction layer.
|
||||||
|
// See [Output] for more information on why this type exists separate to drivers.
|
||||||
|
type Input interface {
|
||||||
|
Get() (level bool)
|
||||||
|
}
|
||||||
+24
-35
@@ -8,6 +8,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AccelRange uint8
|
type AccelRange uint8
|
||||||
@@ -25,7 +26,7 @@ type Device struct {
|
|||||||
accelSampleRate AccelSampleRate
|
accelSampleRate AccelSampleRate
|
||||||
gyroRange GyroRange
|
gyroRange GyroRange
|
||||||
gyroSampleRate GyroSampleRate
|
gyroSampleRate GyroSampleRate
|
||||||
buf [7]uint8 // up to 6 bytes for read + 1 byte for the register address
|
buf [6]uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configuration for LSM6DS3TR device.
|
// Configuration for LSM6DS3TR device.
|
||||||
@@ -83,20 +84,30 @@ func (d *Device) doConfigure(cfg Configuration) (err error) {
|
|||||||
d.gyroSampleRate = GYRO_SR_104
|
d.gyroSampleRate = GYRO_SR_104
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data := d.buf[:1]
|
||||||
|
|
||||||
// Configure accelerometer
|
// Configure accelerometer
|
||||||
err = d.writeByte(CTRL1_XL, uint8(d.accelRange)|uint8(d.accelSampleRate))
|
data[0] = uint8(d.accelRange) | uint8(d.accelSampleRate)
|
||||||
|
err = legacy.WriteRegister(d.bus, uint8(d.Address), CTRL1_XL, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable ODR scaling
|
// Set ODR bit
|
||||||
err = d.setBits(CTRL4_C, BW_SCAL_ODR_ENABLED)
|
err = legacy.ReadRegister(d.bus, uint8(d.Address), CTRL4_C, data)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data[0] = data[0] &^ BW_SCAL_ODR_ENABLED
|
||||||
|
data[0] |= BW_SCAL_ODR_ENABLED
|
||||||
|
err = legacy.WriteRegister(d.bus, uint8(d.Address), CTRL4_C, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure gyroscope
|
// Configure gyroscope
|
||||||
err = d.writeByte(CTRL2_G, uint8(d.gyroRange)|uint8(d.gyroSampleRate))
|
data[0] = uint8(d.gyroRange) | uint8(d.gyroSampleRate)
|
||||||
|
err = legacy.WriteRegister(d.bus, uint8(d.Address), CTRL2_G, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -107,10 +118,8 @@ func (d *Device) doConfigure(cfg Configuration) (err error) {
|
|||||||
// Connected returns whether a LSM6DS3TR has been found.
|
// Connected returns whether a LSM6DS3TR has been found.
|
||||||
// It does a "who am I" request and checks the response.
|
// It does a "who am I" request and checks the response.
|
||||||
func (d *Device) Connected() bool {
|
func (d *Device) Connected() bool {
|
||||||
data, err := d.readBytes(WHO_AM_I, 1)
|
data := d.buf[:1]
|
||||||
if err != nil {
|
legacy.ReadRegister(d.bus, uint8(d.Address), WHO_AM_I, data)
|
||||||
return false
|
|
||||||
}
|
|
||||||
return data[0] == 0x6A
|
return data[0] == 0x6A
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +128,8 @@ func (d *Device) Connected() bool {
|
|||||||
// and the sensor is not moving the returned value will be around 1000000 or
|
// and the sensor is not moving the returned value will be around 1000000 or
|
||||||
// -1000000.
|
// -1000000.
|
||||||
func (d *Device) ReadAcceleration() (x, y, z int32, err error) {
|
func (d *Device) ReadAcceleration() (x, y, z int32, err error) {
|
||||||
data, err := d.readBytes(OUTX_L_XL, 6)
|
data := d.buf[:6]
|
||||||
|
err = legacy.ReadRegister(d.bus, uint8(d.Address), OUTX_L_XL, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -143,7 +153,8 @@ func (d *Device) ReadAcceleration() (x, y, z int32, err error) {
|
|||||||
// rotation along one axis and while doing so integrate all values over time,
|
// rotation along one axis and while doing so integrate all values over time,
|
||||||
// you would get a value close to 360000000.
|
// you would get a value close to 360000000.
|
||||||
func (d *Device) ReadRotation() (x, y, z int32, err error) {
|
func (d *Device) ReadRotation() (x, y, z int32, err error) {
|
||||||
data, err := d.readBytes(OUTX_L_G, 6)
|
data := d.buf[:6]
|
||||||
|
err = legacy.ReadRegister(d.bus, uint8(d.Address), OUTX_L_G, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -166,7 +177,8 @@ func (d *Device) ReadRotation() (x, y, z int32, err error) {
|
|||||||
|
|
||||||
// ReadTemperature returns the temperature in celsius milli degrees (°C/1000)
|
// ReadTemperature returns the temperature in celsius milli degrees (°C/1000)
|
||||||
func (d *Device) ReadTemperature() (t int32, err error) {
|
func (d *Device) ReadTemperature() (t int32, err error) {
|
||||||
data, err := d.readBytes(OUT_TEMP_L, 2)
|
data := d.buf[:2]
|
||||||
|
err = legacy.ReadRegister(d.bus, uint8(d.Address), OUT_TEMP_L, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -175,26 +187,3 @@ func (d *Device) ReadTemperature() (t int32, err error) {
|
|||||||
t = 25000 + (int32(int16((int16(data[1])<<8)|int16(data[0])))*125)/32
|
t = 25000 + (int32(int16((int16(data[1])<<8)|int16(data[0])))*125)/32
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) readBytes(reg, size uint8) ([]byte, error) {
|
|
||||||
d.buf[0] = reg
|
|
||||||
err := d.bus.Tx(d.Address, d.buf[0:1], d.buf[1:size+1])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return d.buf[1 : size+1], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) writeByte(reg, value uint8) error {
|
|
||||||
d.buf[0] = reg
|
|
||||||
d.buf[1] = value
|
|
||||||
return d.bus.Tx(d.Address, d.buf[0:2], nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) setBits(reg, bits uint8) error {
|
|
||||||
data, err := d.readBytes(reg, 1)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return d.writeByte(reg, (data[0]&^bits)|bits)
|
|
||||||
}
|
|
||||||
|
|||||||
+4
-4
@@ -3,9 +3,9 @@ package max6675
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrThermocoupleOpen is returned when the thermocouple input is open.
|
// ErrThermocoupleOpen is returned when the thermocouple input is open.
|
||||||
@@ -14,16 +14,16 @@ var ErrThermocoupleOpen = errors.New("thermocouple input open")
|
|||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new Device to read from a MAX6675 thermocouple.
|
// Create a new Device to read from a MAX6675 thermocouple.
|
||||||
// Pins must be configured before use. Frequency for SPI
|
// Pins must be configured before use. Frequency for SPI
|
||||||
// should be 4.3MHz maximum.
|
// should be 4.3MHz maximum.
|
||||||
func NewDevice(bus drivers.SPI, cs machine.Pin) *Device {
|
func NewDevice(bus drivers.SPI, cs pin.Output) *Device {
|
||||||
return &Device{
|
return &Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
cs: cs,
|
cs: cs.Set,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-9
@@ -3,31 +3,36 @@
|
|||||||
package max72xx
|
package max72xx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
|
configurePins func()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDriver creates a new max7219 connection. The SPI wire must already be configured
|
// NewDriver creates a new max7219 connection. The SPI wire must already be configured
|
||||||
// The SPI frequency must not be higher than 10MHz.
|
// The SPI frequency must not be higher than 10MHz.
|
||||||
// parameter cs: the datasheet also refers to this pin as "load" pin.
|
// parameter cs: the datasheet also refers to this pin as "load" pin.
|
||||||
func NewDevice(bus drivers.SPI, cs machine.Pin) *Device {
|
func NewDevice(bus drivers.SPI, cs pin.Output) *Device {
|
||||||
return &Device{
|
return &Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
cs: cs,
|
cs: cs.Set,
|
||||||
|
configurePins: func() {
|
||||||
|
legacy.ConfigurePinOut(cs)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure setups the pins.
|
// Configure setups the pins.
|
||||||
func (driver *Device) Configure() {
|
func (driver *Device) Configure() {
|
||||||
outPutConfig := machine.PinConfig{Mode: machine.PinOutput}
|
if driver.configurePins == nil {
|
||||||
|
panic(legacy.ErrConfigBeforeInstantiated)
|
||||||
driver.cs.Configure(outPutConfig)
|
}
|
||||||
|
driver.configurePins()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetScanLimit sets the scan limit. Maximum is 8.
|
// SetScanLimit sets the scan limit. Maximum is 8.
|
||||||
|
|||||||
+16
-8
@@ -8,18 +8,20 @@ package mcp2515 // import "tinygo.org/x/drivers/mcp2515"
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Device wraps MCP2515 SPI CAN Module.
|
// Device wraps MCP2515 SPI CAN Module.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
spi SPI
|
spi SPI
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
msg *CANMsg
|
msg *CANMsg
|
||||||
mcpMode byte
|
mcpMode byte
|
||||||
|
configurePins func()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CANMsg stores CAN message fields.
|
// CANMsg stores CAN message fields.
|
||||||
@@ -36,15 +38,18 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// New returns a new MCP2515 driver. Pass in a fully configured SPI bus.
|
// New returns a new MCP2515 driver. Pass in a fully configured SPI bus.
|
||||||
func New(b drivers.SPI, csPin machine.Pin) *Device {
|
func New(b drivers.SPI, csPin pin.Output) *Device {
|
||||||
d := &Device{
|
d := &Device{
|
||||||
spi: SPI{
|
spi: SPI{
|
||||||
bus: b,
|
bus: b,
|
||||||
tx: make([]byte, 0, bufferSize),
|
tx: make([]byte, 0, bufferSize),
|
||||||
rx: make([]byte, 0, bufferSize),
|
rx: make([]byte, 0, bufferSize),
|
||||||
},
|
},
|
||||||
cs: csPin,
|
cs: csPin.Set,
|
||||||
msg: &CANMsg{},
|
msg: &CANMsg{},
|
||||||
|
configurePins: func() {
|
||||||
|
legacy.ConfigurePinOut(csPin)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return d
|
return d
|
||||||
@@ -52,7 +57,10 @@ func New(b drivers.SPI, csPin machine.Pin) *Device {
|
|||||||
|
|
||||||
// Configure sets up the device for communication.
|
// Configure sets up the device for communication.
|
||||||
func (d *Device) Configure() {
|
func (d *Device) Configure() {
|
||||||
d.cs.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
if d.configurePins == nil {
|
||||||
|
panic(legacy.ErrConfigBeforeInstantiated)
|
||||||
|
}
|
||||||
|
d.configurePins()
|
||||||
}
|
}
|
||||||
|
|
||||||
const beginTimeoutValue int = 10
|
const beginTimeoutValue int = 10
|
||||||
|
|||||||
+24
-16
@@ -5,8 +5,9 @@ package onewire // import "tinygo.org/x/drivers/onewire"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OneWire ROM commands
|
// OneWire ROM commands
|
||||||
@@ -19,7 +20,8 @@ const (
|
|||||||
|
|
||||||
// Device wraps a connection to an 1-Wire devices.
|
// Device wraps a connection to an 1-Wire devices.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
p machine.Pin
|
set drivers.PinOutput
|
||||||
|
get drivers.PinInput
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config wraps a configuration to an 1-Wire devices.
|
// Config wraps a configuration to an 1-Wire devices.
|
||||||
@@ -32,24 +34,30 @@ var (
|
|||||||
errReadAddress = errors.New("Error: OneWire. Read address error: CRC mismatch.")
|
errReadAddress = errors.New("Error: OneWire. Read address error: CRC mismatch.")
|
||||||
)
|
)
|
||||||
|
|
||||||
// New creates a new GPIO 1-Wire connection.
|
// NewFromFuncs expects pin setter and getter for DQ line. Ideally this driver should receive
|
||||||
// The pin must be pulled up to the VCC via a resistor greater than 500 ohms (default 4.7k).
|
// a one-wire bus HAL abstraction, but I was asked to show how this could be done using pin HAL so here goes.
|
||||||
func New(p machine.Pin) Device {
|
func NewFromFuncs(getPinLevel drivers.PinInput, setPinLevel drivers.PinOutput) *Device {
|
||||||
return Device{
|
return &Device{
|
||||||
p: p,
|
set: setPinLevel,
|
||||||
|
get: getPinLevel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure initializes the protocol.
|
// Configure initializes the protocol.
|
||||||
func (d *Device) Configure(config Config) {}
|
func (d *Device) Configure(config Config) {}
|
||||||
|
|
||||||
|
// By setting the pin value one should configure as output and also expect a more
|
||||||
|
// consistent behaviour across all tinygo hosts by pulling DQ line low consistently. Win-win.
|
||||||
|
func (d *Device) cfgOut() { d.set.Low() }
|
||||||
|
func (d *Device) cfgIn() { d.get() }
|
||||||
|
|
||||||
// Reset pull DQ line low, then up.
|
// Reset pull DQ line low, then up.
|
||||||
func (d Device) Reset() error {
|
func (d Device) Reset() error {
|
||||||
d.p.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
d.cfgOut()
|
||||||
time.Sleep(480 * time.Microsecond)
|
time.Sleep(480 * time.Microsecond)
|
||||||
d.p.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
|
d.cfgIn()
|
||||||
time.Sleep(70 * time.Microsecond)
|
time.Sleep(70 * time.Microsecond)
|
||||||
precence := d.p.Get()
|
precence := d.get()
|
||||||
time.Sleep(410 * time.Microsecond)
|
time.Sleep(410 * time.Microsecond)
|
||||||
if precence {
|
if precence {
|
||||||
return errNoPresence
|
return errNoPresence
|
||||||
@@ -59,14 +67,14 @@ func (d Device) Reset() error {
|
|||||||
|
|
||||||
// WriteBit transmits a bit to 1-Wire bus.
|
// WriteBit transmits a bit to 1-Wire bus.
|
||||||
func (d Device) WriteBit(data uint8) {
|
func (d Device) WriteBit(data uint8) {
|
||||||
d.p.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
d.cfgOut()
|
||||||
if data&1 == 1 { // Send '1'
|
if data&1 == 1 { // Send '1'
|
||||||
time.Sleep(5 * time.Microsecond)
|
time.Sleep(5 * time.Microsecond)
|
||||||
d.p.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
|
d.cfgIn()
|
||||||
time.Sleep(60 * time.Microsecond)
|
time.Sleep(60 * time.Microsecond)
|
||||||
} else { // Send '0'
|
} else { // Send '0'
|
||||||
time.Sleep(60 * time.Microsecond)
|
time.Sleep(60 * time.Microsecond)
|
||||||
d.p.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
|
d.cfgIn()
|
||||||
time.Sleep(5 * time.Microsecond)
|
time.Sleep(5 * time.Microsecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,11 +89,11 @@ func (d Device) Write(data uint8) {
|
|||||||
|
|
||||||
// ReadBit receives a bit from 1-Wire bus.
|
// ReadBit receives a bit from 1-Wire bus.
|
||||||
func (d Device) ReadBit() (data uint8) {
|
func (d Device) ReadBit() (data uint8) {
|
||||||
d.p.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
d.cfgOut()
|
||||||
time.Sleep(3 * time.Microsecond)
|
time.Sleep(3 * time.Microsecond)
|
||||||
d.p.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
|
d.cfgIn()
|
||||||
time.Sleep(8 * time.Microsecond)
|
time.Sleep(8 * time.Microsecond)
|
||||||
if d.p.Get() {
|
if d.get() {
|
||||||
data = 1
|
data = 1
|
||||||
}
|
}
|
||||||
time.Sleep(60 * time.Microsecond)
|
time.Sleep(60 * time.Microsecond)
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package onewire
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New creates a new GPIO 1-Wire connection.
|
||||||
|
// The pin must be pulled up to the VCC via a resistor greater than 500 ohms (default 4.7k).
|
||||||
|
func New(p machine.Pin) Device {
|
||||||
|
isOut := false
|
||||||
|
return Device{
|
||||||
|
set: func(level bool) {
|
||||||
|
if !isOut {
|
||||||
|
legacy.ConfigurePinOut(p)
|
||||||
|
isOut = true
|
||||||
|
}
|
||||||
|
p.Set(level)
|
||||||
|
},
|
||||||
|
get: func() (level bool) {
|
||||||
|
if isOut {
|
||||||
|
legacy.ConfigurePinInputPullup(p)
|
||||||
|
isOut = false
|
||||||
|
}
|
||||||
|
return p.Get()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-8
@@ -6,18 +6,18 @@ package pcd8544 // import "tinygo.org/x/drivers/pcd8544"
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Device wraps an SPI connection.
|
// Device wraps an SPI connection.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
dcPin machine.Pin
|
dcPin drivers.PinOutput
|
||||||
rstPin machine.Pin
|
rstPin drivers.PinOutput
|
||||||
scePin machine.Pin
|
scePin drivers.PinOutput
|
||||||
buffer []byte
|
buffer []byte
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
@@ -30,12 +30,12 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new PCD8544 connection. The SPI bus must already be configured.
|
// New creates a new PCD8544 connection. The SPI bus must already be configured.
|
||||||
func New(bus drivers.SPI, dcPin, rstPin, scePin machine.Pin) *Device {
|
func New(bus drivers.SPI, dcPin, rstPin, scePin pin.Output) *Device {
|
||||||
return &Device{
|
return &Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
dcPin: dcPin,
|
dcPin: dcPin.Set,
|
||||||
rstPin: rstPin,
|
rstPin: rstPin.Set,
|
||||||
scePin: scePin,
|
scePin: scePin.Set,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package drivers
|
||||||
|
|
||||||
|
// PinOutput is hardware abstraction for a pin which outputs a
|
||||||
|
// digital signal (high or low level).
|
||||||
|
//
|
||||||
|
// // Code conversion demo: from machine.Pin to drivers.PinOutput
|
||||||
|
// led := machine.LED
|
||||||
|
// led.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
// var pin drivers.PinOutput = led.Set // Going from a machine.Pin to a drivers.PinOutput
|
||||||
|
type PinOutput func(level bool)
|
||||||
|
|
||||||
|
// High sets the underlying pin's level to high. This is equivalent to calling PinOutput(true).
|
||||||
|
func (po PinOutput) High() {
|
||||||
|
po(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Low sets the underlying pin's level to low. This is equivalent to calling PinOutput(false).
|
||||||
|
func (po PinOutput) Low() {
|
||||||
|
po(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PinInput 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 drivers.PinInput
|
||||||
|
// input := machine.LED
|
||||||
|
// input.Configure(machine.PinConfig{Mode: machine.PinInputPulldown}) // or use machine.PinInputPullup or machine.PinInput
|
||||||
|
// var pin drivers.PinInput = input.Get // Going from a machine.Pin to a drivers.PinInput
|
||||||
|
type PinInput func() (level bool)
|
||||||
@@ -2,7 +2,9 @@
|
|||||||
package shiftregister
|
package shiftregister
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"machine"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NumberBit int8
|
type NumberBit int8
|
||||||
@@ -16,9 +18,10 @@ const (
|
|||||||
|
|
||||||
// Device holds pin number
|
// Device holds pin number
|
||||||
type Device struct {
|
type Device struct {
|
||||||
latch, clock, out machine.Pin // IC wiring
|
latch, clock, out drivers.PinOutput // IC wiring
|
||||||
bits NumberBit // Pin number
|
config func()
|
||||||
mask uint32 // keep all pins state
|
bits NumberBit // Pin number
|
||||||
|
mask uint32 // keep all pins state
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShiftPin is the implementation of the ShiftPin interface.
|
// ShiftPin is the implementation of the ShiftPin interface.
|
||||||
@@ -29,20 +32,25 @@ type ShiftPin struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new shift output register device
|
// New returns a new shift output register device
|
||||||
func New(Bits NumberBit, Latch, Clock, Out machine.Pin) *Device {
|
func New(Bits NumberBit, Latch, Clock, Out pin.Output) *Device {
|
||||||
return &Device{
|
return &Device{
|
||||||
latch: Latch,
|
latch: Latch.Set,
|
||||||
clock: Clock,
|
clock: Clock.Set,
|
||||||
out: Out,
|
out: Out.Set,
|
||||||
bits: Bits,
|
bits: Bits,
|
||||||
|
config: func() {
|
||||||
|
legacy.ConfigurePinOut(Latch)
|
||||||
|
legacy.ConfigurePinOut(Clock)
|
||||||
|
legacy.ConfigurePinOut(Out)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure set hardware configuration
|
// Configure set hardware configuration
|
||||||
func (d *Device) Configure() {
|
func (d *Device) Configure() {
|
||||||
d.latch.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
if d.config == nil {
|
||||||
d.clock.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
panic(legacy.ErrConfigBeforeInstantiated)
|
||||||
d.out.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
}
|
||||||
d.latch.High()
|
d.latch.High()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +61,7 @@ func (d *Device) WriteMask(mask uint32) {
|
|||||||
d.latch.Low()
|
d.latch.Low()
|
||||||
for i := 0; i < int(d.bits); i++ {
|
for i := 0; i < int(d.bits); i++ {
|
||||||
d.clock.Low()
|
d.clock.Low()
|
||||||
d.out.Set(mask&1 != 0)
|
d.out(mask&1 != 0)
|
||||||
mask = mask >> 1
|
mask = mask >> 1
|
||||||
d.clock.High()
|
d.clock.High()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -65,8 +65,8 @@ tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/shifter/
|
|||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht4x/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht4x/main.go
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/shtc3/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/shtc3/main.go
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/i2c_128x32/main.go
|
||||||
tinygo build -size short -o ./build/test.hex -target=thumby ./examples/ssd1306/
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/spi_128x64/main.go
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1331/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1331/main.go
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7735/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7735/main.go
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7789/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7789/main.go
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//go:build baremetal
|
||||||
|
|
||||||
package ssd1289
|
package ssd1289
|
||||||
|
|
||||||
import "machine"
|
import "machine"
|
||||||
|
|||||||
+18
-16
@@ -7,6 +7,9 @@ import (
|
|||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
"machine"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Bus interface {
|
type Bus interface {
|
||||||
@@ -14,10 +17,10 @@ type Bus interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
rs machine.Pin
|
rs drivers.PinOutput
|
||||||
wr machine.Pin
|
wr drivers.PinOutput
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
rst machine.Pin
|
rst drivers.PinOutput
|
||||||
bus Bus
|
bus Bus
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,21 +29,20 @@ const height = int16(320)
|
|||||||
|
|
||||||
func New(rs machine.Pin, wr machine.Pin, cs machine.Pin, rst machine.Pin, bus Bus) Device {
|
func New(rs machine.Pin, wr machine.Pin, cs machine.Pin, rst machine.Pin, bus Bus) Device {
|
||||||
d := Device{
|
d := Device{
|
||||||
rs: rs,
|
rs: rs.Set,
|
||||||
wr: wr,
|
wr: wr.Set,
|
||||||
cs: cs,
|
cs: cs.Set,
|
||||||
rst: rst,
|
rst: rst.Set,
|
||||||
bus: bus,
|
bus: bus,
|
||||||
}
|
}
|
||||||
|
legacy.ConfigurePinOut(rs)
|
||||||
|
legacy.ConfigurePinOut(wr)
|
||||||
|
legacy.ConfigurePinOut(cs)
|
||||||
|
legacy.ConfigurePinOut(rst)
|
||||||
|
|
||||||
rs.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
cs.Set(true)
|
||||||
wr.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
rst.Set(true)
|
||||||
cs.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
wr.Set(true)
|
||||||
rst.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
|
||||||
|
|
||||||
cs.High()
|
|
||||||
rst.High()
|
|
||||||
wr.High()
|
|
||||||
|
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ func (b *SPIBus) tx(data []byte, isCommand bool) error {
|
|||||||
|
|
||||||
if isCommand {
|
if isCommand {
|
||||||
b.csPin.High()
|
b.csPin.High()
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
b.dcPin.Low()
|
b.dcPin.Low()
|
||||||
b.csPin.Low()
|
b.csPin.Low()
|
||||||
|
|
||||||
@@ -329,6 +330,7 @@ func (b *SPIBus) tx(data []byte, isCommand bool) error {
|
|||||||
b.csPin.High()
|
b.csPin.High()
|
||||||
} else {
|
} else {
|
||||||
b.csPin.High()
|
b.csPin.High()
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
b.dcPin.High()
|
b.dcPin.High()
|
||||||
b.csPin.Low()
|
b.csPin.Low()
|
||||||
|
|
||||||
|
|||||||
+11
-10
@@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Model uint8
|
type Model uint8
|
||||||
@@ -19,9 +20,9 @@ type Rotation uint8
|
|||||||
// Device wraps an SPI connection.
|
// Device wraps an SPI connection.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
dcPin machine.Pin
|
dcPin drivers.PinOutput
|
||||||
resetPin machine.Pin
|
resetPin drivers.PinOutput
|
||||||
csPin machine.Pin
|
csPin drivers.PinOutput
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
batchLength int16
|
batchLength int16
|
||||||
@@ -37,14 +38,14 @@ type Config struct {
|
|||||||
|
|
||||||
// New creates a new SSD1331 connection. The SPI wire must already be configured.
|
// New creates a new SSD1331 connection. The SPI wire must already be configured.
|
||||||
func New(bus drivers.SPI, resetPin, dcPin, csPin machine.Pin) Device {
|
func New(bus drivers.SPI, resetPin, dcPin, csPin machine.Pin) Device {
|
||||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(dcPin)
|
||||||
resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(resetPin)
|
||||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(csPin)
|
||||||
return Device{
|
return Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
dcPin: dcPin,
|
dcPin: dcPin.Set,
|
||||||
resetPin: resetPin,
|
resetPin: resetPin.Set,
|
||||||
csPin: csPin,
|
csPin: csPin.Set,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +252,7 @@ func (d *Device) Data(data uint8) {
|
|||||||
|
|
||||||
// Tx sends data to the display
|
// Tx sends data to the display
|
||||||
func (d *Device) Tx(data []byte, isCommand bool) {
|
func (d *Device) Tx(data []byte, isCommand bool) {
|
||||||
d.dcPin.Set(!isCommand)
|
d.dcPin(!isCommand)
|
||||||
d.bus.Tx(data, nil)
|
d.bus.Tx(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+32
-24
@@ -6,10 +6,11 @@ package ssd1351 // import "tinygo.org/x/drivers/ssd1351"
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -19,17 +20,18 @@ var (
|
|||||||
|
|
||||||
// Device wraps an SPI connection.
|
// Device wraps an SPI connection.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
dcPin machine.Pin
|
dcPin drivers.PinOutput
|
||||||
resetPin machine.Pin
|
resetPin drivers.PinOutput
|
||||||
csPin machine.Pin
|
csPin drivers.PinOutput
|
||||||
enPin machine.Pin
|
enPin drivers.PinOutput
|
||||||
rwPin machine.Pin
|
rwPin drivers.PinOutput
|
||||||
width int16
|
configurePins func()
|
||||||
height int16
|
width int16
|
||||||
rowOffset int16
|
height int16
|
||||||
columnOffset int16
|
rowOffset int16
|
||||||
bufferLength int16
|
columnOffset int16
|
||||||
|
bufferLength int16
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is the configuration for the display
|
// Config is the configuration for the display
|
||||||
@@ -41,19 +43,29 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new SSD1351 connection. The SPI wire must already be configured.
|
// New creates a new SSD1351 connection. The SPI wire must already be configured.
|
||||||
func New(bus drivers.SPI, resetPin, dcPin, csPin, enPin, rwPin machine.Pin) Device {
|
func New(bus drivers.SPI, resetPin, dcPin, csPin, enPin, rwPin pin.Output) Device {
|
||||||
return Device{
|
return Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
dcPin: dcPin,
|
dcPin: dcPin.Set,
|
||||||
resetPin: resetPin,
|
resetPin: resetPin.Set,
|
||||||
csPin: csPin,
|
csPin: csPin.Set,
|
||||||
enPin: enPin,
|
enPin: enPin.Set,
|
||||||
rwPin: rwPin,
|
rwPin: rwPin.Set,
|
||||||
|
configurePins: func() {
|
||||||
|
legacy.ConfigurePinOut(dcPin)
|
||||||
|
legacy.ConfigurePinOut(resetPin)
|
||||||
|
legacy.ConfigurePinOut(csPin)
|
||||||
|
legacy.ConfigurePinOut(enPin)
|
||||||
|
legacy.ConfigurePinOut(rwPin)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure initializes the display with default configuration
|
// Configure initializes the display with default configuration
|
||||||
func (d *Device) Configure(cfg Config) {
|
func (d *Device) Configure(cfg Config) {
|
||||||
|
if d.configurePins == nil {
|
||||||
|
panic(legacy.ErrConfigBeforeInstantiated)
|
||||||
|
}
|
||||||
if cfg.Width == 0 {
|
if cfg.Width == 0 {
|
||||||
cfg.Width = 128
|
cfg.Width = 128
|
||||||
}
|
}
|
||||||
@@ -73,11 +85,7 @@ func (d *Device) Configure(cfg Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// configure GPIO pins
|
// configure GPIO pins
|
||||||
d.dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
d.configurePins()
|
||||||
d.resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
|
||||||
d.csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
|
||||||
d.enPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
|
||||||
d.rwPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
|
||||||
|
|
||||||
// reset the device
|
// reset the device
|
||||||
d.resetPin.High()
|
d.resetPin.High()
|
||||||
@@ -278,7 +286,7 @@ func (d *Device) Data(data uint8) {
|
|||||||
|
|
||||||
// Tx sends data to the display
|
// Tx sends data to the display
|
||||||
func (d *Device) Tx(data []byte, isCommand bool) {
|
func (d *Device) Tx(data []byte, isCommand bool) {
|
||||||
d.dcPin.Set(!isCommand)
|
d.dcPin(!isCommand)
|
||||||
d.csPin.Low()
|
d.csPin.Low()
|
||||||
d.bus.Tx(data, nil)
|
d.bus.Tx(data, nil)
|
||||||
d.csPin.High()
|
d.csPin.High()
|
||||||
|
|||||||
+17
-16
@@ -5,12 +5,13 @@ package st7735 // import "tinygo.org/x/drivers/st7735"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
"tinygo.org/x/drivers/pixel"
|
"tinygo.org/x/drivers/pixel"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -39,10 +40,10 @@ type Device = DeviceOf[pixel.RGB565BE]
|
|||||||
// formats.
|
// formats.
|
||||||
type DeviceOf[T Color] struct {
|
type DeviceOf[T Color] struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
dcPin machine.Pin
|
dcPin drivers.PinOutput
|
||||||
resetPin machine.Pin
|
resetPin drivers.PinOutput
|
||||||
csPin machine.Pin
|
csPin drivers.PinOutput
|
||||||
blPin machine.Pin
|
blPin drivers.PinOutput
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
columnOffset int16
|
columnOffset int16
|
||||||
@@ -65,23 +66,23 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new ST7735 connection. The SPI wire must already be configured.
|
// New creates a new ST7735 connection. The SPI wire must already be configured.
|
||||||
func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin machine.Pin) Device {
|
func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin pin.Output) Device {
|
||||||
return NewOf[pixel.RGB565BE](bus, resetPin, dcPin, csPin, blPin)
|
return NewOf[pixel.RGB565BE](bus, resetPin, dcPin, csPin, blPin)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOf creates a new ST7735 connection with a particular pixel format. The SPI
|
// NewOf creates a new ST7735 connection with a particular pixel format. The SPI
|
||||||
// wire must already be configured.
|
// wire must already be configured.
|
||||||
func NewOf[T Color](bus drivers.SPI, resetPin, dcPin, csPin, blPin machine.Pin) DeviceOf[T] {
|
func NewOf[T Color](bus drivers.SPI, resetPin, dcPin, csPin, blPin pin.Output) DeviceOf[T] {
|
||||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(dcPin)
|
||||||
resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(resetPin)
|
||||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(csPin)
|
||||||
blPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(blPin)
|
||||||
return DeviceOf[T]{
|
return DeviceOf[T]{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
dcPin: dcPin,
|
dcPin: dcPin.Set,
|
||||||
resetPin: resetPin,
|
resetPin: resetPin.Set,
|
||||||
csPin: csPin,
|
csPin: csPin.Set,
|
||||||
blPin: blPin,
|
blPin: blPin.Set,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +424,7 @@ func (d *DeviceOf[T]) Data(data uint8) {
|
|||||||
|
|
||||||
// Tx sends data to the display
|
// Tx sends data to the display
|
||||||
func (d *DeviceOf[T]) Tx(data []byte, isCommand bool) {
|
func (d *DeviceOf[T]) Tx(data []byte, isCommand bool) {
|
||||||
d.dcPin.Set(!isCommand)
|
d.dcPin(!isCommand)
|
||||||
d.bus.Tx(data, nil)
|
d.bus.Tx(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-17
@@ -7,13 +7,14 @@ package st7789 // import "tinygo.org/x/drivers/st7789"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
"tinygo.org/x/drivers/pixel"
|
"tinygo.org/x/drivers/pixel"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -46,10 +47,10 @@ type Device = DeviceOf[pixel.RGB565BE]
|
|||||||
// formats.
|
// formats.
|
||||||
type DeviceOf[T Color] struct {
|
type DeviceOf[T Color] struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
dcPin machine.Pin
|
dcPin drivers.PinOutput
|
||||||
resetPin machine.Pin
|
resetPin drivers.PinOutput
|
||||||
csPin machine.Pin
|
csPin drivers.PinOutput
|
||||||
blPin machine.Pin
|
blPin drivers.PinOutput
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
columnOffsetCfg int16
|
columnOffsetCfg int16
|
||||||
@@ -83,23 +84,27 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new ST7789 connection. The SPI wire must already be configured.
|
// New creates a new ST7789 connection. The SPI wire must already be configured.
|
||||||
func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin machine.Pin) Device {
|
func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin pin.Output) Device {
|
||||||
return NewOf[pixel.RGB565BE](bus, resetPin, dcPin, csPin, blPin)
|
return NewOf[pixel.RGB565BE](bus, resetPin, dcPin, csPin, blPin)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOf creates a new ST7789 connection with a particular pixel format. The SPI
|
// NewOf creates a new ST7789 connection with a particular pixel format. The SPI
|
||||||
// wire must already be configured.
|
// wire must already be configured.
|
||||||
func NewOf[T Color](bus drivers.SPI, resetPin, dcPin, csPin, blPin machine.Pin) DeviceOf[T] {
|
func NewOf[T Color](bus drivers.SPI, resetPin, dcPin, csPin, blPin pin.Output) DeviceOf[T] {
|
||||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(dcPin)
|
||||||
resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(resetPin)
|
||||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(csPin)
|
||||||
blPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(blPin)
|
||||||
|
var cs drivers.PinOutput
|
||||||
|
if !legacy.PinIsNoPin(csPin) {
|
||||||
|
cs = csPin.Set
|
||||||
|
}
|
||||||
return DeviceOf[T]{
|
return DeviceOf[T]{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
dcPin: dcPin,
|
dcPin: dcPin.Set,
|
||||||
resetPin: resetPin,
|
resetPin: resetPin.Set,
|
||||||
csPin: csPin,
|
csPin: cs,
|
||||||
blPin: blPin,
|
blPin: blPin.Set,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +234,7 @@ func (d *DeviceOf[T]) sendCommand(command uint8, data []byte) error {
|
|||||||
// startWrite must be called at the beginning of all exported methods to set the
|
// startWrite must be called at the beginning of all exported methods to set the
|
||||||
// chip select pin low.
|
// chip select pin low.
|
||||||
func (d *DeviceOf[T]) startWrite() {
|
func (d *DeviceOf[T]) startWrite() {
|
||||||
if d.csPin != machine.NoPin {
|
if d.csPin != nil {
|
||||||
d.csPin.Low()
|
d.csPin.Low()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,7 +242,7 @@ func (d *DeviceOf[T]) startWrite() {
|
|||||||
// endWrite must be called at the end of all exported methods to set the chip
|
// endWrite must be called at the end of all exported methods to set the chip
|
||||||
// select pin high.
|
// select pin high.
|
||||||
func (d *DeviceOf[T]) endWrite() {
|
func (d *DeviceOf[T]) endWrite() {
|
||||||
if d.csPin != machine.NoPin {
|
if d.csPin != nil {
|
||||||
d.csPin.High()
|
d.csPin.High()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -6,10 +6,10 @@ package sx127x
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
"tinygo.org/x/drivers/lora"
|
"tinygo.org/x/drivers/lora"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ const (
|
|||||||
// Device wraps an SPI connection to a SX127x device.
|
// Device wraps an SPI connection to a SX127x device.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
spi drivers.SPI // SPI bus for module communication
|
spi drivers.SPI // SPI bus for module communication
|
||||||
rstPin machine.Pin // GPIO for reset
|
rstPin drivers.PinOutput // GPIO for reset
|
||||||
radioEventChan chan lora.RadioEvent // Channel for Receiving events
|
radioEventChan chan lora.RadioEvent // Channel for Receiving events
|
||||||
loraConf lora.Config // Current Lora configuration
|
loraConf lora.Config // Current Lora configuration
|
||||||
controller RadioController // to manage interactions with the radio
|
controller RadioController // to manage interactions with the radio
|
||||||
@@ -43,10 +43,10 @@ func (d *Device) GetRadioEventChan() chan lora.RadioEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new SX127x connection. The SPI bus must already be configured.
|
// New creates a new SX127x connection. The SPI bus must already be configured.
|
||||||
func New(spi drivers.SPI, rstPin machine.Pin) *Device {
|
func New(spi drivers.SPI, rstPin pin.Output) *Device {
|
||||||
k := Device{
|
k := Device{
|
||||||
spi: spi,
|
spi: spi,
|
||||||
rstPin: rstPin,
|
rstPin: rstPin.Set,
|
||||||
radioEventChan: make(chan lora.RadioEvent, RADIOEVENTCHAN_SIZE),
|
radioEventChan: make(chan lora.RadioEvent, RADIOEVENTCHAN_SIZE),
|
||||||
spiTxBuf: make([]byte, SPI_BUFFER_SIZE),
|
spiTxBuf: make([]byte, SPI_BUFFER_SIZE),
|
||||||
spiRxBuf: make([]byte, SPI_BUFFER_SIZE),
|
spiRxBuf: make([]byte, SPI_BUFFER_SIZE),
|
||||||
|
|||||||
+15
-7
@@ -57,10 +57,14 @@ func (comm *UARTComm) WriteRegister(register uint8, value uint32, driverIndex ui
|
|||||||
byte((value >> 16) & 0xFF), // Middle byte
|
byte((value >> 16) & 0xFF), // Middle byte
|
||||||
byte((value >> 8) & 0xFF), // Next byte
|
byte((value >> 8) & 0xFF), // Next byte
|
||||||
byte(value & 0xFF), // LSB of value
|
byte(value & 0xFF), // LSB of value
|
||||||
0, // CRC
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[7] = CalculateCRC(buffer[:7])
|
// Calculate checksum by XORing all bytes
|
||||||
|
checksum := byte(0)
|
||||||
|
for _, b := range buffer[:7] {
|
||||||
|
checksum ^= b
|
||||||
|
}
|
||||||
|
buffer[7] = checksum // Set checksum byte
|
||||||
|
|
||||||
// Write the data to the TMC2209
|
// Write the data to the TMC2209
|
||||||
done := make(chan error, 1)
|
done := make(chan error, 1)
|
||||||
@@ -82,10 +86,10 @@ func (comm *UARTComm) WriteRegister(register uint8, value uint32, driverIndex ui
|
|||||||
// ReadRegister sends a register read command to the TMC2209 with a timeout.
|
// ReadRegister sends a register read command to the TMC2209 with a timeout.
|
||||||
func (comm *UARTComm) ReadRegister(register uint8, driverIndex uint8) (uint32, error) {
|
func (comm *UARTComm) ReadRegister(register uint8, driverIndex uint8) (uint32, error) {
|
||||||
var writeBuffer [4]byte
|
var writeBuffer [4]byte
|
||||||
writeBuffer[0] = 0x05 // Sync byte
|
writeBuffer[0] = 0x05 // Sync byte
|
||||||
writeBuffer[1] = 0x00 // Slave address
|
writeBuffer[1] = 0x00 // Slave address
|
||||||
writeBuffer[2] = register & 0x7F // Read command (MSB clear for read)
|
writeBuffer[2] = register & 0x7F // Read command (MSB clear for read)
|
||||||
writeBuffer[3] = CalculateCRC(writeBuffer[:3])
|
writeBuffer[3] = writeBuffer[0] ^ writeBuffer[1] ^ writeBuffer[2] // Checksum
|
||||||
|
|
||||||
// Send the read command
|
// Send the read command
|
||||||
done := make(chan []byte, 1)
|
done := make(chan []byte, 1)
|
||||||
@@ -99,7 +103,11 @@ func (comm *UARTComm) ReadRegister(register uint8, driverIndex uint8) (uint32, e
|
|||||||
// Implementing timeout using a 100ms timer
|
// Implementing timeout using a 100ms timer
|
||||||
select {
|
select {
|
||||||
case readBuffer := <-done:
|
case readBuffer := <-done:
|
||||||
checksum := CalculateCRC(readBuffer[:7])
|
// Validate checksum
|
||||||
|
checksum := byte(0)
|
||||||
|
for i := 0; i < 7; i++ {
|
||||||
|
checksum ^= readBuffer[i]
|
||||||
|
}
|
||||||
if checksum != readBuffer[7] {
|
if checksum != readBuffer[7] {
|
||||||
return 0, CustomError("checksum error")
|
return 0, CustomError("checksum error")
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-17
@@ -8,10 +8,11 @@ package uc8151 // import "tinygo.org/x/drivers/uc8151"
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
"tinygo.org/x/drivers/pixel"
|
"tinygo.org/x/drivers/pixel"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,10 +32,10 @@ type Config struct {
|
|||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
dc machine.Pin
|
dc drivers.PinOutput
|
||||||
rst machine.Pin
|
rst drivers.PinOutput
|
||||||
busy machine.Pin
|
isBusy drivers.PinInput
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
buffer []uint8
|
buffer []uint8
|
||||||
@@ -49,17 +50,17 @@ type Device struct {
|
|||||||
type Speed uint8
|
type Speed uint8
|
||||||
|
|
||||||
// New returns a new uc8151 driver. Pass in a fully configured SPI bus.
|
// 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 {
|
func New(bus drivers.SPI, csPin, dcPin, rstPin pin.Output, busyPin pin.Input) Device {
|
||||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(csPin)
|
||||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(dcPin)
|
||||||
rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(rstPin)
|
||||||
busyPin.Configure(machine.PinConfig{Mode: machine.PinInput})
|
legacy.ConfigurePinInput(busyPin)
|
||||||
return Device{
|
return Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
cs: csPin,
|
cs: csPin.Set,
|
||||||
dc: dcPin,
|
dc: dcPin.Set,
|
||||||
rst: rstPin,
|
rst: rstPin.Set,
|
||||||
busy: busyPin,
|
isBusy: busyPin.Get,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,14 +314,14 @@ func (d *Device) ClearDisplay() {
|
|||||||
|
|
||||||
// WaitUntilIdle waits until the display is ready
|
// WaitUntilIdle waits until the display is ready
|
||||||
func (d *Device) WaitUntilIdle() {
|
func (d *Device) WaitUntilIdle() {
|
||||||
for !d.busy.Get() {
|
for !d.isBusy() {
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBusy returns the busy status of the display
|
// IsBusy returns the busy status of the display
|
||||||
func (d *Device) IsBusy() bool {
|
func (d *Device) IsBusy() bool {
|
||||||
return d.busy.Get()
|
return d.isBusy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearBuffer sets the buffer to 0xFF (white)
|
// ClearBuffer sets the buffer to 0xFF (white)
|
||||||
|
|||||||
+1
-1
@@ -2,4 +2,4 @@ package drivers
|
|||||||
|
|
||||||
// Version returns a user-readable string showing the version of the drivers package for support purposes.
|
// Version returns a user-readable string showing the version of the drivers package for support purposes.
|
||||||
// Update this value before release of new version of software.
|
// Update this value before release of new version of software.
|
||||||
const Version = "0.32.0"
|
const Version = "0.30.0"
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ import (
|
|||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
"machine"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -22,14 +26,14 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus *machine.SPI
|
bus *machine.SPI
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
dc machine.Pin
|
dc drivers.PinOutput
|
||||||
rst machine.Pin
|
rst drivers.PinOutput
|
||||||
busy machine.Pin
|
isBusy drivers.PinInput
|
||||||
|
configurePins func()
|
||||||
buffer []uint8
|
buffer []uint8
|
||||||
rotation Rotation
|
rotation Rotation
|
||||||
}
|
}
|
||||||
|
|
||||||
type Rotation uint8
|
type Rotation uint8
|
||||||
@@ -79,22 +83,28 @@ var partialRefresh = [159]uint8{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new epd1in54 driver. Pass in a fully configured SPI bus.
|
// New returns a new epd1in54 driver. Pass in a fully configured SPI bus.
|
||||||
func New(bus *machine.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device {
|
func New(bus *machine.SPI, csPin, dcPin, rstPin pin.Output, busyPin pin.Input) Device {
|
||||||
return Device{
|
return Device{
|
||||||
buffer: make([]uint8, (uint32(Width)*uint32(Height))/8),
|
buffer: make([]uint8, (uint32(Width)*uint32(Height))/8),
|
||||||
bus: bus,
|
bus: bus,
|
||||||
cs: csPin,
|
cs: csPin.Set,
|
||||||
dc: dcPin,
|
dc: dcPin.Set,
|
||||||
rst: rstPin,
|
rst: rstPin.Set,
|
||||||
busy: busyPin,
|
isBusy: busyPin.Get,
|
||||||
|
configurePins: func() {
|
||||||
|
legacy.ConfigurePinOut(csPin)
|
||||||
|
legacy.ConfigurePinOut(dcPin)
|
||||||
|
legacy.ConfigurePinOut(rstPin)
|
||||||
|
legacy.ConfigurePinInput(busyPin)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) LDirInit(cfg Config) {
|
func (d *Device) LDirInit(cfg Config) {
|
||||||
d.cs.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
if d.configurePins == nil {
|
||||||
d.rst.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
panic(legacy.ErrConfigBeforeInstantiated)
|
||||||
d.dc.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
}
|
||||||
d.busy.Configure(machine.PinConfig{Mode: machine.PinInput})
|
d.configurePins()
|
||||||
|
|
||||||
d.bus.Configure(machine.SPIConfig{
|
d.bus.Configure(machine.SPIConfig{
|
||||||
Frequency: 2000000,
|
Frequency: 2000000,
|
||||||
@@ -150,10 +160,10 @@ func (d *Device) LDirInit(cfg Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) HDirInit(cfg Config) {
|
func (d *Device) HDirInit(cfg Config) {
|
||||||
d.cs.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
if d.configurePins == nil {
|
||||||
d.rst.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
panic(legacy.ErrConfigBeforeInstantiated)
|
||||||
d.dc.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
}
|
||||||
d.busy.Configure(machine.PinConfig{Mode: machine.PinInput})
|
d.configurePins()
|
||||||
|
|
||||||
d.bus.Configure(machine.SPIConfig{
|
d.bus.Configure(machine.SPIConfig{
|
||||||
Frequency: 2000000,
|
Frequency: 2000000,
|
||||||
@@ -369,7 +379,7 @@ func (d *Device) Clear() {
|
|||||||
|
|
||||||
// WaitUntilIdle waits until the display is ready
|
// WaitUntilIdle waits until the display is ready
|
||||||
func (d *Device) WaitUntilIdle() {
|
func (d *Device) WaitUntilIdle() {
|
||||||
for d.busy.Get() {
|
for d.isBusy() {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
time.Sleep(200 * time.Millisecond)
|
time.Sleep(200 * time.Millisecond)
|
||||||
@@ -377,7 +387,7 @@ func (d *Device) WaitUntilIdle() {
|
|||||||
|
|
||||||
// IsBusy returns the busy status of the display
|
// IsBusy returns the busy status of the display
|
||||||
func (d *Device) IsBusy() bool {
|
func (d *Device) IsBusy() bool {
|
||||||
return d.busy.Get()
|
return d.isBusy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearBuffer sets the buffer to 0xFF (white)
|
// ClearBuffer sets the buffer to 0xFF (white)
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ package epd2in13 // import "tinygo.org/x/drivers/waveshare-epd/epd2in13"
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -21,10 +22,10 @@ type Config struct {
|
|||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
dc machine.Pin
|
dc drivers.PinOutput
|
||||||
rst machine.Pin
|
rst drivers.PinOutput
|
||||||
busy machine.Pin
|
isBusy drivers.PinInput
|
||||||
logicalWidth int16
|
logicalWidth int16
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
@@ -53,17 +54,17 @@ var lutPartialUpdate = [30]uint8{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new epd2in13x driver. Pass in a fully configured SPI bus.
|
// New returns a new epd2in13x driver. Pass in a fully configured SPI bus.
|
||||||
func New(bus drivers.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device {
|
func New(bus drivers.SPI, csPin, dcPin, rstPin pin.Output, busyPin pin.Input) Device {
|
||||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(csPin)
|
||||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(dcPin)
|
||||||
rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(rstPin)
|
||||||
busyPin.Configure(machine.PinConfig{Mode: machine.PinInput})
|
legacy.ConfigurePinInput(busyPin)
|
||||||
return Device{
|
return Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
cs: csPin,
|
cs: csPin.Set,
|
||||||
dc: dcPin,
|
dc: dcPin.Set,
|
||||||
rst: rstPin,
|
rst: rstPin.Set,
|
||||||
busy: busyPin,
|
isBusy: busyPin.Get,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,14 +299,14 @@ func (d *Device) setMemoryPointer(x int16, y int16) {
|
|||||||
|
|
||||||
// WaitUntilIdle waits until the display is ready
|
// WaitUntilIdle waits until the display is ready
|
||||||
func (d *Device) WaitUntilIdle() {
|
func (d *Device) WaitUntilIdle() {
|
||||||
for d.busy.Get() {
|
for d.isBusy() {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBusy returns the busy status of the display
|
// IsBusy returns the busy status of the display
|
||||||
func (d *Device) IsBusy() bool {
|
func (d *Device) IsBusy() bool {
|
||||||
return d.busy.Get()
|
return d.isBusy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearBuffer sets the buffer to 0xFF (white)
|
// ClearBuffer sets the buffer to 0xFF (white)
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ package epd2in13x // import "tinygo.org/x/drivers/waveshare-epd/epd2in13x"
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -20,10 +21,10 @@ type Config struct {
|
|||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
dc machine.Pin
|
dc drivers.PinOutput
|
||||||
rst machine.Pin
|
rst drivers.PinOutput
|
||||||
busy machine.Pin
|
isBusy drivers.PinInput
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
buffer [][]uint8
|
buffer [][]uint8
|
||||||
@@ -33,17 +34,17 @@ type Device struct {
|
|||||||
type Color uint8
|
type Color uint8
|
||||||
|
|
||||||
// New returns a new epd2in13x driver. Pass in a fully configured SPI bus.
|
// New returns a new epd2in13x driver. Pass in a fully configured SPI bus.
|
||||||
func New(bus drivers.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device {
|
func New(bus drivers.SPI, csPin, dcPin, rstPin pin.Output, busyPin pin.Input) Device {
|
||||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(csPin)
|
||||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(dcPin)
|
||||||
rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(rstPin)
|
||||||
busyPin.Configure(machine.PinConfig{Mode: machine.PinInput})
|
legacy.ConfigurePinInput(busyPin)
|
||||||
return Device{
|
return Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
cs: csPin,
|
cs: csPin.Set,
|
||||||
dc: dcPin,
|
dc: dcPin.Set,
|
||||||
rst: rstPin,
|
rst: rstPin.Set,
|
||||||
busy: busyPin,
|
isBusy: busyPin.Get,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,14 +278,14 @@ func (d *Device) ClearDisplay() {
|
|||||||
|
|
||||||
// WaitUntilIdle waits until the display is ready
|
// WaitUntilIdle waits until the display is ready
|
||||||
func (d *Device) WaitUntilIdle() {
|
func (d *Device) WaitUntilIdle() {
|
||||||
for !d.busy.Get() {
|
for !d.isBusy() {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBusy returns the busy status of the display
|
// IsBusy returns the busy status of the display
|
||||||
func (d *Device) IsBusy() bool {
|
func (d *Device) IsBusy() bool {
|
||||||
return d.busy.Get()
|
return d.isBusy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearBuffer sets the buffer to 0xFF (white)
|
// ClearBuffer sets the buffer to 0xFF (white)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ package epd2in66b
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
@@ -18,19 +17,12 @@ const (
|
|||||||
|
|
||||||
const Baudrate = 4_000_000 // 4 MHz
|
const Baudrate = 4_000_000 // 4 MHz
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
ResetPin machine.Pin
|
|
||||||
DataPin machine.Pin
|
|
||||||
ChipSelectPin machine.Pin
|
|
||||||
BusyPin machine.Pin
|
|
||||||
}
|
|
||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
dc machine.Pin
|
dc drivers.PinOutput
|
||||||
rst machine.Pin
|
rst drivers.PinOutput
|
||||||
busy machine.Pin
|
isBusy drivers.PinInput
|
||||||
|
|
||||||
blackBuffer []byte
|
blackBuffer []byte
|
||||||
redBuffer []byte
|
redBuffer []byte
|
||||||
@@ -50,21 +42,6 @@ func New(bus drivers.SPI) Device {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure configures the device and its pins.
|
|
||||||
func (d *Device) Configure(c Config) error {
|
|
||||||
d.cs = c.ChipSelectPin
|
|
||||||
d.dc = c.DataPin
|
|
||||||
d.rst = c.ResetPin
|
|
||||||
d.busy = c.BusyPin
|
|
||||||
|
|
||||||
d.cs.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
|
||||||
d.dc.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
|
||||||
d.rst.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
|
||||||
d.busy.Configure(machine.PinConfig{Mode: machine.PinInput})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Size() (x, y int16) {
|
func (d *Device) Size() (x, y int16) {
|
||||||
return displayWidth, displayHeight
|
return displayWidth, displayHeight
|
||||||
}
|
}
|
||||||
@@ -229,7 +206,7 @@ func (d *Device) WaitUntilIdle() {
|
|||||||
// give it some time to get busy
|
// give it some time to get busy
|
||||||
time.Sleep(50 * time.Millisecond)
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
for d.busy.Get() { // high = busy
|
for d.isBusy() { // high = busy
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
//go:build baremetal
|
||||||
|
|
||||||
|
package epd2in66b
|
||||||
|
|
||||||
|
import "machine"
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
ResetPin machine.Pin
|
||||||
|
DataPin machine.Pin
|
||||||
|
ChipSelectPin machine.Pin
|
||||||
|
BusyPin machine.Pin
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure configures the device and its pins.
|
||||||
|
func (d *Device) Configure(c Config) error {
|
||||||
|
cs := c.ChipSelectPin
|
||||||
|
dc := c.DataPin
|
||||||
|
rst := c.ResetPin
|
||||||
|
busy := c.BusyPin
|
||||||
|
|
||||||
|
cs.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
dc.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
rst.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
busy.Configure(machine.PinConfig{Mode: machine.PinInput})
|
||||||
|
d.cs = cs.Set
|
||||||
|
d.dc = dc.Set
|
||||||
|
d.rst = rst.Set
|
||||||
|
d.isBusy = busy.Get
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -13,10 +13,11 @@ package epd2in9 // import "tinygo.org/x/drivers/waveshare-epd/epd2in9"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -28,10 +29,10 @@ type Config struct {
|
|||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
dc machine.Pin
|
dc drivers.PinOutput
|
||||||
rst machine.Pin
|
rst drivers.PinOutput
|
||||||
busy machine.Pin
|
isBusy drivers.PinInput
|
||||||
logicalWidth int16
|
logicalWidth int16
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
@@ -61,17 +62,17 @@ var lutPartialUpdate = [30]uint8{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new epd2in9 driver. Pass in a fully configured SPI bus.
|
// New returns a new epd2in9 driver. Pass in a fully configured SPI bus.
|
||||||
func New(bus drivers.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device {
|
func New(bus drivers.SPI, csPin, dcPin, rstPin pin.Output, busyPin pin.Input) Device {
|
||||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(csPin)
|
||||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(dcPin)
|
||||||
rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(rstPin)
|
||||||
busyPin.Configure(machine.PinConfig{Mode: machine.PinInput})
|
legacy.ConfigurePinInput(busyPin)
|
||||||
return Device{
|
return Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
cs: csPin,
|
cs: csPin.Set,
|
||||||
dc: dcPin,
|
dc: dcPin.Set,
|
||||||
rst: rstPin,
|
rst: rstPin.Set,
|
||||||
busy: busyPin,
|
isBusy: busyPin.Get,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,14 +246,14 @@ func (d *Device) setMemoryPointer(x int16, y int16) {
|
|||||||
|
|
||||||
// WaitUntilIdle waits until the display is ready
|
// WaitUntilIdle waits until the display is ready
|
||||||
func (d *Device) WaitUntilIdle() {
|
func (d *Device) WaitUntilIdle() {
|
||||||
for d.busy.Get() {
|
for d.isBusy() {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBusy returns the busy status of the display
|
// IsBusy returns the busy status of the display
|
||||||
func (d *Device) IsBusy() bool {
|
func (d *Device) IsBusy() bool {
|
||||||
return d.busy.Get()
|
return d.isBusy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearBuffer sets the buffer to 0xFF (white)
|
// ClearBuffer sets the buffer to 0xFF (white)
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ package epd4in2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/internal/legacy"
|
||||||
|
"tinygo.org/x/drivers/internal/pin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -25,10 +26,10 @@ type Config struct {
|
|||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.SPI
|
bus drivers.SPI
|
||||||
cs machine.Pin
|
cs drivers.PinOutput
|
||||||
dc machine.Pin
|
dc drivers.PinOutput
|
||||||
rst machine.Pin
|
rst drivers.PinOutput
|
||||||
busy machine.Pin
|
isBusy drivers.PinInput
|
||||||
logicalWidth int16
|
logicalWidth int16
|
||||||
width int16
|
width int16
|
||||||
height int16
|
height int16
|
||||||
@@ -40,17 +41,17 @@ type Device struct {
|
|||||||
type Rotation uint8
|
type Rotation uint8
|
||||||
|
|
||||||
// New returns a new epd4in2 driver. Pass in a fully configured SPI bus.
|
// New returns a new epd4in2 driver. Pass in a fully configured SPI bus.
|
||||||
func New(bus drivers.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device {
|
func New(bus drivers.SPI, csPin, dcPin, rstPin pin.Output, busyPin pin.Input) Device {
|
||||||
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(csPin)
|
||||||
dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(dcPin)
|
||||||
rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
legacy.ConfigurePinOut(rstPin)
|
||||||
busyPin.Configure(machine.PinConfig{Mode: machine.PinInput})
|
legacy.ConfigurePinInput(busyPin)
|
||||||
return Device{
|
return Device{
|
||||||
bus: bus,
|
bus: bus,
|
||||||
cs: csPin,
|
cs: csPin.Set,
|
||||||
dc: dcPin,
|
dc: dcPin.Set,
|
||||||
rst: rstPin,
|
rst: rstPin.Set,
|
||||||
busy: busyPin,
|
isBusy: busyPin.Get,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,14 +312,14 @@ func (d *Device) ClearDisplay() {
|
|||||||
|
|
||||||
// WaitUntilIdle waits until the display is ready
|
// WaitUntilIdle waits until the display is ready
|
||||||
func (d *Device) WaitUntilIdle() {
|
func (d *Device) WaitUntilIdle() {
|
||||||
for d.busy.Get() {
|
for d.isBusy() {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBusy returns the busy status of the display
|
// IsBusy returns the busy status of the display
|
||||||
func (d *Device) IsBusy() bool {
|
func (d *Device) IsBusy() bool {
|
||||||
return d.busy.Get()
|
return d.isBusy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearBuffer sets the buffer to 0xFF (white)
|
// ClearBuffer sets the buffer to 0xFF (white)
|
||||||
|
|||||||
@@ -1320,465 +1320,6 @@ void ws2812_writeByte168(char c, uint32_t *portSet, uint32_t *portClear, uint32_
|
|||||||
[maskClear]"r"(maskClear),
|
[maskClear]"r"(maskClear),
|
||||||
[portClear]"m"(*portClear));
|
[portClear]"m"(*portClear));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((always_inline))
|
|
||||||
void ws2812_writeByte200(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
|
|
||||||
// Timings:
|
|
||||||
// T0H: 70 - 72 cycles or 350.0ns - 360.0ns
|
|
||||||
// T1H: 210 - 212 cycles or 1050.0ns - 1060.0ns
|
|
||||||
// TLD: 230 - cycles or 1150.0ns -
|
|
||||||
uint32_t value = (uint32_t)c << 24;
|
|
||||||
char i = 8;
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"1: @ send_bit\n"
|
|
||||||
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t lsls %[value], #1 @ [1]\n"
|
|
||||||
"\t bcs.n 2f @ [1/3] skip_store\n"
|
|
||||||
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
|
|
||||||
"\t2: @ skip_store\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t nop\n"
|
|
||||||
"\t subs %[i], #1 @ [1]\n"
|
|
||||||
"\t beq.n 3f @ [1/3] end\n"
|
|
||||||
"\t b 1b @ [1/3] send_bit\n"
|
|
||||||
"\t3: @ end\n"
|
|
||||||
: [value]"+r"(value),
|
|
||||||
[i]"+r"(i)
|
|
||||||
: [maskSet]"r"(maskSet),
|
|
||||||
[portSet]"m"(*portSet),
|
|
||||||
[maskClear]"r"(maskClear),
|
|
||||||
[portClear]"m"(*portClear));
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@@ -1841,13 +1382,3 @@ func (d Device) writeByte168(c byte) {
|
|||||||
|
|
||||||
interrupt.Restore(mask)
|
interrupt.Restore(mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Device) writeByte200(c byte) {
|
|
||||||
portSet, maskSet := d.Pin.PortMaskSet()
|
|
||||||
portClear, maskClear := d.Pin.PortMaskClear()
|
|
||||||
|
|
||||||
mask := interrupt.Disable()
|
|
||||||
C.ws2812_writeByte200(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
|
|
||||||
|
|
||||||
interrupt.Restore(mask)
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
// Package ws2812 implements a driver for WS2812 and SK6812 RGB LED strips.
|
// Package ws2812 implements a driver for WS2812 and SK6812 RGB LED strips.
|
||||||
package ws2812 // import "tinygo.org/x/drivers/ws2812"
|
package ws2812 // import "tinygo.org/x/drivers/ws2812"
|
||||||
|
|
||||||
//go:generate go run gen-ws2812.go -arch=cortexm 16 48 64 120 125 168 200
|
//go:generate go run gen-ws2812.go -arch=cortexm 16 48 64 120 125 168
|
||||||
//go:generate go run gen-ws2812.go -arch=tinygoriscv 160 320
|
//go:generate go run gen-ws2812.go -arch=tinygoriscv 160 320
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -28,15 +28,12 @@ func (d Device) WriteByte(c byte) error {
|
|||||||
case 120_000_000: // 120MHz
|
case 120_000_000: // 120MHz
|
||||||
d.writeByte120(c)
|
d.writeByte120(c)
|
||||||
return nil
|
return nil
|
||||||
case 125_000_000: // 125 MHz e.g. rp2040 originally
|
case 125_000_000: // 125 MHz e.g. rp2040
|
||||||
d.writeByte125(c)
|
d.writeByte125(c)
|
||||||
return nil
|
return nil
|
||||||
case 168_000_000: // 168MHz, e.g. stm32f405
|
case 168_000_000: // 168MHz, e.g. stm32f405
|
||||||
d.writeByte168(c)
|
d.writeByte168(c)
|
||||||
return nil
|
return nil
|
||||||
case 200_000_000: // 200MHz, e.g. rp2040 starting with TinyGo v0.37
|
|
||||||
d.writeByte200(c)
|
|
||||||
return nil
|
|
||||||
default:
|
default:
|
||||||
return errUnknownClockSpeed
|
return errUnknownClockSpeed
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user