From e9b1f05f3a789dc12a0e7734bc314d0212b9b5ef Mon Sep 17 00:00:00 2001 From: sat0ken <15720506+sat0ken@users.noreply.github.com> Date: Sun, 24 Nov 2024 20:39:11 +0900 Subject: [PATCH] Add support for gopher-badge i2c type (#11) --- Makefile | 1 + README.md | 2 + hardware/gopher-board-i2c.go | 126 ++++++++++++++++++++++++++++++++++ targets/gopher-board-i2c.json | 7 ++ 4 files changed, 136 insertions(+) create mode 100644 hardware/gopher-board-i2c.go create mode 100644 targets/gopher-board-i2c.json diff --git a/Makefile b/Makefile index 96ad382..bf7ed13 100644 --- a/Makefile +++ b/Makefile @@ -8,5 +8,6 @@ smoketest: FORCE tinygo build -o ./out/all.pybadge.uf2 --size short --target pybadge ./games/all/ tinygo build -o ./out/all.wioterminal.uf2 --size short --target wioterminal ./games/all/ tinygo build -o ./out/all.macropad-rp2040.uf2 --size short --target macropad-rp2040 ./games/all/ + tinygo build -o ./out/all.gopher-board-i2c.uf2 --size short --target ./targets/gopher-board-i2c.json ./games/all/ FORCE: diff --git a/README.md b/README.md index 6b8b967..780c359 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ The currently supported hardware is as follows. * https://www.seeedstudio.com/Wio-Terminal-p-4509.html * macropad-rp2040 * https://learn.adafruit.com/adafruit-macropad-rp2040 +* gopher-board + * https://github.com/sat0ken/gopher-board/tree/main/rp2040/v2 ## Add new hardware diff --git a/hardware/gopher-board-i2c.go b/hardware/gopher-board-i2c.go new file mode 100644 index 0000000..ba07b2f --- /dev/null +++ b/hardware/gopher-board-i2c.go @@ -0,0 +1,126 @@ +//go:build tinygo && gopher_board_i2c + +package hardware + +import ( + "machine" + + "github.com/sago35/koebiten" + "tinygo.org/x/drivers/ssd1306" +) + +var ( + Device = &device{} + Display *ssd1306.Device + gpioPins []machine.Pin +) + +type device struct { + gpioPins []machine.Pin + state []State + cycle []int +} + +const ( + debounce = 0 +) + +type State uint8 + +const ( + None State = iota + NoneToPress + Press + PressToRelease +) + +func (z *device) GetDisplay() koebiten.Displayer { + return Display +} + +func (z *device) Init() error { + i2c := machine.I2C0 + i2c.Configure(machine.I2CConfig{ + Frequency: 2_800_000, + SDA: machine.GPIO0, + SCL: machine.GPIO1, + }) + + d := ssd1306.NewI2C(i2c) + d.Configure(ssd1306.Config{ + Address: 0x3C, + Width: 128, + Height: 64, + }) + d.ClearDisplay() + Display = &d + + gpioPins = []machine.Pin{ + machine.GPIO4, // up + machine.GPIO5, // left + machine.GPIO6, // down + machine.GPIO7, // right + machine.GPIO27, // A + machine.GPIO28, // B + } + + for _, p := range gpioPins { + p.Configure(machine.PinConfig{Mode: machine.PinInputPullup}) + } + + z.gpioPins = []machine.Pin{ + machine.GPIO27, + machine.GPIO28, + machine.GPIO5, + machine.GPIO7, + machine.GPIO4, + machine.GPIO6, + } + + z.state = make([]State, len(z.gpioPins)) + z.cycle = make([]int, len(z.gpioPins)) + return nil +} + +func (z *device) KeyUpdate() error { + for r := range z.gpioPins { + current := !z.gpioPins[r].Get() + if z.gpioPins[r] == machine.NoPin { + current = false + } + idx := r + + switch z.state[idx] { + case None: + if current { + if z.cycle[idx] >= debounce { + z.state[idx] = NoneToPress + z.cycle[idx] = 0 + } else { + z.cycle[idx]++ + } + } else { + z.cycle[idx] = 0 + } + case NoneToPress: + z.state[idx] = Press + koebiten.AppendJustPressedKeys([]koebiten.Key{koebiten.Key(idx)}) + case Press: + koebiten.AppendPressedKeys([]koebiten.Key{koebiten.Key(idx)}) + if current { + z.cycle[idx] = 0 + } else { + if z.cycle[idx] >= debounce { + z.state[idx] = PressToRelease + z.cycle[idx] = 0 + } else { + z.cycle[idx]++ + } + } + case PressToRelease: + z.state[idx] = None + koebiten.AppendJustReleasedKeys([]koebiten.Key{koebiten.Key(idx)}) + } + } + return nil +} diff --git a/targets/gopher-board-i2c.json b/targets/gopher-board-i2c.json new file mode 100644 index 0000000..b397ca9 --- /dev/null +++ b/targets/gopher-board-i2c.json @@ -0,0 +1,7 @@ +{ + "inherits": [ + "waveshare-rp2040-zero" + ], + "build-tags": ["gopher_board_i2c"] +} +