Skip to content

Instantly share code, notes, and snippets.

@todbot
Last active July 16, 2025 21:24
Show Gist options
  • Save todbot/e91853b9d5e021405bb9a85081a39163 to your computer and use it in GitHub Desktop.
Save todbot/e91853b9d5e021405bb9a85081a39163 to your computer and use it in GitHub Desktop.
Find the defined board.* pins for a CircuitPython board, given a repo directory
#!/usr/bin/env python3
# Find all the defined pins for a CircuitPython board
# 5 Jul 2025 - @todbot / Tod Kurt
# e.g. "cirpy-showpins.py qtpy_m0 ~/projects/adafruit/circuitpython"
# Note: you need a checkout of the CircuitPython github repo for this tool to work
# e.g. "mkdir -f ~/projects/adafruit && cd ~/projects/adafruit && git checkout https://github.com/adafruit/circuitpython/"
import os, sys, re
if len(sys.argv) <= 1:
print("usage: cirpy-showpins.py board_id [repo_dir]")
exit(1)
home_dir = os.path.expanduser('~')
board_id = sys.argv[1]
cirpy_repo = sys.argv[2] if len(sys.argv)==3 else home_dir + "/projects/adafruit/circuitpython"
print("board_id:", board_id)
def find_port_dir(board_id, repo_dir):
"""Find port directory for given board_id or None"""
ports_dir = repo_dir+"/ports"
for root, dirs, files in os.walk(ports_dir):
for d in dirs:
if d.endswith(board_id) and d.find('build')==-1:
return root + "/" + d
return None
def find_pins(board_id, repo_dir):
port_dir = find_port_dir(board_id, repo_dir)
if not port_dir:
print("no board found with id", board_id)
exit(1)
pins = []
with open(port_dir+"/pins.c", "r") as pin_file:
for line in pin_file:
if m:= re.search(r'MP_QSTR_(.+?)\)', line):
pins.append(m[1])
return pins
pins = find_pins(board_id, cirpy_repo)
print("pins:", " ".join(sorted(pins)))
@todbot
Copy link
Author

todbot commented Jul 5, 2025

Here's what the output looks like for a few boards:
Screenshot 2025-07-05 at 12 02 32 PM

@todbot
Copy link
Author

todbot commented Jul 5, 2025

Original Perl version:

#!/usr/bin/env perl
# Find all the defined pins for a CircuitPython board
# 5 Jul 2025 - @todbot / Tod Kurt
# original idea: perl -ne 'if(/MP_QSTR_(.+?)\),/) { print "$1\n" } '  ~/projects/adafruit/circuitpython/ports/raspberrypi/boards/waveshare_rp2040_zero/pins.c |

use strict;  use warnings;
use File::Find;

my $CIRPY_REPO = "/Users/tod/projects/adafruit/circuitpython";

my ($board_id) = @ARGV;

if (not defined $board_id) {
    die "usage: cirpy-showpins board_id\n";
}

print("searching for board_id: $board_id\n");

my @port_dirs;
find(
     sub{ 
         -d $_ && $_ =~ /^$board_id$/  
             && push @port_dirs, $File::Find::name
     }, "$CIRPY_REPO/ports"
    );

my $port_dir = $port_dirs[0];

if (not defined $port_dir) {
    die "could not find port named '$board_id'";
}
my $stripped_port_dir = $port_dir;  $stripped_port_dir =~ s/$CIRPY_REPO\///;
print("port_dir: $stripped_port_dir\n");

my @port_pins;
open(FH, "<", "$port_dir/pins.c") or die("Cannot open port_dir: $!\n");
while(<FH>) {
    if( $_ =~ /MP_QSTR_(.+?)\),/) { push @port_pins, $1; }
}
close(FH);

my @sorted_pins = sort @port_pins;
print("pins: @sorted_pins\n");

@TheKitty
Copy link

Great project!

@todbot
Copy link
Author

todbot commented Jul 15, 2025

Great project!

Thanks! I only now realized that this replicates some of the function of board_stub_builder.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment