diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..6324d40 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.14 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..4bed810 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Wokwi GDB", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/src/simulation/ESP32_GENERIC_S3-20260406-v1.28.0.bin", + "cwd": "${workspaceFolder}", + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/lldb", + "miDebuggerServerAddress": "localhost:1234" + } + ] +} \ No newline at end of file diff --git a/misc/wokwi-vscode-micropython b/misc/wokwi-vscode-micropython new file mode 160000 index 0000000..9b95e43 --- /dev/null +++ b/misc/wokwi-vscode-micropython @@ -0,0 +1 @@ +Subproject commit 9b95e43ee8709d463f885fcc44aa7a192898a4bd diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2b41cbd --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,12 @@ +[project] +name = "creaturedex" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.14" +dependencies = [] + +[dependency-groups] +dev = [ + "mpremote>=1.28.0", +] diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..152bea3 --- /dev/null +++ b/src/main.py @@ -0,0 +1,115 @@ +from machine import Pin, SPI, SoftSPI +import framebuf +import time +import random + +WIDTH = 128 +HEIGHT = 64 + + +class SecondaryDisplay: + def __init__(self, spi, dc_pin, ce_pin): + self.spi = spi + self.dc = dc_pin + self.ce = ce_pin + self.buffer = bytearray(WIDTH * HEIGHT // 8) + self.fb = framebuf.FrameBuffer(self.buffer, WIDTH, HEIGHT, framebuf.MONO_VLSB) + + self.ce.value(1) + self._init_display() + + def _command(self, value): + self.dc.value(0) + self.ce.value(0) + self.spi.write(bytes((value,))) + self.ce.value(1) + + def _data(self, payload): + self.dc.value(1) + self.ce.value(0) + self.spi.write(payload) + self.ce.value(1) + + def _init_display(self): + # These commands are accepted by the simulation chip model. + self._command(0x21) + self._command(0x20) + self._command(0x0C) + + def clear(self): + self.fb.fill(0) + + def text(self, message, x=0, y=0): + self.fb.text(message, x, y, 1) + + def show(self): + self._command(0x80) + self._command(0x40) + self._data(self.buffer) + + +def create_spi_bus(): + try: + return SPI( + 2, + baudrate=4_000_000, + polarity=0, + phase=0, + sck=Pin(36), + mosi=Pin(35), + miso=Pin(37), + ) + except Exception: + try: + return SPI( + 1, + baudrate=4_000_000, + polarity=0, + phase=0, + sck=Pin(36), + mosi=Pin(35), + miso=Pin(37), + ) + except Exception: + return SoftSPI( + baudrate=1_000_000, + polarity=0, + phase=0, + sck=Pin(36), + mosi=Pin(35), + miso=Pin(37), + ) + + +def main(): + print("hello i'm going to start") + spi = create_spi_bus() + print("spi bus created") + + rst = Pin(11, Pin.OUT, value=1) + dc = Pin(37, Pin.OUT, value=0) + ce1 = Pin(12, Pin.OUT, value=1) + ce2 = Pin(13, Pin.OUT, value=1) + ce3 = Pin(14, Pin.OUT, value=1) + + rst.value(0) + time.sleep_ms(10) + rst.value(1) + + displays = [ + SecondaryDisplay(spi, dc, ce1), + #SecondaryDisplay(spi, dc, ce2), + #SecondaryDisplay(spi, dc, ce3), + ] + + display = displays[0] + display.clear() + for i in range(10): + display.text(str(random.randint(0,i)), i, i) + display.show() + + while True: + time.sleep(1) + + +main() diff --git a/src/simulation/ESP32_GENERIC_S3-20251209-v1.27.0.bin b/src/simulation/ESP32_GENERIC_S3-20251209-v1.27.0.bin new file mode 100644 index 0000000..0124e92 Binary files /dev/null and b/src/simulation/ESP32_GENERIC_S3-20251209-v1.27.0.bin differ diff --git a/src/simulation/ESP32_GENERIC_S3-20260406-v1.28.0.bin b/src/simulation/ESP32_GENERIC_S3-20260406-v1.28.0.bin new file mode 100644 index 0000000..af05472 Binary files /dev/null and b/src/simulation/ESP32_GENERIC_S3-20260406-v1.28.0.bin differ diff --git a/src/simulation/chips/secondary-display/Makefile b/src/simulation/chips/secondary-display/Makefile index adfe690..d4bfaf0 100644 --- a/src/simulation/chips/secondary-display/Makefile +++ b/src/simulation/chips/secondary-display/Makefile @@ -13,7 +13,7 @@ dist: $(TARGET): dist $(SOURCES) wokwi-api.h podman run --rm -u root -v "$(CURDIR)":/src:Z -w /src docker.io/wokwi/builder-clang-wasm:latest \ - clang --target=wasm32-unknown-wasi --sysroot /opt/wasi-libc -nostartfiles -Wl,--import-memory -Wl,--export-table -Wl,--no-entry -Werror -o $(TARGET) $(SOURCES) + clang --target=wasm32-unknown-wasi -g -O0 --sysroot /opt/wasi-libc -nostartfiles -Wl,--import-memory -Wl,--export-table -Wl,--no-entry -Werror -o $(TARGET) $(SOURCES) dist/chip.json: dist chip.json cp chip.json dist diff --git a/src/simulation/chips/secondary-display/dist/chip.wasm b/src/simulation/chips/secondary-display/dist/chip.wasm index 4e49010..3b95a7d 100755 Binary files a/src/simulation/chips/secondary-display/dist/chip.wasm and b/src/simulation/chips/secondary-display/dist/chip.wasm differ diff --git a/src/simulation/wokwi.toml b/src/simulation/wokwi.toml index db54d99..3d268a7 100644 --- a/src/simulation/wokwi.toml +++ b/src/simulation/wokwi.toml @@ -1,7 +1,11 @@ [wokwi] version = 1 -firmware = "../build/firmware.bin" -elf = "../build/firmware.elf" +#firmware = "ESP32_GENERIC_S3-20251209-v1.27.0.bin" +#elf = "ESP32_GENERIC_S3-20251209-v1.27.0.bin" +firmware = "ESP32_GENERIC_S3-20260406-v1.28.0.bin" +elf = "ESP32_GENERIC_S3-20260406-v1.28.0.bin" +rfc2217ServerPort = 4000 +gdbServerPort=1234 [[chip]] name = "main-display" @@ -13,4 +17,4 @@ binary = "chips/secondary-display/dist/chip.wasm" [[chip]] name = "nfc-reader" -binary = "chips/nfc-reader/dist/chip.wasm" \ No newline at end of file +binary = "chips/nfc-reader/dist/chip.wasm" diff --git a/target/flycheck0/stderr b/target/flycheck0/stderr new file mode 100644 index 0000000..9f3eec1 --- /dev/null +++ b/target/flycheck0/stderr @@ -0,0 +1 @@ +error: manifest path `/home/rhetenor/Projects/creaturedex/Cargo.toml` does not exist diff --git a/target/flycheck0/stdout b/target/flycheck0/stdout new file mode 100644 index 0000000..e69de29 diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..72aa13a --- /dev/null +++ b/uv.lock @@ -0,0 +1,49 @@ +version = 1 +revision = 3 +requires-python = ">=3.14" + +[[package]] +name = "creaturedex" +version = "0.1.0" +source = { virtual = "." } + +[package.dev-dependencies] +dev = [ + { name = "mpremote" }, +] + +[package.metadata] + +[package.metadata.requires-dev] +dev = [{ name = "mpremote", specifier = ">=1.28.0" }] + +[[package]] +name = "mpremote" +version = "1.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "pyserial" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/20/1b/d008342d1b018fb60e1196bf72a164ea71a567f924db11934f0e3a0a10bc/mpremote-1.28.0.tar.gz", hash = "sha256:fdb5626be83dff4e53c0184f8950814cb519b524dba7f1f8b1668aa477257a31", size = 31412, upload-time = "2026-04-06T13:21:14.976Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/d7/634a63290002a9df2708e05983fc769447d64f074ac2e8d8990316c70fd0/mpremote-1.28.0-py3-none-any.whl", hash = "sha256:2df2a50f3c8098cae8c732dbf2541e7e58185e7896513b45d05196901e049334", size = 36098, upload-time = "2026-04-06T13:21:13.368Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/78/9b/560e4be8e26f6fd133a03630a8df0c663b9e8d61b4ade152b72005aec83b/platformdirs-4.11.0.tar.gz", hash = "sha256:0555d18370482847566ffabcaa53ad7c6c1c29f195989ae1ed634a05f76ea1e0", size = 31953, upload-time = "2026-07-21T13:09:36.565Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/68/d8d58938dfb1370b266a1a729e6d77a985be23689a0496498ee17b2cbf90/platformdirs-4.11.0-py3-none-any.whl", hash = "sha256:360ccded2b7fce0af0ff80cc8f5942a1c5d99b0e856033acb030bfc634709e74", size = 23247, upload-time = "2026-07-21T13:09:35.422Z" }, +] + +[[package]] +name = "pyserial" +version = "3.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/7d/ae3f0a63f41e4d2f6cb66a5b57197850f919f59e558159a4dd3a818f5082/pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb", size = 159125, upload-time = "2020-11-23T03:59:15.045Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0", size = 90585, upload-time = "2020-11-23T03:59:13.41Z" }, +]