From c344e5d879b7126193d6bfc5b738b7ce1d6c4687 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Wed, 21 Feb 2024 01:02:23 +0100 Subject: [PATCH] ssd1306: improvements needed for Thumby SPI display Signed-off-by: deadprogram --- examples/ssd1306/spi_thumby/main.go | 50 +++++++++++++++++++++++++++++ ssd1306/ssd1306.go | 30 ++++++++++++++--- 2 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 examples/ssd1306/spi_thumby/main.go diff --git a/examples/ssd1306/spi_thumby/main.go b/examples/ssd1306/spi_thumby/main.go new file mode 100644 index 0000000..b2a41e5 --- /dev/null +++ b/examples/ssd1306/spi_thumby/main.go @@ -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) + } +} diff --git a/ssd1306/ssd1306.go b/ssd1306/ssd1306.go index 2f27096..53b38ba 100644 --- a/ssd1306/ssd1306.go +++ b/ssd1306/ssd1306.go @@ -13,6 +13,8 @@ import ( "tinygo.org/x/drivers/internal/legacy" ) +type ResetValue [2]byte + // Device wraps I2C or SPI connection. type Device struct { bus Buser @@ -22,6 +24,8 @@ type Device struct { bufferSize int16 vccState VccMode canReset bool + resetCol ResetValue + resetPage ResetValue } // Config is the configuration for the display @@ -30,6 +34,13 @@ type Config struct { Height int16 VccState VccMode Address uint16 + // ResetCol and ResetPage are used to reset the screen to 0x0 + // This is useful for some screens that have a different size than 128x64 + // For example, the Thumby's screen is 72x40 + // The default values are normally set automatically based on the size. + // If you're using a different size, you might need to set these values manually. + ResetCol ResetValue + ResetPage ResetValue } type I2CBus struct { @@ -79,6 +90,7 @@ func NewSPI(bus drivers.SPI, dcPin, resetPin, csPin machine.Pin) Device { // Configure initializes the display with default configuration func (d *Device) Configure(cfg Config) { + var zeroReset ResetValue if cfg.Width != 0 { d.width = cfg.Width } else { @@ -97,6 +109,16 @@ func (d *Device) Configure(cfg Config) { } else { d.vccState = SWITCHCAPVCC } + if cfg.ResetCol != zeroReset { + d.resetCol = cfg.ResetCol + } else { + d.resetCol = ResetValue{0, uint8(d.width - 1)} + } + if cfg.ResetPage != zeroReset { + d.resetPage = cfg.ResetPage + } else { + d.resetPage = ResetValue{0, uint8(d.height/8) - 1} + } d.bufferSize = d.width * d.height / 8 d.buffer = make([]byte, d.bufferSize) d.canReset = cfg.Address != 0 || d.width != 128 || d.height != 64 // I2C or not 128x64 @@ -186,11 +208,11 @@ func (d *Device) Display() error { // Since we're printing the whole buffer, avoid resetting it in this case if d.canReset { d.Command(COLUMNADDR) - d.Command(0) - d.Command(uint8(d.width - 1)) + d.Command(d.resetCol[0]) + d.Command(d.resetCol[1]) d.Command(PAGEADDR) - d.Command(0) - d.Command(uint8(d.height/8) - 1) + d.Command(d.resetPage[0]) + d.Command(d.resetPage[1]) } return d.Tx(d.buffer, false)