From 8a6f57723916794b7c742a72b07849f6d3212d60 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sun, 14 Dec 2025 11:11:38 +0100 Subject: [PATCH 1/3] st7789: remove dependency on the machine package by using internal/pin instead Signed-off-by: deadprogram --- st7789/st7789.go | 56 ++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/st7789/st7789.go b/st7789/st7789.go index 5db2402ba..561a55902 100644 --- a/st7789/st7789.go +++ b/st7789/st7789.go @@ -7,13 +7,14 @@ package st7789 // import "tinygo.org/x/drivers/st7789" import ( "image/color" - "machine" "math" "time" "errors" "tinygo.org/x/drivers" + "tinygo.org/x/drivers/internal/legacy" + "tinygo.org/x/drivers/internal/pin" "tinygo.org/x/drivers/pixel" ) @@ -46,10 +47,10 @@ type Device = DeviceOf[pixel.RGB565BE] // formats. type DeviceOf[T Color] struct { bus drivers.SPI - dcPin machine.Pin - resetPin machine.Pin - csPin machine.Pin - blPin machine.Pin + dcPin pin.OutputFunc + resetPin pin.OutputFunc + csPin pin.OutputFunc + blPin pin.OutputFunc width int16 height int16 columnOffsetCfg int16 @@ -83,23 +84,27 @@ type Config struct { } // 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) } // NewOf creates a new ST7789 connection with a particular pixel format. The SPI // wire must already be configured. -func NewOf[T Color](bus drivers.SPI, resetPin, dcPin, csPin, blPin machine.Pin) DeviceOf[T] { - dcPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) - resetPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) - csPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) - blPin.Configure(machine.PinConfig{Mode: machine.PinOutput}) +func NewOf[T Color](bus drivers.SPI, resetPin, dcPin, csPin, blPin pin.Output) DeviceOf[T] { + // IMPORTANT: pin configuration should really be done outside of this + // driver, but for backwards compatibility with existing code, we do it + // here. + legacy.ConfigurePinOut(dcPin) + legacy.ConfigurePinOut(resetPin) + legacy.ConfigurePinOut(csPin) + legacy.ConfigurePinOut(blPin) + return DeviceOf[T]{ bus: bus, - dcPin: dcPin, - resetPin: resetPin, - csPin: csPin, - blPin: blPin, + dcPin: dcPin.Set, + resetPin: resetPin.Set, + csPin: csPin.Set, + blPin: blPin.Set, } } @@ -139,12 +144,7 @@ func (d *DeviceOf[T]) Configure(cfg Config) { d.batchLength += d.batchLength & 1 // Reset the device - d.resetPin.High() - time.Sleep(50 * time.Millisecond) - d.resetPin.Low() - time.Sleep(50 * time.Millisecond) - d.resetPin.High() - time.Sleep(50 * time.Millisecond) + d.Reset() // Common initialization d.startWrite() @@ -212,6 +212,16 @@ func (d *DeviceOf[T]) Configure(cfg Config) { d.blPin.High() // Backlight ON } +// Reset performs a hardware reset of the display. +func (d *DeviceOf[T]) Reset() { + d.resetPin.High() + time.Sleep(50 * time.Millisecond) + d.resetPin.Low() + time.Sleep(50 * time.Millisecond) + d.resetPin.High() + time.Sleep(50 * time.Millisecond) +} + // Send a command with data to the display. It does not change the chip select // pin (it must be low when calling). The DC pin is left high after return, // meaning that data can be sent right away. @@ -229,7 +239,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 // chip select pin low. func (d *DeviceOf[T]) startWrite() { - if d.csPin != machine.NoPin { + if d.csPin != nil { d.csPin.Low() } } @@ -237,7 +247,7 @@ func (d *DeviceOf[T]) startWrite() { // endWrite must be called at the end of all exported methods to set the chip // select pin high. func (d *DeviceOf[T]) endWrite() { - if d.csPin != machine.NoPin { + if d.csPin != nil { d.csPin.High() } } From 6d3907c0f436ce51652883b693f60584980d48ae Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sun, 14 Dec 2025 11:12:36 +0100 Subject: [PATCH 2/3] examples: switch st7789 example to use the Adafruit Clue since that device actually comes with one. Signed-off-by: deadprogram --- examples/st7789/main.go | 8 ++++---- smoketest.sh | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/st7789/main.go b/examples/st7789/main.go index 48532d871..941e65f4f 100644 --- a/examples/st7789/main.go +++ b/examples/st7789/main.go @@ -29,10 +29,10 @@ func main() { Mode: 0, }) display := st7789.New(machine.SPI0, - machine.P6, // TFT_RESET - machine.P7, // TFT_DC - machine.P8, // TFT_CS - machine.P9) // TFT_LITE + machine.TFT_RESET, // TFT_RESET + machine.TFT_DC, // TFT_DC + machine.TFT_CS, // TFT_CS + machine.TFT_LITE) // TFT_LITE display.Configure(st7789.Config{ Rotation: st7789.NO_ROTATION, diff --git a/smoketest.sh b/smoketest.sh index aee7229e9..4ef8db102 100755 --- a/smoketest.sh +++ b/smoketest.sh @@ -74,7 +74,7 @@ tinygo build -size short -o ./build/test.hex -target=xiao-rp2040 ./examples/ssd1 tinygo build -size short -o ./build/test.hex -target=thumby ./examples/ssd1306/ 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/st7789/main.go +tinygo build -size short -o ./build/test.hex -target=clue ./examples/st7789/main.go tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/thermistor/main.go tinygo build -size short -o ./build/test.hex -target=circuitplay-bluefruit ./examples/tone tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/tm1637/main.go From 22f27660370753a757a54c4e1bac6d4965a9a5a4 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sun, 14 Dec 2025 11:19:41 +0100 Subject: [PATCH 3/3] st7789: add Bus interface to accomodate both SPI and parallel connections to display Signed-off-by: deadprogram --- st7789/bus.go | 8 ++++++++ st7789/st7789.go | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 st7789/bus.go diff --git a/st7789/bus.go b/st7789/bus.go new file mode 100644 index 000000000..44a2ea82b --- /dev/null +++ b/st7789/bus.go @@ -0,0 +1,8 @@ +package st7789 + +// Bus is the interface that wraps the basic Tx and Transfer methods +// for communication buses like SPI or Parallel. +type Bus interface { + Tx(w, r []byte) error + Transfer(w byte) (byte, error) +} diff --git a/st7789/st7789.go b/st7789/st7789.go index 561a55902..838f28400 100644 --- a/st7789/st7789.go +++ b/st7789/st7789.go @@ -46,7 +46,7 @@ type Device = DeviceOf[pixel.RGB565BE] // DeviceOf is a generic version of Device. It supports multiple different pixel // formats. type DeviceOf[T Color] struct { - bus drivers.SPI + bus Bus dcPin pin.OutputFunc resetPin pin.OutputFunc csPin pin.OutputFunc @@ -84,13 +84,13 @@ type Config struct { } // New creates a new ST7789 connection. The SPI wire must already be configured. -func New(bus drivers.SPI, resetPin, dcPin, csPin, blPin pin.Output) Device { +func New(bus Bus, resetPin, dcPin, csPin, blPin pin.Output) Device { return NewOf[pixel.RGB565BE](bus, resetPin, dcPin, csPin, blPin) } // NewOf creates a new ST7789 connection with a particular pixel format. The SPI // wire must already be configured. -func NewOf[T Color](bus drivers.SPI, resetPin, dcPin, csPin, blPin pin.Output) DeviceOf[T] { +func NewOf[T Color](bus Bus, resetPin, dcPin, csPin, blPin pin.Output) DeviceOf[T] { // IMPORTANT: pin configuration should really be done outside of this // driver, but for backwards compatibility with existing code, we do it // here.