summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Trentini <matt.trentini@gmail.com>2025-04-25 14:39:25 +1000
committerDamien George <damien@micropython.org>2025-12-01 16:05:49 +1100
commitbfacf821f448c4d99055738e90de81e50dcb156c (patch)
tree8f9216b3c3b63fc20dc2e5005e7c1432fed23ded
parent7357fc583b5a0407d1b4b7e07aa932f99b0eb32b (diff)
rp2/boards/WEACTSTUDIO_RP2350B_CORE: Add board.pinout.
This adds an ANSI-rendered pinout for the WeAct Studio RP2350B Core board. Signed-off-by: Matt Trentini <matt.trentini@gmail.com>
-rw-r--r--ports/rp2/boards/WEACTSTUDIO_RP2350B_CORE/manifest.py1
-rw-r--r--ports/rp2/boards/WEACTSTUDIO_RP2350B_CORE/modules/board.py8
-rw-r--r--tools/make_pinout_diagram/README.md43
-rw-r--r--tools/make_pinout_diagram/compress.py10
-rw-r--r--tools/make_pinout_diagram/pinout.py104
-rw-r--r--tools/make_pinout_diagram/weact_pinout.pngbin0 -> 22295 bytes
6 files changed, 166 insertions, 0 deletions
diff --git a/ports/rp2/boards/WEACTSTUDIO_RP2350B_CORE/manifest.py b/ports/rp2/boards/WEACTSTUDIO_RP2350B_CORE/manifest.py
index 832942f05..7ae2ed15d 100644
--- a/ports/rp2/boards/WEACTSTUDIO_RP2350B_CORE/manifest.py
+++ b/ports/rp2/boards/WEACTSTUDIO_RP2350B_CORE/manifest.py
@@ -1 +1,2 @@
include("$(PORT_DIR)/boards/manifest.py")
+freeze("modules")
diff --git a/ports/rp2/boards/WEACTSTUDIO_RP2350B_CORE/modules/board.py b/ports/rp2/boards/WEACTSTUDIO_RP2350B_CORE/modules/board.py
new file mode 100644
index 000000000..8e3cc2953
--- /dev/null
+++ b/ports/rp2/boards/WEACTSTUDIO_RP2350B_CORE/modules/board.py
@@ -0,0 +1,8 @@
+import deflate
+import io
+
+_compressed_pinout = b'(\x91\xcd\x92\xbdn\xdb0\x10\xc7w\xbdB\x96\x1b\x93M$E\xc9\x82\xa7:Q\x83"A\x1c\xd8\x89;d*\x1a\x0f\x1d\x04\x03A:t\x0b\xbc6F:HA\x91%C\xbb\x14h\x9d<A\x1f\x86OR\x8a\x92]K"O\x96\x98\x02=\x10\x12\xc1\xfb \x7f\xff;\x07r\xdb\xb9\xf0\xbc>\x89amo\xa7\xaf\xde_\xc3\xf8\xfa\xe3\xe5\x87\x19\x8cN)\xe3\xee\x00\xf6gWS\x18\xcc\xde]]\xfe\r\xdc\xb9pc\xc7\x01\x83\x89\xf4\x97Hn\xe4\x82Q4\x8e\xceVqG\xd3O\xb0{(\xab\xeeA\xee\xceV\xba\x94\xf1\xc9|3i0\x1c\x9eUk\xaf\xbd\xffp\xa5KG\x82\xb1^\x9f\xf7\t\x8f\xa58\xd9\x8ey1P?\'\x06\x83\x9b\xaf\xdc\x12\xa4\x88\xa0\xd4\x8d\xc5\xedou\xac9*p\xd2e}\xb3\x81[\xbb\x8d\x12?\x86\xfd\xe3\xa3\xe2:\xd0\x95\xae\x1f)y\xf5/\xf7P0\xa0\xach\xb5!\xbd\x87\xeb\x12\xb4\xd7%\x99\x8b\x9f\xdf\xb3om\x93\xeb"\xff\x986\x07o\x86\xe5\x17uV\x866(CPe\x98\x8b+\x13v\x98\x98g5\x1fO\xf5M\xed\x8aL\tq\xf7\xa0\xae\xc8&J\xa9fV\x8e\xc8\xf7N\x98\x8a\xb6U\r\xc7\x06\x12\xe2\xaa\xe1\xa23\xd2Z5i\xc7\xd1\xc1\xba\x1c\rcq\xffc\xe5\xd9\xae\xc4\xd6\x17Y\xcf\x1c\xe95\xa8\x17\xe0\xeay\xb8z\xac\x83z\xbb\x87\xa7\x94\xef\xc9\x8dx\xfc,\x1e\x17\xb0a\xb6\xb0~\x03,\xc7a\xf1t\xc6\xbb\x8cJn\x125\xff-^\x0e\x16o\r\x10\x86\xc3\xe2\x83\xc1\x82\xae\xb0\x05j\x05\xd7\x16\x966\xc0\x12#,\xed\xc5\xe0\xb98l\xd8\x1dv\xa1\xe1\xb6\x85\xc5_\x0b\x10\xe2\xb0f\xad\x94\x9b\xd8\x8c\xf1\xa2\x82j\r\x0b\xf8\x1c\x02\x048\xac\x87\xc3\xb2\xee\xb0\n\xb7\x84j\x0f\xeb7\xc0r\x1c\xd6\x9c\xae\xdc\xdc\x06\xb6l\xb6\xa0\xe6\xb6\xe4\xa0l\x05\n\xa3\xf3\x130\x01\x05\xff\x0f\x10m\x00"\xc6\xce\x91\x18\xd8\x84\x99\xb2K\xde\xd6\x98"\xb9\x15\xc9Mm}y1l\x17\x9d\xb8\xc9(zm\xc4\xf63\xa0\xbb\x87j\x01\x7f]\x80\xca\x0b\xa2\x13C\x8b\xef\xbf5\xb3\xcf+\x9b\n\xaf\xa6D~\xa4\xe75=X\x13\xd0\x96\xd9\x18\xd0\x0c]\x1cm\r\xdd\xb2\xc9r\xfc\xf8\xc4\xfc\\\xd9\xe2\xc1\xf9\xb8\xc0-\x9bH\x9fu\xa3W_\x89\xee\xf0\xebV\xb9\xe9\x93\xe3\xfc\x01\x83\'\xd6K'
+
+
+def pinout():
+ print(str(deflate.DeflateIO(io.BytesIO(_compressed_pinout), deflate.ZLIB).read(), "utf-8"))
diff --git a/tools/make_pinout_diagram/README.md b/tools/make_pinout_diagram/README.md
new file mode 100644
index 000000000..bebd7df7c
--- /dev/null
+++ b/tools/make_pinout_diagram/README.md
@@ -0,0 +1,43 @@
+# Pinout diagram
+
+Pinout diagrams can be a helpful tool to display the pin layout for a board.
+
+Rendering them using ANSI and building them into a board's firmware means they
+are always conveniently available, even over a serial connection.
+
+![WeAct RP2350B Core pinout diagram](weact_pinout.png)
+
+## Overview
+
+`pinout.py` generates a unicode pinout diagram that uses ANSI escape characters
+to add colour. It currently generates the pinout diagram for the WeActStudio
+RP2350B board but is an example that could be extended for any board.
+
+Display the output by executing the script:
+
+```bash
+python pinout.py
+```
+
+
+## Compression
+
+`compress.py` uses zlib to _compress input_ and output a _byte string_.
+
+The output from `pinout.py` can be large but compresses efficiently, so the
+intent is that the byte string output from `compress.py` can then be copied to
+`../modules/board.py` so that the _compressed_ pinout will be included in the
+firmware.
+
+To execute:
+
+```bash
+python pinout.py | python compress.py
+```
+
+## Reference
+
+[Build your own Command Line with ANSI escape
+codes](https://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html)
+provides a good reference of how to use ANSI codes, including helpful colour
+lookups.
diff --git a/tools/make_pinout_diagram/compress.py b/tools/make_pinout_diagram/compress.py
new file mode 100644
index 000000000..7e95ab035
--- /dev/null
+++ b/tools/make_pinout_diagram/compress.py
@@ -0,0 +1,10 @@
+import sys
+import zlib
+
+data_str = sys.stdin.read()
+compressed = zlib.compress(bytes(data_str, "utf-8"), wbits=10)
+print(
+ f"{len(data_str) / len(compressed):.1f}x smaller: uncompressed={len(data_str)}, compressed={len(compressed)}",
+ file=sys.stderr,
+)
+print(compressed)
diff --git a/tools/make_pinout_diagram/pinout.py b/tools/make_pinout_diagram/pinout.py
new file mode 100644
index 000000000..569f40510
--- /dev/null
+++ b/tools/make_pinout_diagram/pinout.py
@@ -0,0 +1,104 @@
+import re
+
+pinout_str = """
+ \u001b[44;1m WeAct Studio RP2350B Core Board \u001b[0m
+
+ ╭── RESET
+ Key (GP23) ───╮ │ ╭── BOOT
+ ╭────────────────────────────────╮
+ [26 ] [25 ] │⌾ ⌾ ╭─╮╭─╮╭─╮ ╭─[CLK] ⌾ ⌾│ [24 ] [ 23 ]
+ [28 ] [27 ] │⌾ ⌾ │⬤││⬤││⬤│ │ ╭─[DIO] ⌾ ⌾│ [22 ] [ 21 ]
+ [30 ] [29 ] │⌾ ⌾ ╰─╯╰─╯╰─╯[⏚]╮ │ │ ╭─[3V3]⌾ ⌾│ [20 ] [ 19 ]
+ [32 ] [31 ] │⌾ ⌾ LED ▩ ⌾ ⌾ ⌾ ⌾ ⌾ ⌾│ [18 ] [ 17 ]
+ [34 ] [33 ] │⌾ ⌾ (GP25) ⟋⟍ ⌾ ⌾│ [16 ] [ 15 ]
+ [36 ] [35 ] │⌾ ⌾ ⟋ ⟍ ⌾ ⌾│ [14 ] [ 13 ]
+ [38 ] [37 ] │⌾ ⌾ ⟋ ⟍ ⌾ ⌾│ [12 ] [ 11 ]
+ [40 ] [39 ] │⌾ ⌾ ⟍ ⟋ ⌾ ⌾│ [10 ] [ 9 ]
+ [42 ] [41 ] │⌾ ⌾ ⟍ ⟋ ⌾ ⌾│ [ 8 ] [ 7 ]
+ [44 ] [43 ] │⌾ ⌾ ⟍⟋ ⌾ ⌾│ [ 6 ] [ 5 ]
+ [46 ] [45 ] │⌾ ⌾ ⌾ ⌾│ [ 4 ] [ 3 ]
+ [RUN] [47 ] │⌾ ⌾ ⌾ ⌾│ [ 2 ] [ 1 ]
+ [3V3] [3V3] │⌾ ⌾ ┌──────┐ ⌾ ⌾│ [ 0 ] [VREF]
+ [ ⏚ ] [EN ] │▣ ⌾ │ │ ▣ ▣│ [ ⏚ ] [ ⏚ ]
+ [ ⏚ ] [ ⏚ ] │▣ ▣ │ │ ⌾ ⌾│ [5V ] [VBUS]
+ ╰────────────└──────┘────────────╯
+"""
+
+
+def ansi_colour(wrap_str: str, colours: tuple[int | None, int | None]) -> str:
+ """Wrap a string in the ANSI foreground and background colour escape sequences."""
+ wrapped_str = ""
+
+ wrapped_str += "\u001b[38;5;" + str(colours[0]) + "m" if colours[0] else ""
+ wrapped_str += "\u001b[48;5;" + str(colours[1]) + "m" if colours[1] else ""
+ wrapped_str += wrap_str
+ wrapped_str += "\u001b[0m" if colours[0] or colours[1] else ""
+
+ return wrapped_str
+
+
+def add_colour(pinout_str):
+ symbol_colours = {
+ "⌾": (220, None), # Pin (Yellow)
+ "▣": (220, None), # Ground pin (Yellow)
+ "↺": (15, None), # Reset (White)
+ "▩": (129, None), # LED (Purple)
+ }
+
+ for symbol, colours in symbol_colours.items():
+ pinout_str = pinout_str.replace(symbol, ansi_colour(symbol, colours))
+ return pinout_str
+
+
+def colour_tags(matchobj: re.Match) -> str:
+ white_on_red = (15, 1)
+ white_on_peach = (15, 216)
+ white_on_dark_green = (15, 28)
+ white_on_black = (15, 16)
+ black_on_pink = (16, 224)
+
+ tag_colours = {
+ "5V": white_on_red,
+ "VBUS": white_on_red,
+ "VREF": white_on_dark_green,
+ "3V3": white_on_red,
+ "⏚": white_on_black,
+ "EN": black_on_pink,
+ "CLK": white_on_peach,
+ "DIO": white_on_peach,
+ }
+
+ if matchobj.group(2) not in tag_colours.keys():
+ return matchobj.group(0)
+
+ pin_colours = tag_colours[matchobj.group(2)]
+
+ return ansi_colour(matchobj.group(1), pin_colours)
+
+
+def replace_tags(pinout_str):
+ return re.sub(r"(\[\s*(\S+)\s*\])", colour_tags, pinout_str)
+
+
+def colour_pins(matchobj: re.Match) -> str:
+ # Regular GPIO is green, ADC pins (40-47) are darker greeen
+ gpio_colours = (15, 34) # White on green
+ adc_colours = (15, 28) # White on dark green
+ pin_number = int(matchobj.group(2))
+
+ pin_colours = gpio_colours if pin_number < 40 else adc_colours
+
+ return ansi_colour(matchobj.group(1), pin_colours)
+
+
+def replace_gpio(pinout_str) -> str:
+ return re.sub(r"(\[\s*(\d+)\s*\])", colour_pins, pinout_str)
+
+
+pinout_str = replace_gpio(replace_tags(add_colour(pinout_str)))
+# Colours include a square bracket; temporarily change them!
+pinout_str = pinout_str.replace("\u001b[", "~")
+pinout_str = pinout_str.replace("[", " ").replace("]", " ")
+pinout_str = pinout_str.replace("~", "\u001b[") # Put them back
+
+print(pinout_str)
diff --git a/tools/make_pinout_diagram/weact_pinout.png b/tools/make_pinout_diagram/weact_pinout.png
new file mode 100644
index 000000000..35240ed9e
--- /dev/null
+++ b/tools/make_pinout_diagram/weact_pinout.png
Binary files differ