diff --git a/build_mp.py b/build_mp.py index b557e4a7..ab79e821 100755 --- a/build_mp.py +++ b/build_mp.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Build PyDevices MicroPython firmware with one command. ./build_mp.py --port esp32 --board ESP32_GENERIC_P4 --variant C6_WIFI \\ diff --git a/docs/conf.py b/docs/conf.py index a043e86d..819bf3ac 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Sphinx configuration for the micropython-pydevices documentation. Everything shared by the PyDevices documentation projects (theme, top bar, diff --git a/modules/all/manifest.py b/modules/all/manifest.py index 737fc0fd..3cb2ecb3 100644 --- a/modules/all/manifest.py +++ b/modules/all/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # Every module beside this one, except those that say they are opt-in: a # module with an OPT_IN file (its text says why) is built only when named. # Otherwise all means all, and a module leaves "all" only by leaving modules/. diff --git a/modules/audiocomponents/manifest.py b/modules/audiocomponents/manifest.py index 122d0c28..def9c054 100644 --- a/modules/audiocomponents/manifest.py +++ b/modules/audiocomponents/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # audiocomponents is the old name for audioinstruments plus audioeffects, # kept so `--modules audiocomponents` still builds both. include("../audioinstruments") diff --git a/modules/audioeffects/manifest.py b/modules/audioeffects/manifest.py index 0a6550b9..3f830b7a 100644 --- a/modules/audioeffects/manifest.py +++ b/modules/audioeffects/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # audioeffects, from omnipython-lib: the effect classes, which the library # builds from the PyDevices/audioeffects repository at the tag its # lib-lock.json pins. They import ulab and audiodsp, so name those too (or diff --git a/modules/audioif/manifest.py b/modules/audioif/manifest.py index 8a7b77a3..6b0ac11c 100644 --- a/modules/audioif/manifest.py +++ b/modules/audioif/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # Freeze manifest for this repo. Nothing Python to freeze here; the line below # names the C module so a build that includes this manifest compiles it # (MicroPython 1.29 c_module()). diff --git a/modules/audioif/tests/busio_probe.py b/modules/audioif/tests/busio_probe.py index 981d1a98..0e141b08 100644 --- a/modules/audioif/tests/busio_probe.py +++ b/modules/audioif/tests/busio_probe.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """`audiobusio.I2SOut` against what CircuitPython documents it to do. Everything here is a CircuitPython behaviour taken off diff --git a/modules/audioif/tests/cp_example_probe.py b/modules/audioif/tests/cp_example_probe.py index a7c6ae86..fb260921 100644 --- a/modules/audioif/tests/cp_example_probe.py +++ b/modules/audioif/tests/cp_example_probe.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """The CircuitPython `audiobusio` docstring example, run unmodified. This is the program in CircuitPython 10.3.0's own diff --git a/modules/audioif/tests/i2sin_probe.py b/modules/audioif/tests/i2sin_probe.py index 0ec53c31..f4153005 100644 --- a/modules/audioif/tests/i2sin_probe.py +++ b/modules/audioif/tests/i2sin_probe.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """`audioi2sin.I2SIn` against what CircuitPython documents it to do. Every leg is a behaviour taken off CircuitPython's diff --git a/modules/audioif/tests/p4_starved_probe.py b/modules/audioif/tests/p4_starved_probe.py index 6d8be7c1..0947c074 100644 --- a/modules/audioif/tests/p4_starved_probe.py +++ b/modules/audioif/tests/p4_starved_probe.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """`I2SOut.starved()` on a board: 0 while nothing starves, and it moves when the pump really falls behind. diff --git a/modules/audioif/tests/s3_drift.py b/modules/audioif/tests/s3_drift.py index 52ac3f31..4305bf85 100644 --- a/modules/audioif/tests/s3_drift.py +++ b/modules/audioif/tests/s3_drift.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """audioif#5: do the T-Embed's two I2S ports drift, over an hour? Forty seconds said no -- `rx - tx` stayed at 0 bytes at a 4 x 128 ring. Two diff --git a/modules/audioif/tests/s3_stall_witness.py b/modules/audioif/tests/s3_stall_witness.py index 1d4a9a86..a5a51f96 100644 --- a/modules/audioif/tests/s3_stall_witness.py +++ b/modules/audioif/tests/s3_stall_witness.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Does a flash erase stall the I2S DMA itself, or only the pump? mpftp put -d COM12 tests/s3_stall_witness.py /lib/s3_stall_witness.py diff --git a/modules/audioif/tests/sink_probe.py b/modules/audioif/tests/sink_probe.py index ac814ea4..e0fa9682 100644 --- a/modules/audioif/tests/sink_probe.py +++ b/modules/audioif/tests/sink_probe.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """The driver's file sink hands over exactly what the engine pulled. tests/sink_probe.py [scratch-dir] [--fault WHICH] diff --git a/modules/audioif/tests/tone_check.py b/modules/audioif/tests/tone_check.py index b565b1f0..33cddf90 100644 --- a/modules/audioif/tests/tone_check.py +++ b/modules/audioif/tests/tone_check.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Is there a tone at `hz` in this recording? Asked through `audiometer`. from tone_check import tone_check diff --git a/modules/audioif/tests/wasapi_ring_probe.py b/modules/audioif/tests/wasapi_ring_probe.py index d20e63b0..40e81a12 100644 --- a/modules/audioif/tests/wasapi_ring_probe.py +++ b/modules/audioif/tests/wasapi_ring_probe.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """A WASAPI microphone feeding an audiopump.Ring on its own thread holds pace. micropython.exe tests/wasapi_ring_probe.py [secs=30] [in=ID] [out=ID] diff --git a/modules/audioinstruments/manifest.py b/modules/audioinstruments/manifest.py index 1a13af2c..1a10e14f 100644 --- a/modules/audioinstruments/manifest.py +++ b/modules/audioinstruments/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # audioinstruments, from omnipython-lib: the rack and its instruments, which # the library builds from the PyDevices/audioinstruments repository at the tag # its lib-lock.json pins. They import ulab and audiodsp, so name those too (or diff --git a/modules/cameraif/manifest.py b/modules/cameraif/manifest.py index 4632af8b..1f1c161d 100644 --- a/modules/cameraif/manifest.py +++ b/modules/cameraif/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # MicroPython manifest for cameraif: deliberately empty. # # cameraif is a native module with no Python half. Its whole surface is the diff --git a/modules/cameraif/tests/hardware/espcamera_controls.py b/modules/cameraif/tests/hardware/espcamera_controls.py index f12cef15..a569f770 100644 --- a/modules/cameraif/tests/hardware/espcamera_controls.py +++ b/modules/cameraif/tests/hardware/espcamera_controls.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Every espcamera control name on a real camera, checked against its driver. Reads each of espcamera's control names, and for the ones the sensor offers, diff --git a/modules/cameraif/tests/hardware/judge_espcamera_controls.py b/modules/cameraif/tests/hardware/judge_espcamera_controls.py index fa08d17d..e7d3fd77 100644 --- a/modules/cameraif/tests/hardware/judge_espcamera_controls.py +++ b/modules/cameraif/tests/hardware/judge_espcamera_controls.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Judge espcamera_controls.py's output against the OV5647 driver's own source. The expectation comes from esp_cam_sensor's ov5647.c (which parameter ids its diff --git a/modules/castif/manifest.py b/modules/castif/manifest.py index 49599da8..f5106ae9 100644 --- a/modules/castif/manifest.py +++ b/modules/castif/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # castif: C only, ESP32-P4 only. The cast's RTP, pacing and audio; the # encoding is h264enc's and the MPEG-TS tsmux's (name all three modules). c_module(".") diff --git a/modules/castif/tests/check_castif_hls.py b/modules/castif/tests/check_castif_hls.py index 917dc6cd..bcaff6ad 100644 --- a/modules/castif/tests/check_castif_hls.py +++ b/modules/castif/tests/check_castif_hls.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """ffprobe decodes what test_castif_hls served: each kept segment alone and the playlist, and /stats parses as JSON. A planted fault (a segment cut in half) must fail. diff --git a/modules/displayif/manifest.py b/modules/displayif/manifest.py index 8a7b77a3..6b0ac11c 100644 --- a/modules/displayif/manifest.py +++ b/modules/displayif/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # Freeze manifest for this repo. Nothing Python to freeze here; the line below # names the C module so a build that includes this manifest compiles it # (MicroPython 1.29 c_module()). diff --git a/modules/displayif/src/ports/rp2/picodvi/libdvi/tmds_table_gen.py b/modules/displayif/src/ports/rp2/picodvi/libdvi/tmds_table_gen.py index 0ad554ea..aa75af8c 100755 --- a/modules/displayif/src/ports/rp2/picodvi/libdvi/tmds_table_gen.py +++ b/modules/displayif/src/ports/rp2/picodvi/libdvi/tmds_table_gen.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT # The key fact is that, if x is even, and the encoder currently has a running # imbalance of 0, encoding x followed by x + 1 produces a symbol pair with a diff --git a/modules/displayif/tests/test_lifecycle_api.py b/modules/displayif/tests/test_lifecycle_api.py index a07c3e84..3804cfd3 100644 --- a/modules/displayif/tests/test_lifecycle_api.py +++ b/modules/displayif/tests/test_lifecycle_api.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Verify displayif modules expose idempotent lifecycle methods on their types. This test runs without display hardware: it imports modules that exist on the diff --git a/modules/displayif/tools/check_qstr_reachability.py b/modules/displayif/tools/check_qstr_reachability.py index 4d370b3f..9e4a086d 100644 --- a/modules/displayif/tools/check_qstr_reachability.py +++ b/modules/displayif/tools/check_qstr_reachability.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Refuse an MP_QSTR_ name that only exists when a usermod's INTERFACE define is set. The rule this enforces, and why, is docs/qstrs-and-usermod-defines.md. In one @@ -20,7 +24,7 @@ A name is not reported when it *also* appears unguarded **in the same file** -- the QSTR pass collects it from there and the guarded reference rides along -- or -when it is in :data:`CORE_POOL` below. +when it is in `CORE_POOL` below. Same file, not same repo, and the difference is the whole check. Every name in ``src/ports/samd/mod_i80bus.c`` is also referenced by the esp32 backend and by diff --git a/modules/displayif/tools/test_dotclockframebuffer_smoke.py b/modules/displayif/tools/test_dotclockframebuffer_smoke.py index 14953b6c..9c0c1299 100644 --- a/modules/displayif/tools/test_dotclockframebuffer_smoke.py +++ b/modules/displayif/tools/test_dotclockframebuffer_smoke.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Smoke test for dotclockframebuffer.DotClockFramebuffer import and buffer protocol (esp32).""" import sys diff --git a/modules/displayif/tools/test_i2cbus_smoke.py b/modules/displayif/tools/test_i2cbus_smoke.py index 19c9ca02..dbb8dac7 100644 --- a/modules/displayif/tools/test_i2cbus_smoke.py +++ b/modules/displayif/tools/test_i2cbus_smoke.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Smoke test for i2cbus import (MCU ports with machine.I2C).""" import sys diff --git a/modules/displayif/tools/test_i80bus_smoke.py b/modules/displayif/tools/test_i80bus_smoke.py index 78ea85ec..57ac0d91 100644 --- a/modules/displayif/tools/test_i80bus_smoke.py +++ b/modules/displayif/tools/test_i80bus_smoke.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Smoke test for i80bus import.""" import sys diff --git a/modules/displayif/tools/test_mimxrt_dotclockframebuffer_smoke.py b/modules/displayif/tools/test_mimxrt_dotclockframebuffer_smoke.py index 25bb97df..a8b5c93e 100644 --- a/modules/displayif/tools/test_mimxrt_dotclockframebuffer_smoke.py +++ b/modules/displayif/tools/test_mimxrt_dotclockframebuffer_smoke.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Smoke test for dotclockframebuffer.DotClockFramebuffer (mimxrt eLCDIF). Small 4x4 buffer on MIMXRT1062 (Teensy 4.x / MIMXRT1060-EVK). Full RK043 panel diff --git a/modules/displayif/tools/test_mimxrt_mipidsi_smoke.py b/modules/displayif/tools/test_mimxrt_mipidsi_smoke.py index 3f96d392..aab06bcf 100644 --- a/modules/displayif/tools/test_mimxrt_mipidsi_smoke.py +++ b/modules/displayif/tools/test_mimxrt_mipidsi_smoke.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Smoke test for mipidsi import (MIMXRT1176 with MIPI DSI only). Full panel bring-up requires MIMXRT1170-EVK + Waveshare 5\" DSI on J84. diff --git a/modules/displayif/tools/test_mipidsi_smoke.py b/modules/displayif/tools/test_mipidsi_smoke.py index 45308d35..f595c0b8 100644 --- a/modules/displayif/tools/test_mipidsi_smoke.py +++ b/modules/displayif/tools/test_mipidsi_smoke.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Smoke test for mipidsi import (ESP32-P4 with MIPI DSI only). Full panel bring-up requires the Waveshare ESP32-P4-WIFI6-Touch-LCD-4B hardware. diff --git a/modules/displayif/tools/test_picodvi_smoke.py b/modules/displayif/tools/test_picodvi_smoke.py index a71fc2ad..43558780 100644 --- a/modules/displayif/tools/test_picodvi_smoke.py +++ b/modules/displayif/tools/test_picodvi_smoke.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Smoke test for picodvi import and Framebuffer (rp2 PIO / HSTX). Uses the smallest supported mode (320x240 @ 4bpp on RP2040). Full DVI output diff --git a/modules/displayif/tools/test_rgbmatrix_smoke.py b/modules/displayif/tools/test_rgbmatrix_smoke.py index 22b62de1..36f08bcf 100644 --- a/modules/displayif/tools/test_rgbmatrix_smoke.py +++ b/modules/displayif/tools/test_rgbmatrix_smoke.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Smoke test for rgbmatrix import, tile height, and buffer protocol.""" import sys diff --git a/modules/displayif/tools/test_spi_smoke.py b/modules/displayif/tools/test_spi_smoke.py index d0ceb76d..1ad50626 100644 --- a/modules/displayif/tools/test_spi_smoke.py +++ b/modules/displayif/tools/test_spi_smoke.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Smoke test for native spibus (displayif src/ports/common/spi).""" import sys diff --git a/modules/h264enc/manifest.py b/modules/h264enc/manifest.py index 48be34e4..a0afe799 100644 --- a/modules/h264enc/manifest.py +++ b/modules/h264enc/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # h264enc: RGB565 frames to H.264 on the ESP32-P4's hardware encoder (the PPA # converts, esp_h264 encodes). C only, ESP32-P4 only; castif encodes through # its C API. Moved out of castif (media modules roadmap, Phase 3). diff --git a/modules/h264enc/tests/check_h264_ffmpeg.py b/modules/h264enc/tests/check_h264_ffmpeg.py index 8f6152cb..f898ff48 100644 --- a/modules/h264enc/tests/check_h264_ffmpeg.py +++ b/modules/h264enc/tests/check_h264_ffmpeg.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """ffmpeg on the PC decodes what test_h264enc.py encoded on the board. Thresholds fixed before the first run (2026-10-06): ffmpeg decodes exactly N diff --git a/modules/h264enc/tests/encode_h264_ffmpeg.py b/modules/h264enc/tests/encode_h264_ffmpeg.py index 8b4050d0..3b7abfec 100644 --- a/modules/h264enc/tests/encode_h264_ffmpeg.py +++ b/modules/h264enc/tests/encode_h264_ffmpeg.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """The board half's stand-in on a PC: ffmpeg's x264 encodes h264_frames.py's frames with the settings hardware/test_h264enc.py gives h264enc (720x720, 30 fps, 3 Mbit/s, a keyframe every 30), so CI can run check_h264_ffmpeg.py diff --git a/modules/h264enc/tests/h264_frames.py b/modules/h264enc/tests/h264_frames.py index 5479d7ec..2fbdd320 100644 --- a/modules/h264enc/tests/h264_frames.py +++ b/modules/h264enc/tests/h264_frames.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The test's source frames, computed the same way on a board (MicroPython) # and on the PC (CPython, check_h264_ffmpeg.py): a fixed RGB565 gradient with # a 96x96 box crossing it, 8 px a frame, in native byte order. diff --git a/modules/h264enc/tests/hardware/test_h264enc.py b/modules/h264enc/tests/hardware/test_h264enc.py index a21fd2c8..d11af3bb 100644 --- a/modules/h264enc/tests/hardware/test_h264enc.py +++ b/modules/h264enc/tests/hardware/test_h264enc.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """h264enc on the ESP32-P4 -- the media Phase 3 encode gate, board half. Encodes N frames from h264_frames.py (no camera, no cast) at 720x720, 30 fps, diff --git a/modules/jpegio/manifest.py b/modules/jpegio/manifest.py index 4036f4ac..bd0ceb5c 100644 --- a/modules/jpegio/manifest.py +++ b/modules/jpegio/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # jpegio: JPEG decoding into RGB565 (CircuitPython's jpegio API, on ChaN's # TJpgDec), and LVGL's JPEG decoder when LVGL (omnipython-lvgl) is in the build. # C only; every port. Moved here from displayif (media modules roadmap, diff --git a/modules/jpegio/tests/check_encode_pil.py b/modules/jpegio/tests/check_encode_pil.py index e45a133e..34330306 100644 --- a/modules/jpegio/tests/check_encode_pil.py +++ b/modules/jpegio/tests/check_encode_pil.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Pillow, a decoder that is not ours, must read back what we encoded. Every JPEG test_jpegio_encode.py wrote must open in Pillow at its size and diff --git a/modules/jpegio/tests/hardware/board_lvgl_glass.py b/modules/jpegio/tests/hardware/board_lvgl_glass.py index 45842993..7593cdb6 100644 --- a/modules/jpegio/tests/hardware/board_lvgl_glass.py +++ b/modules/jpegio/tests/hardware/board_lvgl_glass.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # On a board with a display, LVGL and jpegio: draw a corpus JPEG with # lv.image and compare what lands in the panel's framebuffer, pixel for pixel, # with jpegio decoding the same file into a buffer. The framebuffer is what diff --git a/modules/jpegio/tests/jpegwalk.py b/modules/jpegio/tests/jpegwalk.py index 811b6a3d..bd777707 100644 --- a/modules/jpegio/tests/jpegwalk.py +++ b/modules/jpegio/tests/jpegwalk.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """jpegwalk -- a tiny JPEG marker walker. Plain Python with no third-party imports, written so it also runs under diff --git a/modules/jpegio/tests/make_corpus.py b/modules/jpegio/tests/make_corpus.py index 4bc824f8..e05fc4b3 100644 --- a/modules/jpegio/tests/make_corpus.py +++ b/modules/jpegio/tests/make_corpus.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Build the jpegio test corpus in frames/ and write frames/README.md. Run: python3 modules/jpegio/tests/make_corpus.py (needs Pillow; 12.3 used) diff --git a/modules/jpegio/tests/reference.py b/modules/jpegio/tests/reference.py index c08431cb..e7bcdbb8 100644 --- a/modules/jpegio/tests/reference.py +++ b/modules/jpegio/tests/reference.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Pillow fidelity reference for the jpegio corpus -> frames/reference.json. Run: python3 modules/jpegio/tests/reference.py (needs Pillow; 12.3 used) diff --git a/modules/jpegio/tests/test_jpegio.py b/modules/jpegio/tests/test_jpegio.py index 99d3a22d..d1d6c5a3 100644 --- a/modules/jpegio/tests/test_jpegio.py +++ b/modules/jpegio/tests/test_jpegio.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """jpegio -- unix MicroPython tests against the corpus and the Pillow reference. The Phase 1 gate of the org's docs/jpegio-vision.md, checked mechanically: diff --git a/modules/jpegio/tests/test_jpegio_encode.py b/modules/jpegio/tests/test_jpegio_encode.py index 3f82892f..6e6c3c65 100644 --- a/modules/jpegio/tests/test_jpegio_encode.py +++ b/modules/jpegio/tests/test_jpegio_encode.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """jpegio.JpegEncoder (and the P4's hardware decode) -- the media Phase 2 gate. Thresholds were fixed before the first run, on the corpus's real camera frame diff --git a/modules/jpegio/tests/test_jpegio_lvgl.py b/modules/jpegio/tests/test_jpegio_lvgl.py index 7b525955..a3199097 100644 --- a/modules/jpegio/tests/test_jpegio_lvgl.py +++ b/modules/jpegio/tests/test_jpegio_lvgl.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """jpegio -- its LVGL image decoder, on unix MicroPython built beside lvgl (omnipython-lvgl). The LVGL half of the Phase 2 gate in the org's docs/jpegio-vision.md, checked diff --git a/modules/jpegio/tools/make_jpegenc.py b/modules/jpegio/tools/make_jpegenc.py index 19ada61d..8436969f 100644 --- a/modules/jpegio/tools/make_jpegenc.py +++ b/modules/jpegio/tools/make_jpegenc.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + import sys S = sys.argv[1] src = open(S + "/stb_image_write.h").read() diff --git a/modules/library.py b/modules/library.py index 83b76f3d..279afb3d 100644 --- a/modules/library.py +++ b/modules/library.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # Registers omnipython-lib, our library of Python-only packages, so a manifest # can require("pydevices", library="omnipython-lib"). build_mp.py assembles the # library tree (tools/libbuild.py build --tree-only in the pinned repository) diff --git a/modules/manifest.py b/modules/manifest.py index 543240ae..351c1d5e 100644 --- a/modules/manifest.py +++ b/modules/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The manifest a build_mp.py build freezes: upstream's own content for the # port, then the modules you named. This is the user manifest MicroPython's # manifest reference describes -- the port's base, then your additions -- and diff --git a/modules/mdns/manifest.py b/modules/mdns/manifest.py index a3f4d851..0744fdba 100644 --- a/modules/mdns/manifest.py +++ b/modules/mdns/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # mdns: CircuitPython's mdns API (find and advertise services on the local # network). C only; esp32, rp2 with a network, unix and windows. On CPython, # pydevices-desktop's mdns.py gives the same API over python-zeroconf. diff --git a/modules/mdns/tests/check_mdns_zeroconf.py b/modules/mdns/tests/check_mdns_zeroconf.py index 87ca56e1..60327bf6 100644 --- a/modules/mdns/tests/check_mdns_zeroconf.py +++ b/modules/mdns/tests/check_mdns_zeroconf.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """mdns against another implementation: python-zeroconf, in another process. python3 check_mdns_zeroconf.py ./builds/unix/standard/micropython diff --git a/modules/mdns/tests/test_mdns.py b/modules/mdns/tests/test_mdns.py index 7a361969..88075918 100644 --- a/modules/mdns/tests/test_mdns.py +++ b/modules/mdns/tests/test_mdns.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # mdns on a desktop MicroPython (unix or windows): the API, its errors, and a # service this process advertises, found by this process. # diff --git a/modules/micropython-lib/manifest.py b/modules/micropython-lib/manifest.py index 1088607c..128d17ac 100644 --- a/modules/micropython-lib/manifest.py +++ b/modules/micropython-lib/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The packages from micropython-lib that PyDevices' APIs lean on, frozen in so # an OmniPython firmware never asks anyone to mip.install them first (on stock # MicroPython you install them from micropython-lib's index, then ours): diff --git a/modules/palettes/manifest.py b/modules/palettes/manifest.py index db84c5fe..1294a28f 100644 --- a/modules/palettes/manifest.py +++ b/modules/palettes/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # palettes, from omnipython-lib. Frozen at opt=3, as before. include("../library.py") require("palettes", library="omnipython-lib", opt=3) diff --git a/modules/pdwidgets/manifest.py b/modules/pdwidgets/manifest.py index 39c73e28..45e7d3de 100644 --- a/modules/pdwidgets/manifest.py +++ b/modules/pdwidgets/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # pdwidgets, from omnipython-lib. Frozen at opt=3, as before. include("../library.py") require("pdwidgets", library="omnipython-lib", opt=3) diff --git a/modules/picotts/manifest.py b/modules/picotts/manifest.py index 5e0a8516..ab219aa5 100644 --- a/modules/picotts/manifest.py +++ b/modules/picotts/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # picotts: text to speech on the SVOX Pico engine, the API of Adafruit's # adafruit_picotts. The engine is C (_picotts); the TTS class is frozen Python. # Needs PSRAM on a microcontroller: about 2.5 MB for the engine and voice. diff --git a/modules/picotts/py/picotts.py b/modules/picotts/py/picotts.py index 977664f2..9b26a88c 100644 --- a/modules/picotts/py/picotts.py +++ b/modules/picotts/py/picotts.py @@ -156,10 +156,11 @@ def render(self, buffer): class TTS: """Speak text through an audio output. - :param audio: An audio output object with ``play()``, ``stop()`` and ``playing``, such as - `audiobusio.I2SOut`, `audioio.AudioOut` or `audiopwmio.PWMAudioOut`. The library - creates its own `audiomixer.Mixer` on it. Or an `audiomixer.MixerVoice` from the - caller's mixer, whose sample rate must match `sample_rate`. + Args: + audio: An audio output object with ``play()``, ``stop()`` and ``playing``, such as + `audiobusio.I2SOut`, `audioio.AudioOut` or `audiopwmio.PWMAudioOut`. The library + creates its own `audiomixer.Mixer` on it. Or an `audiomixer.MixerVoice` from the + caller's mixer, whose sample rate must match `sample_rate`. """ def __init__(self, audio, *, voice_dir=None) -> None: @@ -273,10 +274,11 @@ def voices(self) -> tuple: def say(self, text: str, *, wait: bool = True, interrupt: bool = False) -> None: """Speak ``text``. If speech is already playing, ``text`` is queued after it. - :param str text: The text to speak. - :param bool wait: If True, return when all queued speech ends. If False, return - right away; call `update` in the main loop to keep speech going. - :param bool interrupt: If True, stop current speech and clear the queue first. + Args: + text (str): The text to speak. + wait (bool): If True, return when all queued speech ends. If False, return + right away; call `update` in the main loop to keep speech going. + interrupt (bool): If True, stop current speech and clear the queue first. """ if interrupt: self.stop() diff --git a/modules/picotts/tests/test_picotts.py b/modules/picotts/tests/test_picotts.py index 70af1d9b..c41c3325 100644 --- a/modules/picotts/tests/test_picotts.py +++ b/modules/picotts/tests/test_picotts.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """picotts on the unix port: the engine renders speech, and the API around it. Run with the unix MicroPython built with --modules picotts, and the folder diff --git a/modules/pngio/manifest.py b/modules/pngio/manifest.py index 49aa0f9a..a0d802bf 100644 --- a/modules/pngio/manifest.py +++ b/modules/pngio/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # pngio: PNG encoding (real deflate) and decoding, RGB565 in and out. C only; # every port with the deflate module (decode uses its uzlib). On CPython, # pydevices-desktop's pngio.py gives the same API over Pillow. diff --git a/modules/pngio/tests/check_pngio_pillow.py b/modules/pngio/tests/check_pngio_pillow.py index 9bf1a622..2962a122 100644 --- a/modules/pngio/tests/check_pngio_pillow.py +++ b/modules/pngio/tests/check_pngio_pillow.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """pngio against Pillow, on the PC, both ways. python check_pngio_pillow.py MICROPYTHON DIR diff --git a/modules/pngio/tests/test_pngio.py b/modules/pngio/tests/test_pngio.py index d8ca4679..be6542b7 100644 --- a/modules/pngio/tests/test_pngio.py +++ b/modules/pngio/tests/test_pngio.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """pngio on MicroPython: round trips, sizes and times. Runs on unix and on boards. micropython test_pngio.py [--out DIR] diff --git a/modules/ppa/manifest.py b/modules/ppa/manifest.py index ad8f51aa..aa4aa391 100644 --- a/modules/ppa/manifest.py +++ b/modules/ppa/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # ppa: scale, rotate, mirror, colour-convert, fill and blend on pixel buffers; # the ESP32-P4's Pixel Processing Accelerator, with portable C for scale, # rotate, mirror and colour convert everywhere (media modules roadmap, Phase 5). diff --git a/modules/ppa/tests/test_ppa.py b/modules/ppa/tests/test_ppa.py index e1c0e334..9b2cf163 100644 --- a/modules/ppa/tests/test_ppa.py +++ b/modules/ppa/tests/test_ppa.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """ppa -- the media Phase 5 gate. Thresholds fixed before the first run. On every port (the software path): diff --git a/modules/pydevices/manifest.py b/modules/pydevices/manifest.py index 5f527318..deab2404 100644 --- a/modules/pydevices/manifest.py +++ b/modules/pydevices/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # PyDevices' own Python, from omnipython-lib: what lib/ holds, which is # `pydevices` and `bledev` as the library splits them, plus the host-only # parts of audiodev, bledev, displaydev and multimer that mip ships in diff --git a/modules/sayso/manifest.py b/modules/sayso/manifest.py index f9a2c7b4..65f7ca7a 100644 --- a/modules/sayso/manifest.py +++ b/modules/sayso/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # sayso, from omnipython-lib: the Spotify controller. Desktop and web builds # only (unix, windows, webassembly): a board build that names it, or all, # freezes nothing. Frozen at opt=3. diff --git a/modules/tflite/manifest.py b/modules/tflite/manifest.py index e3ce95a0..61cd0c32 100644 --- a/modules/tflite/manifest.py +++ b/modules/tflite/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # tflite: TensorFlow Lite Micro inference, esp-vision's module compiled as it # is (modules/.esp-vision). C only; ESP32-P4 and ESP32-S3. # diff --git a/modules/tsmux/manifest.py b/modules/tsmux/manifest.py index b3782f60..943645f6 100644 --- a/modules/tsmux/manifest.py +++ b/modules/tsmux/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # tsmux: MPEG-TS from H.264 access units (and castif's LPCM track), and HLS # segments with their playlist. C only, every port; castif muxes through its # C core. Moved out of castif (media modules roadmap, Phase 4). diff --git a/modules/tsmux/tests/check_tsmux_ffmpeg.py b/modules/tsmux/tests/check_tsmux_ffmpeg.py index ad8e3ed4..7d6e7a2a 100644 --- a/modules/tsmux/tests/check_tsmux_ffmpeg.py +++ b/modules/tsmux/tests/check_tsmux_ffmpeg.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """ffmpeg decodes what test_tsmux.py muxed: the stream, each segment alone, and the playlist. A planted fault (the stream with every sync byte zeroed) must fail. diff --git a/modules/tsmux/tests/extract_castif_ref.py b/modules/tsmux/tests/extract_castif_ref.py index 7872213a..9615b28a 100644 --- a/modules/tsmux/tests/extract_castif_ref.py +++ b/modules/tsmux/tests/extract_castif_ref.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Regenerate castif_ref.inc: castif's muxer functions, verbatim from git. python extract_castif_ref.py [COMMIT] (default ccccb28, the last castif diff --git a/modules/tsmux/tests/test_tsmux.py b/modules/tsmux/tests/test_tsmux.py index 83cfccc1..5016b4e6 100644 --- a/modules/tsmux/tests/test_tsmux.py +++ b/modules/tsmux/tests/test_tsmux.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """tsmux on unix MicroPython -- the media Phase 4 portable half. Muxes canned_160x96.h264 (90 frames, a keyframe every 30, from ffmpeg) into diff --git a/modules/usbhost/manifest.py b/modules/usbhost/manifest.py index ecd100ac..844df8f8 100644 --- a/modules/usbhost/manifest.py +++ b/modules/usbhost/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # MicroPython manifest for usbhost. # # usbhost's native half, the `_usbhost` module built from ``src/``: the USB host diff --git a/modules/usbhost/tests/hardware/soft_reset_check.py b/modules/usbhost/tests/hardware/soft_reset_check.py index 26554f1e..ecbf2bb9 100644 --- a/modules/usbhost/tests/hardware/soft_reset_check.py +++ b/modules/usbhost/tests/hardware/soft_reset_check.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Soft reset check: usbhost shuts its hardware down on a soft reset. Run on the PC, with CPython and ``mpftp`` on the PATH (or named by ``MPFTP``), diff --git a/modules/usbhost/tests/hardware/uac_duplex_loopback.py b/modules/usbhost/tests/hardware/uac_duplex_loopback.py index b98ed29b..51db5cbc 100644 --- a/modules/usbhost/tests/hardware/uac_duplex_loopback.py +++ b/modules/usbhost/tests/hardware/uac_duplex_loopback.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """UAC host duplex check: play to a USB sound card and record from it at once. Run on a board that hosts a USB audio device whose output is looped back into diff --git a/modules/usbhost/tests/hardware/uac_host_ring_check.py b/modules/usbhost/tests/hardware/uac_host_ring_check.py index 1b8ae074..2911b92e 100644 --- a/modules/usbhost/tests/hardware/uac_host_ring_check.py +++ b/modules/usbhost/tests/hardware/uac_host_ring_check.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """UAC host ring check (usbif#36). Run on the HOST board. The host board plays to a hosted USB speaker (a P4 running diff --git a/modules/usbhost/tests/hardware/uac_play_tone.py b/modules/usbhost/tests/hardware/uac_play_tone.py index 92acc860..5e42cc91 100644 --- a/modules/usbhost/tests/hardware/uac_play_tone.py +++ b/modules/usbhost/tests/hardware/uac_play_tone.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Sound card stream check, host half (usbif#37). Run with Windows Python. Plays a 440 Hz sine to "Speakers (Espressif Device)" through WASAPI, then diff --git a/modules/usbhost/tools/host/audio_check.py b/modules/usbhost/tools/host/audio_check.py index 3770e4a9..a867c5ec 100644 --- a/modules/usbhost/tools/host/audio_check.py +++ b/modules/usbhost/tools/host/audio_check.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # usb.host.audio on usb.core: play a tone into the hosted speaker. import math import time diff --git a/modules/usbhost/tools/host/cdc_check.py b/modules/usbhost/tools/host/cdc_check.py index 5ef4703c..8289f056 100644 --- a/modules/usbhost/tools/host/cdc_check.py +++ b/modules/usbhost/tools/host/cdc_check.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # usb.host.cdc on usb.core: type a line into a hosted MicroPython board's REPL # over its USB serial port and read the answer back. import time diff --git a/modules/usbhost/tools/host/core_probe.py b/modules/usbhost/tools/host/core_probe.py index f435f56c..7969e407 100644 --- a/modules/usbhost/tools/host/core_probe.py +++ b/modules/usbhost/tools/host/core_probe.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # Board half of the usb.core check: list what's plugged into the host port, # then talk to a flash drive with nothing but usb.core's bulk transfers # (SCSI INQUIRY and READ CAPACITY over Bulk-Only Transport), and to a MIDI diff --git a/modules/usbhost/tools/host/kbd_device.py b/modules/usbhost/tools/host/kbd_device.py index f81bf9ca..67312b10 100644 --- a/modules/usbhost/tools/host/kbd_device.py +++ b/modules/usbhost/tools/host/kbd_device.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The DEV-KIT as a USB keyboard on its device port (usb_hid on # machine.USBDevice, typed with adafruit_hid), for a host board to read. import time diff --git a/modules/usbhost/tools/host/kbd_host.py b/modules/usbhost/tools/host/kbd_host.py index 5865ab91..9521d155 100644 --- a/modules/usbhost/tools/host/kbd_host.py +++ b/modules/usbhost/tools/host/kbd_host.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # Read a hosted keyboard's key events through usb.host.hid for a while. import time diff --git a/modules/usbhost/tools/host/msc_mount_check.py b/modules/usbhost/tools/host/msc_mount_check.py index 8bef2538..5f3792ba 100644 --- a/modules/usbhost/tools/host/msc_mount_check.py +++ b/modules/usbhost/tools/host/msc_mount_check.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # Mount the flash drive on the host port through usb.host.msc, list it, then # write a small file, read it back, and remove it. import os diff --git a/modules/usbhost/tools/host/s3_uvc_grab.py b/modules/usbhost/tools/host/s3_uvc_grab.py index aeab178e..c9e37c25 100644 --- a/modules/usbhost/tools/host/s3_uvc_grab.py +++ b/modules/usbhost/tools/host/s3_uvc_grab.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The S3 hosts a UVC camera through usb.host.video, streams for a while, # and saves the last whole frame to /frame.bin. import time diff --git a/modules/usbhost/tools/host/video_check.py b/modules/usbhost/tools/host/video_check.py index 4d7d9a3b..433129a0 100644 --- a/modules/usbhost/tools/host/video_check.py +++ b/modules/usbhost/tools/host/video_check.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # usb.host.video on usb.core: open the hosted camera, stream, decode a frame. import time diff --git a/modules/usbhost/tools/matrix/cdc_echo.py b/modules/usbhost/tools/matrix/cdc_echo.py index 63c5b848..09c85803 100644 --- a/modules/usbhost/tools/matrix/cdc_echo.py +++ b/modules/usbhost/tools/matrix/cdc_echo.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Echo a pattern through a board's extra USB serial port (Windows Python). python cdc_echo.py SERIAL [BYTES] diff --git a/modules/usbhost/tools/matrix/desc_check.py b/modules/usbhost/tools/matrix/desc_check.py index a809a4bd..d68e5578 100644 --- a/modules/usbhost/tools/matrix/desc_check.py +++ b/modules/usbhost/tools/matrix/desc_check.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Structural checks of a USB configuration descriptor, as a host receives it. python3 desc_check.py HEX SPEED IN_MAX # HEX: the configuration bytes diff --git a/modules/usbhost/tools/matrix/host_board.py b/modules/usbhost/tools/matrix/host_board.py index fac87824..f6a60d02 100644 --- a/modules/usbhost/tools/matrix/host_board.py +++ b/modules/usbhost/tools/matrix/host_board.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The board half of the proof matrix's host leg (tools/matrix/run_host.py). # # Runs on the board whose native port is the USB host, with usbhost's check diff --git a/modules/usbhost/tools/matrix/matrix_board.py b/modules/usbhost/tools/matrix/matrix_board.py index adea5c88..90453a7b 100644 --- a/modules/usbhost/tools/matrix/matrix_board.py +++ b/modules/usbhost/tools/matrix/matrix_board.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The board half of the device-class proof matrix (tools/matrix/run_matrix.py). # # setup(names) brings up any combination of "cdc" (an extra serial port), diff --git a/modules/usbhost/tools/matrix/rawinput_count.py b/modules/usbhost/tools/matrix/rawinput_count.py index 1e01b0a0..eabe5ffb 100644 --- a/modules/usbhost/tools/matrix/rawinput_count.py +++ b/modules/usbhost/tools/matrix/rawinput_count.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Count raw mouse and keyboard reports from one USB device on Windows. python rawinput_count.py VID_303A SECONDS diff --git a/modules/usbhost/tools/matrix/run_host.py b/modules/usbhost/tools/matrix/run_host.py index c5710914..556723f3 100644 --- a/modules/usbhost/tools/matrix/run_host.py +++ b/modules/usbhost/tools/matrix/run_host.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """The proof matrix's host leg: a board's native port as USB host, checked against what's plugged into it. Runs in WSL; drives the host board (and a peer board, if one is given) over ``mpftp hold``. One command, one verdict: diff --git a/modules/usbhost/tools/matrix/run_matrix.py b/modules/usbhost/tools/matrix/run_matrix.py index 06df2851..cdc894fe 100644 --- a/modules/usbhost/tools/matrix/run_matrix.py +++ b/modules/usbhost/tools/matrix/run_matrix.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """The device-class proof matrix: every combination enumerates on Windows and moves data. Runs in WSL; drives the board over WebREPL with ``mpftp hold``. diff --git a/modules/usbhost/tools/matrix/usb_desc.py b/modules/usbhost/tools/matrix/usb_desc.py index e7b207f2..a07e15b3 100644 --- a/modules/usbhost/tools/matrix/usb_desc.py +++ b/modules/usbhost/tools/matrix/usb_desc.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """What Windows was told: a USB device's speed and its endpoints, from the hub. python usb_desc.py VID [SERIAL] e.g. python usb_desc.py 303A E8F60AE0F070 diff --git a/modules/usbhost/tools/stream/camera_board.py b/modules/usbhost/tools/stream/camera_board.py index 9165054f..dd41066a 100644 --- a/modules/usbhost/tools/stream/camera_board.py +++ b/modules/usbhost/tools/stream/camera_board.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # Board half of the webcam stream check: bring up usb-device-video's camera # beside the console and keep its ring fed with colour bars (YUY2), so a # computer that opens the camera sees eight vertical bars. diff --git a/modules/usbhost/tools/stream/grab_frame.py b/modules/usbhost/tools/stream/grab_frame.py index 48660e5f..a56933c0 100644 --- a/modules/usbhost/tools/stream/grab_frame.py +++ b/modules/usbhost/tools/stream/grab_frame.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Grab a frame from a named webcam and check it shows the colour bars (Windows Python: ffmpeg's dshow, numpy, Pillow). diff --git a/modules/usbhost/tools/stream/play_tone.py b/modules/usbhost/tools/stream/play_tone.py index 66129aa3..0db01966 100644 --- a/modules/usbhost/tools/stream/play_tone.py +++ b/modules/usbhost/tools/stream/play_tone.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Play a tone into a named output device (Windows Python, sounddevice). python play_tone.py NAME SECONDS [HZ] [LEVEL] [--beeps] diff --git a/modules/usbhost/tools/stream/pump_board.py b/modules/usbhost/tools/stream/pump_board.py index 79c5cd4b..3d6e023e 100644 --- a/modules/usbhost/tools/stream/pump_board.py +++ b/modules/usbhost/tools/stream/pump_board.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # Board half of the sound card through audiodsp's pump: usb-device-audio's # speaker writes into an audiopump.Ring from the USB interrupt # (Ring.from_usb), and audiodsp's pump plays that ring on the board's I2S diff --git a/modules/usbhost/tools/stream/speaker_board.py b/modules/usbhost/tools/stream/speaker_board.py index ee4ebf84..885b96f3 100644 --- a/modules/usbhost/tools/stream/speaker_board.py +++ b/modules/usbhost/tools/stream/speaker_board.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # Board half of the sound-card stream check: bring up usb-device-audio's # speaker beside the console, then drain its ring for a while and report what # arrived. Driven over a held REPL (tools/stream/speaker_check.py). diff --git a/modules/vision/manifest.py b/modules/vision/manifest.py index 79944343..844df29a 100644 --- a/modules/vision/manifest.py +++ b/modules/vision/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # vision: esp-vision's OpenMV-style image stack, compiled as it is # (modules/.esp-vision). C only; ESP32-P4 and ESP32-S3. image (with image.ImageIO), # espdl, and on the P4 h264 and rtsp; not sensor or display (see diff --git a/patches/apply_patches.py b/patches/apply_patches.py index f34bb618..d7743edb 100755 --- a/patches/apply_patches.py +++ b/patches/apply_patches.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Prepare a MicroPython checkout for our builds. The checkout is moved to the tag in UPSTREAM, then gets every patch in diff --git a/scripts/ci_scope.py b/scripts/ci_scope.py index cceeab9a..3c3a2aa0 100644 --- a/scripts/ci_scope.py +++ b/scripts/ci_scope.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Say what a change can reach in the workflows that build firmware. A pull request is diffed against its base; a push to main from the commit main diff --git a/scripts/freeze_list.py b/scripts/freeze_list.py index 5bf09aa7..30964855 100755 --- a/scripts/freeze_list.py +++ b/scripts/freeze_list.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """List what a manifest freezes, by name and hash, and compare two lists. scripts/freeze_list.py list --port-dir micropython/ports/unix \\ diff --git a/scripts/release_firmware.py b/scripts/release_firmware.py index 6d02343a..8394d532 100755 --- a/scripts/release_firmware.py +++ b/scripts/release_firmware.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """The firmware set: which boards, how each is built, and the checks on the result. .github/workflows/release-firmware.yml calls this; every step also runs by hand diff --git a/scripts/stage_firmware_page.py b/scripts/stage_firmware_page.py index 407d3757..eb103292 100644 --- a/scripts/stage_firmware_page.py +++ b/scripts/stage_firmware_page.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Lay a firmware set out for the download page. stage_firmware_page.py [--interpreters FILE | diff --git a/scripts/update_provenance.py b/scripts/update_provenance.py index b56de77c..9ef05075 100644 --- a/scripts/update_provenance.py +++ b/scripts/update_provenance.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Keep provenance.json in step with the tree. provenance.json records the MicroPython pin and the SHA-256 of every patch in diff --git a/scripts/wasm_provenance.py b/scripts/wasm_provenance.py index 6f8c5f31..9f1ced0a 100644 --- a/scripts/wasm_provenance.py +++ b/scripts/wasm_provenance.py @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Write micropython.wasm.provenance for a webassembly build. The website and workbench keep this file beside the runtime they serve, so a diff --git a/tests/test_build_mp.py b/tests/test_build_mp.py index 7f634a2e..da76c7c5 100644 --- a/tests/test_build_mp.py +++ b/tests/test_build_mp.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Unit tests for build_mp.py's decisions that need no build. PYTHONPATH=tests python3 -m unittest test_build_mp -v diff --git a/tests/test_ci_scope.py b/tests/test_ci_scope.py index 61b10a8a..a4383f8b 100644 --- a/tests/test_ci_scope.py +++ b/tests/test_ci_scope.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """scripts/ci_scope.py: which jobs of the firmware workflows a change can reach.""" import re diff --git a/tests/test_freeze_list.py b/tests/test_freeze_list.py index f4617bc9..ebe8b659 100644 --- a/tests/test_freeze_list.py +++ b/tests/test_freeze_list.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Unit tests for scripts/freeze_list.py's comparison and, with a prepared MicroPython checkout, its reading of a manifest. diff --git a/tests/test_lib_overrides.py b/tests/test_lib_overrides.py index 36feecb8..576344d7 100644 --- a/tests/test_lib_overrides.py +++ b/tests/test_lib_overrides.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """lib-overrides/mip is micropython-lib's mip plus the marked patch, nothing else.""" import pathlib import re diff --git a/tests/test_provenance.py b/tests/test_provenance.py index 398ba881..d73f72d4 100644 --- a/tests/test_provenance.py +++ b/tests/test_provenance.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Tests for scripts/update_provenance.py, and the check that the committed provenance.json is current. diff --git a/tests/test_release_firmware.py b/tests/test_release_firmware.py index 070ee52f..8220fcee 100644 --- a/tests/test_release_firmware.py +++ b/tests/test_release_firmware.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Tests for scripts/release_firmware.py: the cell table and the checks `assemble` makes on what the builds hand over. Nothing is built. diff --git a/tests/test_stage_firmware_page.py b/tests/test_stage_firmware_page.py index ec8cbf92..42463682 100644 --- a/tests/test_stage_firmware_page.py +++ b/tests/test_stage_firmware_page.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Tests for scripts/stage_firmware_page.py. PYTHONPATH=tests python3 -m unittest test_stage_firmware_page -v diff --git a/variants/desktop-board.py b/variants/desktop-board.py index 08ed3ab3..b73a527f 100644 --- a/variants/desktop-board.py +++ b/variants/desktop-board.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The desktop and browser images' board config, frozen, from omnipython-lib: # board_config and board_peripherals from its `desktop` package, and the # desktop-only helpers pydevices-desktop carries (the pure-Python SDL2 and diff --git a/variants/esp32/ESP32_GENERIC_P4/WIFI6_DEV_KIT_H2/manifest.py b/variants/esp32/ESP32_GENERIC_P4/WIFI6_DEV_KIT_H2/manifest.py index ca8fb46d..81c8dc98 100644 --- a/variants/esp32/ESP32_GENERIC_P4/WIFI6_DEV_KIT_H2/manifest.py +++ b/variants/esp32/ESP32_GENERIC_P4/WIFI6_DEV_KIT_H2/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The DEV-KIT's frozen content: the port's and the modules you named # (modules/manifest.py), plus the USB packages this board's apps import and # midiports, frozen so the board runs without a mip install. Only this variant diff --git a/variants/unix/pydevices/manifest.py b/variants/unix/pydevices/manifest.py index 0dbfb816..c076d01e 100644 --- a/variants/unix/pydevices/manifest.py +++ b/variants/unix/pydevices/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The PyDevices desktop build: the port's own content and the modules you # named (modules/manifest.py), plus the universal desktop board config, # frozen. A board_config.py beside your script still wins: the script's diff --git a/variants/webassembly/pydevices/manifest.py b/variants/webassembly/pydevices/manifest.py index 25bddd52..80c07a38 100644 --- a/variants/webassembly/pydevices/manifest.py +++ b/variants/webassembly/pydevices/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The direct browser runtime. This variant brings its own port content rather # than modules/manifest.py's: # its Fetch-backed requests module must be frozen before anything resolves diff --git a/variants/webassembly/pydevices/requests.py b/variants/webassembly/pydevices/requests.py index ec5e8686..b3cd9762 100644 --- a/variants/webassembly/pydevices/requests.py +++ b/variants/webassembly/pydevices/requests.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + """Small requests-compatible facade over the builtin Fetch bridge.""" import io diff --git a/variants/windows/pydevices/manifest.py b/variants/windows/pydevices/manifest.py index 0dbfb816..c076d01e 100644 --- a/variants/windows/pydevices/manifest.py +++ b/variants/windows/pydevices/manifest.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Brad Barnett +# +# SPDX-License-Identifier: MIT + # The PyDevices desktop build: the port's own content and the modules you # named (modules/manifest.py), plus the universal desktop board config, # frozen. A board_config.py beside your script still wins: the script's