Skip to content

Commit

Permalink
Release v2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
sco1 authored Feb 3, 2025
2 parents 07f3bfb + 7a6b08f commit 5155b33
Show file tree
Hide file tree
Showing 188 changed files with 902 additions and 231 deletions.
6 changes: 6 additions & 0 deletions .bumper.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[tool.bumper]
current_version = "2.0.0"

[[tool.bumper.files]]
file = "./pyproject.toml"
search = 'version = "{current_version}"'
8 changes: 0 additions & 8 deletions .bumpversion.cfg

This file was deleted.

83 changes: 66 additions & 17 deletions .github/workflows/release_artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,85 @@ jobs:
with:
python-version-file: "pyproject.toml"

- name: Compile skyportal lib
run: |
python ./compile.py
- name: Build base bundle
run: |
tar -cvf bundle_base.tar \
./assets/* \
./lib/* \
./boot.py \
./code.py \
./pyportal_startup.bmp \
./pyportal_startup.wav \
./secrets.py \
./skyportal_config.py
- name: Create non-compiled bundle
- name: Build PyPortal bundle base
run: |
mkdir -p ./tmp/assets
cp ./assets/* ./tmp/assets
cp ./tmp/assets/default_map_pyportal.bmp ./tmp/assets/default_map.bmp
rm ./tmp/assets/default_map_*.bmp
mkdir -p ./tmp/lib
cp -r ./lib_by_platform/pyportal/lib/* ./tmp/lib
cp ./pyportal_startup.bmp .
cp ./pyportal_startup.wav .
cp bundle_base.tar pyportal_bundle_base.tar
tar -rvf pyportal_bundle_base.tar -C ./tmp/ .
- name: Create non-compiled PyPortal bundle
run: |
cp pyportal_bundle_base.tar skyportal_bundle_pyportal.tar
tar -rvf skyportal_bundle_pyportal.tar ./skyportal/*
tar -vf skyportal_bundle_pyportal.tar --delete ./skyportal/feather_compat.py
gzip skyportal_bundle_pyportal.tar
- name: Compile skyportal lib for PyPortal
run: |
python ./compile.py pyportal
- name: Create compiled PyPortal bundle
run: |
cp pyportal_bundle_base.tar skyportal_bundle_pyportal_compiled.tar
tar -rvf skyportal_bundle_pyportal_compiled.tar -C ./dist/ .
gzip skyportal_bundle_pyportal_compiled.tar
- name: PyPortal Cleanup
run: |
rm -rf ./tmp
rm -rf ./dist
rm -f pyportal_bundle_base.tar
- name: Build Feather bundle base
run: |
mkdir -p ./tmp/assets
cp ./assets/* ./tmp/assets
cp ./tmp/assets/default_map_featherS3.bmp ./tmp/assets/default_map.bmp
rm ./tmp/assets/default_map_*.bmp
mkdir -p ./tmp/lib
cp -r ./lib_by_platform/featherS3/lib/* ./tmp/lib
cp bundle_base.tar feather_bundle_base.tar
tar -rvf feather_bundle_base.tar -C ./tmp/ .
- name: Create non-compiled FeatherS3 bundle
run: |
cp feather_bundle_base.tar skyportal_bundle_feather.tar
tar -rvf skyportal_bundle_feather.tar ./skyportal/*
tar -vf skyportal_bundle_feather.tar --delete ./skyportal/pyportal_compat.py
gzip skyportal_bundle_feather.tar
- name: Compile skyportal lib for FeatherS3
run: |
cp bundle_base.tar skyportal_bundle.tar
tar -rvf skyportal_bundle.tar ./skyportal/*
gzip skyportal_bundle.tar
python ./compile.py feather
- name: Create compiled bundle
- name: Create compiled FeatherS3 bundle
run: |
cp bundle_base.tar skyportal_bundle_compiled.tar
tar -rvf skyportal_bundle_compiled.tar -C ./dist/ .
gzip skyportal_bundle_compiled.tar
cp feather_bundle_base.tar skyportal_bundle_feather_compiled.tar
tar -rvf skyportal_bundle_feather_compiled.tar -C ./dist/ .
gzip skyportal_bundle_feather_compiled.tar
- name: Upload artifacts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run:
gh release upload ${{ github.event.release.tag_name }} skyportal_bundle.tar.gz skyportal_bundle_compiled.tar.gz
gh release upload ${{ github.event.release.tag_name }} skyportal_bundle_*.tar.gz
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ htmlcov

# CircuitPython
/CircuitPython*

tmp/
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ ci:

repos:
- repo: https://github.com/psf/black
rev: 24.10.0
rev: 25.1.0
hooks:
- id: black
- repo: https://github.com/pycqa/isort
rev: 5.13.2
rev: 6.0.0
hooks:
- id: isort
name: isort
Expand Down Expand Up @@ -35,6 +35,6 @@ repos:
- id: python-check-blanket-type-ignore
- id: python-use-type-annotations
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.6
rev: v0.9.4
hooks:
- id: ruff
Binary file added CAD/Parametric/mounting_plate_featherwing.FCStd
Binary file not shown.
Binary file added CAD/Parametric/mounting_plate_pyportal.FCStd
Binary file not shown.
Binary file added CAD/Parametric/tower_legs.FCStd
Binary file not shown.
6 changes: 5 additions & 1 deletion CAD/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@

Also viewable on [MakerWorld](https://makerworld.com/en/models/410275)

A 3D printable mount for the SkyPortal, compatible with the original PyPortal form factor. The PyPortal is mounted to the mounting plate using M2.5 x 4mm screws (4x), M2.5 x 6mm screws (4x), and M2.5 x 6mm standoffs (4x).
A 3D printable mount for the SkyPortal, with mounting plates compatible with the [Adafruit PyPortal](https://www.adafruit.com/product/4116) and [3.5" Adafruit TFT FeatherWing](https://www.adafruit.com/product/3651).

For mounting:
* PyPortal: M2.5 x 4mm screws (4x), M2.5 x 6mm screws (4x), and M2.5 x 6mm standoffs (4x).
* FeatherWing: M2.5 x 4mm screws (4x), M2.5 x 6mm screws (4x), and M2.5 x 16mm standoffs (4x)

**NOTE:** No tolerance has been built in for fitting of components. The mounting plate and/or base plate channel may need to be toleranced at print time or sanded post-print for fitment prior to assembly.

Expand Down
Binary file added CAD/mounting_plate_featherwing.STL
Binary file not shown.
File renamed without changes.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
# Changelog
Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (`<major>`.`<minor>`.`<patch>`)

## [v2.0.0]
### Added
* #36 Add support for the FeatherS3 + TFT FeatherWing V2 w/TSC2007
* #24 Add map tile generation CLI helper utility, `map_gen`

### Changed
* Bump supported CircuitPython to v9.2.x only
* Bump vendored libraries to v9.2 compatible `*.mpy` files
* #36 (Internal) Refactor hardware interfaces into hardware-specific compatibility layers
* #28 Update vendored `mpy-cross` binaries to CircuitPython v9.2

## [v1.3.0]
### Changed
* #20 Bump supported CircuitPython to v9.x only
Expand Down
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@
[![GitHub License](https://img.shields.io/github/license/sco1/skyportal?color=magenta)](https://github.com/sco1/skyportal/blob/main/LICENSE)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/sco1/skyportal/main.svg)](https://results.pre-commit.ci/latest/github/sco1/skyportal/main)

A PyPortal based flight tracker powered by [Adafruit](https://io.adafruit.com/), [Geoapify](https://www.geoapify.com/), [ADSB.lol](https://adsb.lol), and [The OpenSky Network](https://opensky-network.org/).
A CircuitPython based flight tracker powered by [Adafruit](https://io.adafruit.com/), [Geoapify](https://www.geoapify.com/), [ADSB.lol](https://adsb.lol), and [The OpenSky Network](https://opensky-network.org/).

Heavily inspired by Bob Hammell's PyPortal Flight Tracker ([GH](https://github.com/rhammell/pyportal-flight-tracker), [Tutorial](https://www.hackster.io/rhammell/pyportal-flight-tracker-0be6b0#story)).

Thank you to [markleoart](https://www.fiverr.com/markleoart) for creating the aircraft icon sprite sheets!

![screenshot1](./doc/screenie.bmp "SkyPortal in action") ![screenshot2](./doc/screenie_with_info.bmp "SkyPortal in action, with aircraft popup")

## Supported Hardware Configurations
Compatibilty is guaranteed for the following hardware configurations:
* [Adafruit PyPortal](https://www.adafruit.com/product/4116)
* [FeatherS3](https://www.adafruit.com/product/5399) + [FeatherWing V2 w/TSC2007](https://www.adafruit.com/product/3651)

## Getting Started
Users are assumed have read through [Adafruit's PyPortal learning guide](https://learn.adafruit.com/adafruit-pyportal). CircuitPython v9.0 is currently in use for this repository, no other versions are evaluated & reverse compatibility is not guaranteed.
Users are assumed have read through [Adafruit's PyPortal learning guide](https://learn.adafruit.com/adafruit-pyportal). CircuitPython v9.2 is currently in use for this repository, no other versions are evaluated & reverse compatibility is not guaranteed.

The CircuitPython libraries in `lib` are sourced from the Official and Community bundles, which can be found on the [CircuitPython libraries page](https://learn.adafruit.com/adafruit-pyportal). Compatibility for a given SkyPortal release is only ensured with library files vendored by this repository.

Expand All @@ -24,7 +29,7 @@ To get up and running, copy the following files from the repository to your PyPo

```
assets/
lib/
lib/<your hardware configuration>/lib
skyportal/
boot.py
code.py
Expand All @@ -34,8 +39,12 @@ secrets.py
skyportal_config.py
```

**NOTE:** As of Skyportal v2.0 there are some hardware-specific file configurations that need to be adjusted for proper functionality:
* The sample default map tile provided by the repository is marked with a hardware suffix (screen pixel sizes differ). If using the sample map tile, rename the hardware-appropriate `*.bmp` file to `default_map.bmp` and delete the other tile. This does not have an effect if querying Geoapify for the map tile, though this default map is used as the fallback if this query fails.
* The bundled CircuitPython libraries are separated by hardware type, copy the **nested** `lib` file for your hardware configuration to the root of your device.

#### From GH Release
The Skyportal [Releases page](https://github.com/sco1/skyportal/releases) contains bundled `*.tar.gz` archives, built in CI, that can be downloaded and extracted directly onto the device. Bundles come in two flavors: one pure-python implementation and a compiled version, where the `skyportal` library has been [compiled to `*.mpy`](https://learn.adafruit.com/welcome-to-circuitpython/library-file-types-and-frozen-libraries#dot-mpy-library-files-3117643) and added to `lib/`.
The Skyportal [Releases page](https://github.com/sco1/skyportal/releases) contains bundled `*.tar.gz` archives, built in CI, that can be downloaded and extracted directly onto the device. Bundles are available for each supported hardware configuration and come in two flavors: a pure-python implementation and a compiled version, where the `skyportal` library has been [compiled to `*.mpy`](https://learn.adafruit.com/welcome-to-circuitpython/library-file-types-and-frozen-libraries#dot-mpy-library-files-3117643) and added to `lib/`.

### Configuration
#### Secrets
Expand Down Expand Up @@ -120,3 +129,5 @@ Tapping on an aircraft icon will display state information for the aircraft clos

## Known Limitations
The PyPortal is a highly memory constrained environment, which presents challenges when aiming to create a highly expressive UI. While every attempt is being made to minimize memory usage to keep the Skyportal functioning, the device may occasionally run out of memory. The most likely point for this to happen is when receiving the web request with aircraft state information from your API of choice. Depending on how congested your selected airspace is at query time, there may simply be too much information provided by the API for the device to handle & I've intentionally left the exception unhandled so it will crash the device. Should you find this ocurring often, you may be interested in setting up a proxy server to return only the information needed for the device to function, which can significantly alleviate the amount of RAM needed. See [Proxy API](#proxy-api---proxy) for more information.

Depending on board configuration, the FeatherS3 typically has more RAM avilable to accomodate these web requests, so Skyportal v2.0 expands functionality to serve this board type.
Binary file added assets/default_map_featherS3.bmp
Binary file not shown.
File renamed without changes.
45 changes: 26 additions & 19 deletions code.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import gc
import math
import os
import sys

from adafruit_datetime import datetime, timedelta
from adafruit_pyportal import PyPortal

from skyportal.displaylib import SkyPortalUI
from skyportal.maplib import build_bounding_box
Expand Down Expand Up @@ -45,28 +45,33 @@ def _utc_to_local(utc_timestamp: float, utc_offset: str = "-0000") -> datetime:
os.mkdir("/sd")

# Device Initialization
PYPORTAL = PyPortal() # This also takes care of mounting the SD to /sd
skyportal_ui = SkyPortalUI()

PYPORTAL.network.connect()
print("Wifi connected")

SESSION = PYPORTAL.network._wifi.requests

# The internal PyPortal query to AIO returns as "%Y-%m-%d %H:%M:%S.%L %j %u %z %Z"
# This method sets the internal clock, but we also retain it to transform the API time to local
init_timestamp = PYPORTAL.get_local_time(location=secrets["timezone"])
utc_offset = init_timestamp.split()[4]
# Written verbosely for now, once initial functionality is achieved then we can look at abstracting
# away into the hardware handlers
impl = sys.implementation
device: PyPortal | FeatherS3
if "PyPortal" in impl._machine:
print("Initializing PyPortal")
from skyportal.pyportal_compat import PyPortal

device = PyPortal(tz=secrets["timezone"])
elif "FeatherS3" in impl._machine:
print("Initializing FeatherS3")
from skyportal.feather_compat import FeatherS3

device = FeatherS3(tz=secrets["timezone"])
else:
raise RuntimeError("Unknown machine type: '{impl._machine}'")

grid_bounds = build_bounding_box()
skyportal_ui.post_connect_init(grid_bounds, SESSION)
skyportal_ui = SkyPortalUI(device)
grid_bounds = build_bounding_box(screen_width=device.width, screen_height=device.height)
skyportal_ui.post_connect_init(grid_bounds)

api_handler: APIHandlerBase
if skyportal_config.AIRCRAFT_DATA_SOURCE == "adsblol":
from skyportal.networklib import ADSBLol

api_handler = ADSBLol(
request_session=SESSION,
request_session=device.session,
lat=skyportal_config.MAP_CENTER_LAT,
lon=skyportal_config.MAP_CENTER_LON,
radius=skyportal_config.GRID_WIDTH_MI * 2,
Expand All @@ -75,13 +80,13 @@ def _utc_to_local(utc_timestamp: float, utc_offset: str = "-0000") -> datetime:
elif skyportal_config.AIRCRAFT_DATA_SOURCE == "opensky":
from skyportal.networklib import OpenSky

api_handler = OpenSky(request_session=SESSION, grid_bounds=grid_bounds)
api_handler = OpenSky(request_session=device.session, grid_bounds=grid_bounds)
print("Using OpenSky as aircraft data source")
elif skyportal_config.AIRCRAFT_DATA_SOURCE == "proxy":
from skyportal.networklib import ProxyAPI

api_handler = ProxyAPI(
request_session=SESSION,
request_session=device.session,
lat=skyportal_config.MAP_CENTER_LAT,
lon=skyportal_config.MAP_CENTER_LON,
radius=skyportal_config.GRID_WIDTH_MI * 2,
Expand Down Expand Up @@ -109,7 +114,9 @@ def _utc_to_local(utc_timestamp: float, utc_offset: str = "-0000") -> datetime:
if api_handler.can_draw:
print("Updating aircraft locations")
skyportal_ui.draw_aircraft(api_handler.aircraft)
skyportal_ui.time_label.text = f"{_utc_to_local(api_handler.api_time, utc_offset)}"

local_time_str = _utc_to_local(api_handler.api_time, device.utc_offset)
skyportal_ui.time_label.text = f"{local_time_str}"
else:
print("No aircraft to draw, skipping redraw")

Expand Down
19 changes: 15 additions & 4 deletions compile.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import argparse
import platform
import subprocess
import time
Expand All @@ -7,16 +8,26 @@
DEST_DIR = Path("./dist/lib/skyportal")

COMPILERS = {
"Windows": Path("./mpy-cross/mpy-cross-windows-9.0.5.static.exe"),
"Linux": Path("./mpy-cross/mpy-cross-linux-amd64-9.0.5.static"),
"Darwin": Path("./mpy-cross/mpy-cross-macos-11-9.0.5-arm64"),
"Windows": Path("./mpy-cross/mpy-cross-windows-9.2.2.static.exe"),
"Linux": Path("./mpy-cross/mpy-cross-linux-amd64-9.2.2.static"),
"Darwin": Path("./mpy-cross/mpy-cross-macos-9.2.2-arm64"),
}


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("target", type=str, choices=("pyportal", "feather"))
args = parser.parse_args()

DEST_DIR.mkdir(parents=True, exist_ok=True)

to_compile = list(SOURCE_DIR.glob("*.py"))
# Remove unnecessary compatibility layer
to_compile = set(SOURCE_DIR.glob("*.py"))
if args.target == "pyportal":
to_compile.remove(SOURCE_DIR / "feather_compat.py")
elif args.target == "feather":
to_compile.remove(SOURCE_DIR / "pyportal_compat.py")

print(f"Found {len(to_compile)} *.py files to compile")
for filepath in to_compile:
subprocess.run([COMPILERS[platform.system()], filepath])
Expand Down
Binary file removed lib/adafruit_connection_manager.mpy
Binary file not shown.
Binary file removed lib/adafruit_datetime.mpy
Binary file not shown.
Binary file removed lib/adafruit_display_shapes/arc.mpy
Binary file not shown.
Binary file removed lib/adafruit_display_shapes/multisparkline.mpy
Binary file not shown.
Binary file removed lib/adafruit_display_shapes/polygon.mpy
Binary file not shown.
Binary file removed lib/adafruit_display_text/__init__.mpy
Binary file not shown.
Binary file removed lib/adafruit_display_text/bitmap_label.mpy
Binary file not shown.
Binary file removed lib/adafruit_display_text/scrolling_label.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/__init__.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/bmp/__init__.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/bmp/indexed.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/bmp/truecolor.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/displayio_types.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/gif.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/png.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/pnm/__init__.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/pnm/pbm_ascii.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/pnm/pbm_binary.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/pnm/pgm/__init__.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/pnm/pgm/ascii.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/pnm/pgm/binary.mpy
Binary file not shown.
Binary file removed lib/adafruit_imageload/pnm/ppm_ascii.mpy
Binary file not shown.
Binary file removed lib/adafruit_io/adafruit_io.mpy
Binary file not shown.
Binary file removed lib/adafruit_minimqtt/adafruit_minimqtt.mpy
Binary file not shown.
Binary file removed lib/adafruit_minimqtt/matcher.mpy
Binary file not shown.
Binary file removed lib/adafruit_pyportal/__init__.mpy
Binary file not shown.
Binary file removed lib/adafruit_pyportal/network.mpy
Binary file not shown.
Binary file removed lib/adafruit_pyportal/peripherals.mpy
Binary file not shown.
Binary file removed lib/adafruit_requests.mpy
Binary file not shown.
File renamed without changes.
Binary file not shown.
File renamed without changes.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File renamed without changes.
File renamed without changes.
Binary file not shown.
File renamed without changes.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File renamed without changes.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File renamed without changes.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File renamed without changes.
Binary file not shown.
Binary file not shown.
Binary file added lib_by_platform/featherS3/lib/adafruit_hx8357.mpy
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
File renamed without changes.
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions lib_by_platform/pyportal/lib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Files in this directory are provided by the [CircuitPython library bundles](https://circuitpython.org/libraries)
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added lib_by_platform/pyportal/lib/adafruit_ticks.mpy
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed mpy-cross/mpy-cross-linux-amd64-9.0.5.static
Binary file not shown.
Binary file added mpy-cross/mpy-cross-linux-amd64-9.2.2.static
Binary file not shown.
Binary file removed mpy-cross/mpy-cross-macos-11-9.0.5-arm64
Binary file not shown.
Binary file removed mpy-cross/mpy-cross-macos-11-9.0.5-x64
Binary file not shown.
Binary file added mpy-cross/mpy-cross-macos-9.2.2-arm64
Binary file not shown.
Binary file added mpy-cross/mpy-cross-macos-9.2.2-x64
Binary file not shown.
Binary file removed mpy-cross/mpy-cross-windows-9.0.5.static.exe
Binary file not shown.
Binary file added mpy-cross/mpy-cross-windows-9.2.2.static.exe
Binary file not shown.
Loading

0 comments on commit 5155b33

Please sign in to comment.