From 39e9e209ec022803e5342fa89b76521edafa6e47 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sun, 18 Oct 2020 18:03:12 +0200 Subject: [PATCH 1/4] spi: remove machine.SPI and replace with drivers.SPI interface for almost all SPI drivers Signed-off-by: deadprogram --- apa102/apa102.go | 14 +++++++------ bmi160/bmi160.go | 11 ++++++---- examples/wifinina/mqttclient/main.go | 15 ++++++-------- examples/wifinina/mqttsub/main.go | 15 ++++++-------- examples/wifinina/ntpclient/main.go | 23 +++++++++------------ examples/wifinina/tcpclient/main.go | 15 ++++++-------- examples/wifinina/udpstation/main.go | 20 ++++++++---------- examples/wifinina/webclient/main.go | 15 ++++++-------- flash/flash.go | 14 +++++++------ flash/transport_spi.go | 31 +++++++--------------------- hub75/hub75.go | 6 ++++-- mcp3008/mcp3008.go | 6 ++++-- pcd8544/pcd8544.go | 6 ++++-- spi.go | 7 +++++++ ssd1306/ssd1306.go | 4 ++-- ssd1331/ssd1331.go | 6 ++++-- ssd1351/ssd1351.go | 6 ++++-- st7735/st7735.go | 6 ++++-- st7789/st7789.go | 7 ++++--- waveshare-epd/epd2in13/epd2in13.go | 6 ++++-- waveshare-epd/epd2in13x/epd2in13x.go | 6 ++++-- waveshare-epd/epd4in2/epd4in2.go | 6 ++++-- wifinina/wifinina.go | 14 ++++++++++++- 23 files changed, 135 insertions(+), 124 deletions(-) create mode 100644 spi.go diff --git a/apa102/apa102.go b/apa102/apa102.go index cc3bcdafb..a2d6ed91a 100644 --- a/apa102/apa102.go +++ b/apa102/apa102.go @@ -6,6 +6,8 @@ package apa102 // import "tinygo.org/x/drivers/apa102" import ( "image/color" "machine" + + "tinygo.org/x/drivers" ) const ( @@ -23,20 +25,20 @@ var startFrame = []byte{0x00, 0x00, 0x00, 0x00} // Device wraps APA102 SPI LEDs. type Device struct { - bus SPI + bus drivers.SPI Order int } // The SPI interface specifies the minimum functionality that a bus // implementation needs to provide for use by the APA102 driver. Hardware // SPI from the TinyGo "machine" package implements this already. -type SPI interface { - Tx(w, r []byte) error - Transfer(b byte) (byte, error) -} +// type SPI interface { +// Tx(w, r []byte) error +// Transfer(b byte) (byte, error) +// } // New returns a new APA102 driver. Pass in a fully configured SPI bus. -func New(b SPI) Device { +func New(b drivers.SPI) Device { return Device{bus: b, Order: BGR} } diff --git a/bmi160/bmi160.go b/bmi160/bmi160.go index 75228d9c2..b5bad10eb 100644 --- a/bmi160/bmi160.go +++ b/bmi160/bmi160.go @@ -1,8 +1,11 @@ package bmi160 -import "machine" +import ( + "machine" + "time" -import "time" + "tinygo.org/x/drivers" +) // DeviceSPI is the SPI interface to a BMI160 accelerometer/gyroscope. There is // also an I2C interface, but it is not yet supported. @@ -11,13 +14,13 @@ type DeviceSPI struct { CSB machine.Pin // SPI bus (requires chip select to be usable). - Bus machine.SPI + Bus drivers.SPI } // NewSPI returns a new device driver. The pin and SPI interface are not // touched, provide a fully configured SPI object and call Configure to start // using this device. -func NewSPI(csb machine.Pin, spi machine.SPI) *DeviceSPI { +func NewSPI(csb machine.Pin, spi drivers.SPI) *DeviceSPI { return &DeviceSPI{ CSB: csb, // chip select Bus: spi, diff --git a/examples/wifinina/mqttclient/main.go b/examples/wifinina/mqttclient/main.go index 025ab4b89..3af0b9d14 100644 --- a/examples/wifinina/mqttclient/main.go +++ b/examples/wifinina/mqttclient/main.go @@ -41,15 +41,7 @@ var ( spi = machine.NINA_SPI // this is the ESP chip that has the WIFININA firmware flashed on it - adaptor = &wifinina.Device{ - SPI: spi, - CS: machine.NINA_CS, - ACK: machine.NINA_ACK, - GPIO0: machine.NINA_GPIO0, - RESET: machine.NINA_RESETN, - } - - console = machine.UART0 + adaptor *wifinina.Device topic = "tinygo" ) @@ -68,6 +60,11 @@ func main() { }) // Init esp8266/esp32 + adaptor = wifinina.New(spi, + machine.NINA_CS, + machine.NINA_ACK, + machine.NINA_GPIO0, + machine.NINA_RESETN) adaptor.Configure() connectToAP() diff --git a/examples/wifinina/mqttsub/main.go b/examples/wifinina/mqttsub/main.go index e3c78cf02..249c743a7 100644 --- a/examples/wifinina/mqttsub/main.go +++ b/examples/wifinina/mqttsub/main.go @@ -40,15 +40,7 @@ var ( spi = machine.NINA_SPI // this is the ESP chip that has the WIFININA firmware flashed on it - adaptor = &wifinina.Device{ - SPI: spi, - CS: machine.NINA_CS, - ACK: machine.NINA_ACK, - GPIO0: machine.NINA_GPIO0, - RESET: machine.NINA_RESETN, - } - - console = machine.UART0 + adaptor *wifinina.Device cl mqtt.Client topicTx = "tinygo/tx" @@ -75,6 +67,11 @@ func main() { }) // Init esp8266/esp32 + adaptor = wifinina.New(spi, + machine.NINA_CS, + machine.NINA_ACK, + machine.NINA_GPIO0, + machine.NINA_RESETN) adaptor.Configure() connectToAP() diff --git a/examples/wifinina/ntpclient/main.go b/examples/wifinina/ntpclient/main.go index 432b69c4f..7bbd5a29f 100644 --- a/examples/wifinina/ntpclient/main.go +++ b/examples/wifinina/ntpclient/main.go @@ -24,20 +24,9 @@ const ntpHost = "129.6.15.29" const NTP_PACKET_SIZE = 48 var ( - // this is the ESP chip that has the WIFININA firmware flashed on it - // these are the default pins for the Arduino Nano33 IoT. - adaptor = wifinina.Device{ - SPI: machine.NINA_SPI, - CS: machine.NINA_CS, - ACK: machine.NINA_ACK, - GPIO0: machine.NINA_GPIO0, - RESET: machine.NINA_RESETN, - } - - b = make([]byte, NTP_PACKET_SIZE) - - console = machine.UART0 + adaptor *wifinina.Device + b = make([]byte, NTP_PACKET_SIZE) ) func main() { @@ -50,6 +39,14 @@ func main() { SDI: machine.NINA_SDI, SCK: machine.NINA_SCK, }) + + // these are the default pins for the Arduino Nano33 IoT. + adaptor = wifinina.New(machine.NINA_SPI, + machine.NINA_CS, + machine.NINA_ACK, + machine.NINA_GPIO0, + machine.NINA_RESETN) + adaptor.Configure() // connect to access point diff --git a/examples/wifinina/tcpclient/main.go b/examples/wifinina/tcpclient/main.go index 46188bee3..9449d3f8f 100644 --- a/examples/wifinina/tcpclient/main.go +++ b/examples/wifinina/tcpclient/main.go @@ -35,15 +35,7 @@ var ( spi = machine.NINA_SPI // this is the ESP chip that has the WIFININA firmware flashed on it - adaptor = &wifinina.Device{ - SPI: spi, - CS: machine.NINA_CS, - ACK: machine.NINA_ACK, - GPIO0: machine.NINA_GPIO0, - RESET: machine.NINA_RESETN, - } - - console = machine.UART0 + adaptor *wifinina.Device ) var buf = &bytes.Buffer{} @@ -60,6 +52,11 @@ func main() { SCK: machine.NINA_SCK, }) + adaptor = wifinina.New(spi, + machine.NINA_CS, + machine.NINA_ACK, + machine.NINA_GPIO0, + machine.NINA_RESETN) adaptor.Configure() connectToAP() diff --git a/examples/wifinina/udpstation/main.go b/examples/wifinina/udpstation/main.go index 4c645f746..ed415cf0c 100644 --- a/examples/wifinina/udpstation/main.go +++ b/examples/wifinina/udpstation/main.go @@ -22,19 +22,9 @@ const pass = "" // IP address of the server aka "hub". Replace with your own info. const hubIP = "" -// these are the default pins for the Arduino Nano33 IoT. -// change these to connect to a different UART or pins for the ESP8266/ESP32 var ( - // this is the ESP chip that has the WIFININA firmware flashed on it - // these are the default pins for the Arduino Nano33 IoT. - adaptor = &wifinina.Device{ - SPI: machine.NINA_SPI, - CS: machine.NINA_CS, - ACK: machine.NINA_ACK, - GPIO0: machine.NINA_GPIO0, - RESET: machine.NINA_RESETN, - } + adaptor *wifinina.Device ) func main() { @@ -47,6 +37,14 @@ func main() { SDI: machine.NINA_SDI, SCK: machine.NINA_SCK, }) + + // these are the default pins for the Arduino Nano33 IoT. + // change these to connect to a different UART or pins for the ESP8266/ESP32 + adaptor = wifinina.New(machine.NINA_SPI, + machine.NINA_CS, + machine.NINA_ACK, + machine.NINA_GPIO0, + machine.NINA_RESETN) adaptor.Configure() // connect to access point diff --git a/examples/wifinina/webclient/main.go b/examples/wifinina/webclient/main.go index afc9b9f95..afdc8792e 100644 --- a/examples/wifinina/webclient/main.go +++ b/examples/wifinina/webclient/main.go @@ -33,15 +33,7 @@ var ( spi = machine.NINA_SPI // this is the ESP chip that has the WIFININA firmware flashed on it - adaptor = &wifinina.Device{ - SPI: spi, - CS: machine.NINA_CS, - ACK: machine.NINA_ACK, - GPIO0: machine.NINA_GPIO0, - RESET: machine.NINA_RESETN, - } - - console = machine.UART0 + adaptor *wifinina.Device ) var buf [256]byte @@ -61,6 +53,11 @@ func main() { SCK: machine.NINA_SCK, }) + adaptor = wifinina.New(spi, + machine.NINA_CS, + machine.NINA_ACK, + machine.NINA_GPIO0, + machine.NINA_RESETN) adaptor.Configure() connectToAP() diff --git a/flash/flash.go b/flash/flash.go index aa26bc6c8..cfa268600 100644 --- a/flash/flash.go +++ b/flash/flash.go @@ -133,12 +133,14 @@ func (dev *Device) Configure(config *DeviceConfig) (err error) { time.Sleep(30 * time.Microsecond) // Speed up to max device frequency - if dev.attrs.MaxClockSpeedMHz > 0 { - err := dev.trans.setClockSpeed(uint32(dev.attrs.MaxClockSpeedMHz) * 1e6) - if err != nil { - return err - } - } + // I propose a check here for max frequency, but not put that functionality directly into the driver. + // Either that or we have to change the signature of the SPI interface in the machine package itself. + // if dev.attrs.MaxClockSpeedMHz > 0 { + // err := dev.trans.setClockSpeed(uint32(dev.attrs.MaxClockSpeedMHz) * 1e6) + // if err != nil { + // return err + // } + // } // Enable Quad Mode if available if dev.trans.supportQuadMode() && dev.attrs.QuadEnableBitMask > 0 { diff --git a/flash/transport_spi.go b/flash/transport_spi.go index 2055ccf8d..4a19cf230 100644 --- a/flash/transport_spi.go +++ b/flash/transport_spi.go @@ -1,11 +1,14 @@ package flash -import "machine" +import ( + "machine" + + "tinygo.org/x/drivers" +) type transport interface { configure(config *DeviceConfig) supportQuadMode() bool - setClockSpeed(hz uint32) (err error) runCommand(cmd byte) (err error) readCommand(cmd byte, rsp []byte) (err error) writeCommand(cmd byte, data []byte) (err error) @@ -16,7 +19,7 @@ type transport interface { // NewSPI returns a pointer to a flash device that uses a SPI peripheral to // communicate with a serial memory chip. -func NewSPI(spi *machine.SPI, sdo, sdi, sck, cs machine.Pin) *Device { +func NewSPI(spi drivers.SPI, sdo, sdi, sck, cs machine.Pin) *Device { return &Device{ trans: &spiTransport{ spi: spi, @@ -29,7 +32,7 @@ func NewSPI(spi *machine.SPI, sdo, sdi, sck, cs machine.Pin) *Device { } type spiTransport struct { - spi *machine.SPI + spi drivers.SPI sdo machine.Pin sdi machine.Pin sck machine.Pin @@ -37,31 +40,11 @@ type spiTransport struct { } func (tr *spiTransport) configure(config *DeviceConfig) { - // Configure spi bus - tr.setClockSpeed(5000000) - // Configure chip select pin tr.ss.Configure(machine.PinConfig{Mode: machine.PinOutput}) tr.ss.High() } -func (tr *spiTransport) setClockSpeed(hz uint32) error { - // TODO: un-hardcode this max speed; it is probably a sensible - // default maximum for atsamd and nrf at least - if hz > 24*1e6 { - hz = 24 * 1e6 - } - tr.spi.Configure(machine.SPIConfig{ - Frequency: hz, - SDI: tr.sdi, - SDO: tr.sdo, - SCK: tr.sck, - LSBFirst: false, - Mode: 0, - }) - return nil -} - func (tr *spiTransport) supportQuadMode() bool { return false } diff --git a/hub75/hub75.go b/hub75/hub75.go index 7109e22fb..bb6aa5c99 100644 --- a/hub75/hub75.go +++ b/hub75/hub75.go @@ -9,6 +9,8 @@ import ( "image/color" "machine" "time" + + "tinygo.org/x/drivers" ) type Config struct { @@ -21,7 +23,7 @@ type Config struct { } type Device struct { - bus machine.SPI + bus drivers.SPI a machine.Pin b machine.Pin c machine.Pin @@ -52,7 +54,7 @@ type Device struct { } // New returns a new HUB75 driver. Pass in a fully configured SPI bus. -func New(b machine.SPI, latPin, oePin, aPin, bPin, cPin, dPin machine.Pin) Device { +func New(b drivers.SPI, latPin, oePin, aPin, bPin, cPin, dPin machine.Pin) Device { aPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) bPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) cPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) diff --git a/mcp3008/mcp3008.go b/mcp3008/mcp3008.go index 799c52b1c..4de954d48 100644 --- a/mcp3008/mcp3008.go +++ b/mcp3008/mcp3008.go @@ -7,11 +7,13 @@ package mcp3008 // import "tinygo.org/x/drivers/mcp3008" import ( "errors" "machine" + + "tinygo.org/x/drivers" ) // Device wraps MCP3008 SPI ADC. type Device struct { - bus machine.SPI + bus drivers.SPI cs machine.Pin tx []byte rx []byte @@ -32,7 +34,7 @@ type ADCPin struct { } // New returns a new MCP3008 driver. Pass in a fully configured SPI bus. -func New(b machine.SPI, csPin machine.Pin) *Device { +func New(b drivers.SPI, csPin machine.Pin) *Device { d := &Device{bus: b, cs: csPin, tx: make([]byte, 3), diff --git a/pcd8544/pcd8544.go b/pcd8544/pcd8544.go index 23ed294be..e79c28f40 100644 --- a/pcd8544/pcd8544.go +++ b/pcd8544/pcd8544.go @@ -9,11 +9,13 @@ import ( "image/color" "machine" "time" + + "tinygo.org/x/drivers" ) // Device wraps an SPI connection. type Device struct { - bus machine.SPI + bus drivers.SPI dcPin machine.Pin rstPin machine.Pin scePin machine.Pin @@ -29,7 +31,7 @@ type Config struct { } // New creates a new PCD8544 connection. The SPI bus must already be configured. -func New(bus machine.SPI, dcPin, rstPin, scePin machine.Pin) *Device { +func New(bus drivers.SPI, dcPin, rstPin, scePin machine.Pin) *Device { return &Device{ bus: bus, dcPin: dcPin, diff --git a/spi.go b/spi.go new file mode 100644 index 000000000..f908afe6b --- /dev/null +++ b/spi.go @@ -0,0 +1,7 @@ +package drivers + +// SPI represents a SPI bus. It is implemented by the machine.SPI type. +type SPI interface { + Tx(w, r []byte) error + Transfer(b byte) (byte, error) +} diff --git a/ssd1306/ssd1306.go b/ssd1306/ssd1306.go index 31eccc207..e81a14db4 100644 --- a/ssd1306/ssd1306.go +++ b/ssd1306/ssd1306.go @@ -37,7 +37,7 @@ type I2CBus struct { } type SPIBus struct { - wire machine.SPI + wire drivers.SPI dcPin machine.Pin resetPin machine.Pin csPin machine.Pin @@ -62,7 +62,7 @@ func NewI2C(bus drivers.I2C) Device { } // NewSPI creates a new SSD1306 connection. The SPI wire must already be configured. -func NewSPI(bus machine.SPI, dcPin, resetPin, csPin machine.Pin) Device { +func NewSPI(bus drivers.SPI, dcPin, resetPin, csPin machine.Pin) Device { dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) csPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) diff --git a/ssd1331/ssd1331.go b/ssd1331/ssd1331.go index 32a11c0b4..d8835e951 100644 --- a/ssd1331/ssd1331.go +++ b/ssd1331/ssd1331.go @@ -10,6 +10,8 @@ import ( "errors" "time" + + "tinygo.org/x/drivers" ) type Model uint8 @@ -17,7 +19,7 @@ type Rotation uint8 // Device wraps an SPI connection. type Device struct { - bus machine.SPI + bus drivers.SPI dcPin machine.Pin resetPin machine.Pin csPin machine.Pin @@ -35,7 +37,7 @@ type Config struct { } // New creates a new SSD1331 connection. The SPI wire must already be configured. -func New(bus machine.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}) resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) csPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) diff --git a/ssd1351/ssd1351.go b/ssd1351/ssd1351.go index 89eaac9d8..5a2ab5b98 100644 --- a/ssd1351/ssd1351.go +++ b/ssd1351/ssd1351.go @@ -9,6 +9,8 @@ import ( "image/color" "machine" "time" + + "tinygo.org/x/drivers" ) var ( @@ -18,7 +20,7 @@ var ( // Device wraps an SPI connection. type Device struct { - bus machine.SPI + bus drivers.SPI dcPin machine.Pin resetPin machine.Pin csPin machine.Pin @@ -40,7 +42,7 @@ type Config struct { } // New creates a new SSD1351 connection. The SPI wire must already be configured. -func New(bus machine.SPI, resetPin, dcPin, csPin, enPin, rwPin machine.Pin) Device { +func New(bus drivers.SPI, resetPin, dcPin, csPin, enPin, rwPin machine.Pin) Device { return Device{ bus: bus, dcPin: dcPin, diff --git a/st7735/st7735.go b/st7735/st7735.go index d6bd46379..c5f8c5e68 100644 --- a/st7735/st7735.go +++ b/st7735/st7735.go @@ -10,6 +10,8 @@ import ( "time" "errors" + + "tinygo.org/x/drivers" ) type Model uint8 @@ -17,7 +19,7 @@ type Rotation uint8 // Device wraps an SPI connection. type Device struct { - bus machine.SPI + bus drivers.SPI dcPin machine.Pin resetPin machine.Pin csPin machine.Pin @@ -44,7 +46,7 @@ type Config struct { } // New creates a new ST7735 connection. The SPI wire must already be configured. -func New(bus machine.SPI, resetPin, dcPin, csPin, blPin machine.Pin) Device { +func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin machine.Pin) Device { dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) csPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) diff --git a/st7789/st7789.go b/st7789/st7789.go index 03ae0248b..9158c5cbf 100644 --- a/st7789/st7789.go +++ b/st7789/st7789.go @@ -12,6 +12,8 @@ import ( "time" "errors" + + "tinygo.org/x/drivers" ) type Rotation uint8 @@ -20,7 +22,7 @@ type FrameRate uint8 // Device wraps an SPI connection. type Device struct { - bus machine.SPI + bus drivers.SPI dcPin machine.Pin resetPin machine.Pin csPin machine.Pin @@ -50,7 +52,7 @@ type Config struct { } // New creates a new ST7789 connection. The SPI wire must already be configured. -func New(bus machine.SPI, resetPin, dcPin, csPin, blPin machine.Pin) Device { +func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin machine.Pin) Device { dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) csPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) @@ -276,7 +278,6 @@ func (d *Device) FillRectangle(x, y, width, height int16, c color.RGBA) error { return nil } - // FillRectangle fills a rectangle at a given coordinates with a buffer func (d *Device) FillRectangleWithBuffer(x, y, width, height int16, buffer []color.RGBA) error { i, j := d.Size() diff --git a/waveshare-epd/epd2in13/epd2in13.go b/waveshare-epd/epd2in13/epd2in13.go index 6e143840e..14b2a5ed4 100644 --- a/waveshare-epd/epd2in13/epd2in13.go +++ b/waveshare-epd/epd2in13/epd2in13.go @@ -9,6 +9,8 @@ import ( "image/color" "machine" "time" + + "tinygo.org/x/drivers" ) type Config struct { @@ -19,7 +21,7 @@ type Config struct { } type Device struct { - bus machine.SPI + bus drivers.SPI cs machine.Pin dc machine.Pin rst machine.Pin @@ -51,7 +53,7 @@ var lutPartialUpdate = [30]uint8{ } // New returns a new epd2in13x driver. Pass in a fully configured SPI bus. -func New(bus machine.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device { +func New(bus drivers.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device { csPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) diff --git a/waveshare-epd/epd2in13x/epd2in13x.go b/waveshare-epd/epd2in13x/epd2in13x.go index d97291514..9d3be4002 100644 --- a/waveshare-epd/epd2in13x/epd2in13x.go +++ b/waveshare-epd/epd2in13x/epd2in13x.go @@ -9,6 +9,8 @@ import ( "image/color" "machine" "time" + + "tinygo.org/x/drivers" ) type Config struct { @@ -18,7 +20,7 @@ type Config struct { } type Device struct { - bus machine.SPI + bus drivers.SPI cs machine.Pin dc machine.Pin rst machine.Pin @@ -32,7 +34,7 @@ type Device struct { type Color uint8 // New returns a new epd2in13x driver. Pass in a fully configured SPI bus. -func New(bus machine.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device { +func New(bus drivers.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device { csPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) diff --git a/waveshare-epd/epd4in2/epd4in2.go b/waveshare-epd/epd4in2/epd4in2.go index e13ffee44..7c62a7e2d 100644 --- a/waveshare-epd/epd4in2/epd4in2.go +++ b/waveshare-epd/epd4in2/epd4in2.go @@ -12,6 +12,8 @@ import ( "image/color" "machine" "time" + + "tinygo.org/x/drivers" ) type Config struct { @@ -22,7 +24,7 @@ type Config struct { } type Device struct { - bus machine.SPI + bus drivers.SPI cs machine.Pin dc machine.Pin rst machine.Pin @@ -38,7 +40,7 @@ type Device struct { type Rotation uint8 // New returns a new epd4in2 driver. Pass in a fully configured SPI bus. -func New(bus machine.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device { +func New(bus drivers.SPI, csPin, dcPin, rstPin, busyPin machine.Pin) Device { csPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) diff --git a/wifinina/wifinina.go b/wifinina/wifinina.go index 93d573aee..64f112909 100644 --- a/wifinina/wifinina.go +++ b/wifinina/wifinina.go @@ -13,6 +13,7 @@ import ( "machine" + "tinygo.org/x/drivers" "tinygo.org/x/drivers/net" ) @@ -258,7 +259,7 @@ type command struct { } type Device struct { - SPI machine.SPI + SPI drivers.SPI CS machine.Pin ACK machine.Pin GPIO0 machine.Pin @@ -268,6 +269,17 @@ type Device struct { ssids [10]string } +// New returns a new Wiifinina driver. +func New(bus drivers.SPI, csPin, ackPin, gpio0Pin, resetPin machine.Pin) *Device { + return &Device{ + SPI: bus, + CS: csPin, + ACK: ackPin, + GPIO0: gpio0Pin, + RESET: resetPin, + } +} + func (d *Device) Configure() { net.UseDriver(d.NewDriver()) From 06ab27300ce43d70ca196c7de26e4cbeedb4b129 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sun, 18 Oct 2020 21:22:56 +0200 Subject: [PATCH 2/4] spi: incorporate change from GH issue feedback Signed-off-by: deadprogram --- apa102/apa102.go | 8 -------- spi.go | 6 ++++++ wifinina/wifinina.go | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/apa102/apa102.go b/apa102/apa102.go index a2d6ed91a..4a8ab9ae1 100644 --- a/apa102/apa102.go +++ b/apa102/apa102.go @@ -29,14 +29,6 @@ type Device struct { Order int } -// The SPI interface specifies the minimum functionality that a bus -// implementation needs to provide for use by the APA102 driver. Hardware -// SPI from the TinyGo "machine" package implements this already. -// type SPI interface { -// Tx(w, r []byte) error -// Transfer(b byte) (byte, error) -// } - // New returns a new APA102 driver. Pass in a fully configured SPI bus. func New(b drivers.SPI) Device { return Device{bus: b, Order: BGR} diff --git a/spi.go b/spi.go index f908afe6b..aa9e41030 100644 --- a/spi.go +++ b/spi.go @@ -2,6 +2,12 @@ package drivers // SPI represents a SPI bus. It is implemented by the machine.SPI type. type SPI interface { + // Tx transmits the given buffer w and receives at the same time the buffer r. + // The two buffers must be the same length. The only exception is when w or r are nil, + // in which case Tx only transmits (without receiving) or only receives (while sending 0 bytes). Tx(w, r []byte) error + + // Transfer writes a single byte out on the SPI bus and receives a byte at the same time. + // If you want to transfer multiple bytes, it is more efficient to use Tx instead. Transfer(b byte) (byte, error) } diff --git a/wifinina/wifinina.go b/wifinina/wifinina.go index 64f112909..a984ff3eb 100644 --- a/wifinina/wifinina.go +++ b/wifinina/wifinina.go @@ -269,7 +269,7 @@ type Device struct { ssids [10]string } -// New returns a new Wiifinina driver. +// New returns a new Wifinina driver. func New(bus drivers.SPI, csPin, ackPin, gpio0Pin, resetPin machine.Pin) *Device { return &Device{ SPI: bus, From c7f1c0e7738e4343ed516452b6031bc8bb02c3a0 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sun, 13 Dec 2020 09:56:59 +0100 Subject: [PATCH 3/4] drivers/flash: restore previous calls directly to machine package until we implement SetClockSpeed() Signed-off-by: deadprogram --- flash/flash.go | 12 ++++++------ flash/transport_spi.go | 27 +++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/flash/flash.go b/flash/flash.go index cfa268600..6054f45a8 100644 --- a/flash/flash.go +++ b/flash/flash.go @@ -135,12 +135,12 @@ func (dev *Device) Configure(config *DeviceConfig) (err error) { // Speed up to max device frequency // I propose a check here for max frequency, but not put that functionality directly into the driver. // Either that or we have to change the signature of the SPI interface in the machine package itself. - // if dev.attrs.MaxClockSpeedMHz > 0 { - // err := dev.trans.setClockSpeed(uint32(dev.attrs.MaxClockSpeedMHz) * 1e6) - // if err != nil { - // return err - // } - // } + if dev.attrs.MaxClockSpeedMHz > 0 { + err := dev.trans.setClockSpeed(uint32(dev.attrs.MaxClockSpeedMHz) * 1e6) + if err != nil { + return err + } + } // Enable Quad Mode if available if dev.trans.supportQuadMode() && dev.attrs.QuadEnableBitMask > 0 { diff --git a/flash/transport_spi.go b/flash/transport_spi.go index 4a19cf230..81db7b3f0 100644 --- a/flash/transport_spi.go +++ b/flash/transport_spi.go @@ -2,13 +2,12 @@ package flash import ( "machine" - - "tinygo.org/x/drivers" ) type transport interface { configure(config *DeviceConfig) supportQuadMode() bool + setClockSpeed(hz uint32) (err error) runCommand(cmd byte) (err error) readCommand(cmd byte, rsp []byte) (err error) writeCommand(cmd byte, data []byte) (err error) @@ -19,7 +18,7 @@ type transport interface { // NewSPI returns a pointer to a flash device that uses a SPI peripheral to // communicate with a serial memory chip. -func NewSPI(spi drivers.SPI, sdo, sdi, sck, cs machine.Pin) *Device { +func NewSPI(spi *machine.SPI, sdo, sdi, sck, cs machine.Pin) *Device { return &Device{ trans: &spiTransport{ spi: spi, @@ -32,7 +31,7 @@ func NewSPI(spi drivers.SPI, sdo, sdi, sck, cs machine.Pin) *Device { } type spiTransport struct { - spi drivers.SPI + spi *machine.SPI sdo machine.Pin sdi machine.Pin sck machine.Pin @@ -40,11 +39,31 @@ type spiTransport struct { } func (tr *spiTransport) configure(config *DeviceConfig) { + // Configure spi bus + tr.setClockSpeed(5000000) + // Configure chip select pin tr.ss.Configure(machine.PinConfig{Mode: machine.PinOutput}) tr.ss.High() } +func (tr *spiTransport) setClockSpeed(hz uint32) error { + // TODO: un-hardcode this max speed; it is probably a sensible + // default maximum for atsamd and nrf at least + if hz > 24*1e6 { + hz = 24 * 1e6 + } + tr.spi.Configure(machine.SPIConfig{ + Frequency: hz, + SDI: tr.sdi, + SDO: tr.sdo, + SCK: tr.sck, + LSBFirst: false, + Mode: 0, + }) + return nil +} + func (tr *spiTransport) supportQuadMode() bool { return false } From eb27bea5e21e2e0a61342467c7ebddd63197ec8c Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sun, 13 Dec 2020 10:42:27 +0100 Subject: [PATCH 4/4] test: run unit tests against i2c drivers and any spi drivers without direct gpio Signed-off-by: deadprogram --- .circleci/config.yml | 3 +++ Makefile | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 67f749706..9376d2024 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,6 +12,9 @@ jobs: - run: name: "Enforce Go Formatted Code" command: make fmt-check + - run: + name: "Run unit tests" + command: make unit-test - run: name: "Run build and smoke tests" command: make smoke-test diff --git a/Makefile b/Makefile index 4808532b8..96a1ee54f 100644 --- a/Makefile +++ b/Makefile @@ -158,4 +158,13 @@ endif tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis2mdl/main.go @md5sum ./build/test.hex -test: clean fmt-check smoke-test +DRIVERS = $(wildcard */) +NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 microphone mcp3008 gps microbitmatrix \ + hcsr04 ssd1331 ws2812 thermistor apa102 easystepper ssd1351 ili9341 wifinina shifter hub75 \ + hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x +TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS)) + +unit-test: + @go test -v $(addprefix ./,$(TESTS)) + +test: clean fmt-check unit-test smoke-test