#circuitpython-dev
1 messages Β· Page 94 of 1
Why not add a tomllib module instead of adding a new supervisor API?
What about adding a section in BUILDING.md?
Won't make it for the meeting.
I have nothing to report except that we are having fun letting an LLM writing the code for us.
And also group hug.
Why not add a
tomllibmodule instead of adding a new supervisor API?
tomllib has a simple API but loads the entire TOML file as a dictionary, which doesn't match well with the internal API we already need to look up single values when the VM is not running and we can't allocate a dictionary and its objects easily. tomllib doesn't have a single-value lookup API. But we can brainstorm on this.
What about adding a section in
BUILDING.md?
Works for me! Thanks!
GitHub
The README is missing a comparison to https://github.com/RustPython/RustPython or why it was not considered. Why use a barely functional subset of Python when an almost-complete one already exists ...
Thanks for hosting Dan, have a great week everyone π
@lone axle The echo-cancelling did not work well this time in my recording. Did you make a backup recording? If not, no big deal
Yes, I did. Will upload and share a link a moment.
thank you!
Thanks! downloaded -- you can delete
Here is the notes document for next Mondayβs CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Add your hug reports and status updates to the document before the meeting. If you are unable to attend but would still like to contribute, feel free to add your notes and weβll read them off during the meeting. Hope to see you there! <@&356864093652516868>
https://docs.google.com/document/d/1AxFL2PBO0_5sNtGk03McAd9EYIKtvTdZTly28n_SL4U/edit?usp=sharing
Automated website update for release 10.1.1 by Blinka.
@slender iron have you got some time for a video checkin about short-term PR discussions, etc.?
yup!
We chatted about this and decided this is ok. We want internal typed supervisor APIs and it makes sense to give the user access through the supervisor module.
Merge fix for port_yield() performance problem into main.
This appears to be solved in 10.1.1 so I think this can be closed.
Initing SPI
Done initing SPI
Code done running.
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
Press any key to enter the REPL. Use CTRL-D to reload.
Pretending to deep sleep until alarm, CTRL-C or file write.
Woken up by alarm.
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Initing SPI
Done initing SPI
Code done running.
Press ...
I hope it was ok for me to close the issue. It is fixed in 10.1.1 and I opened it but I'm kind of new to the filing of bugs and closing them so let me know if I should have left it open for others to review.
CircuitPython version and board name
Adafruit CircuitPython 10.1.0-rc.1 on 2026-02-11; Adafruit QT Py ESP32-S3 no psr
am with ESP32S3
Board ID:adafruit_qtpy_esp32s3_nopsram
UID:8DB3ADE87E0F
MAC:D8:3B:DA:8E:E7:F0
Code/REPL
# Hardware:
# (1) QT Py ESP32-S3 with 8Mb Flash, no PSRAM
# (2) QT Py EyeSpy BFF
# (3) 1.28 inch round 240x240 TFT display with microSD card slot
# (4) APDS9960 light/color/proximity/gesture sensor [DISABLED FOR TEST]
#
import ...
It's fine to closed it. You retested and it was no longer a problem -- that's good to hear !
Please try 10.1.1. 10.1.0-rc.1 had serious performance problems on Esprssif.
Thanks guys!
Is there any way to run an automated performance regression test in an emulator as part of the build process? E.g. running a wide range of operations and checking vs. a known duration timestamp for a board?
I saw that there were changes to the garbage collector as well. These changes might be difficult to to test and maybe a "peformance guard" could help in some way?
@daniel-alsen
Automated performance regression tests would be great. But I am not so sure about the emulator part. Even if there were an emulator, it would not detect problems triggered by USB or the network stack.
Running tests on dedicated hardware is possible with Github actions, see e.g. https://github.com/ChandimaJayaneththi/ESP32-GitHub-Actions-CI
The CircuitPython sources do contain a number of performance tests, see directory tests/perf_bench. But these tests are targeted ...
The MagTag 2025 has a SSD1680-based e-ink display. Unfortunately, there are at least two slightly different versions of this display on MagTag 2025 boards. The newer boards need a colstart of 8; older boards need 0. (There was some thought it needed -8, but that's not true.)
Examples:
https://forums.adafruit.com/viewtopic.php?t=222540
https://forums.adafruit.com/viewtopic.php?t=222605
This fix sets the default colstart to 8, to match the latest boards, but makes changeable in ...
Note this is a PR against 10.1.x, so this can be in a 10.1.2 release.
Confirmed works testing with Magtag with EPD ribbon cable markings:
<img width="433" height="324" alt="image" src="https://github.com/user-attachments/assets/7a4935ae-3b5e-4c81-b8bd-064afee7c155" />
No changes to settings.toml or any other code. Just a CP firmware update.
BEFORE
<img width="722" height="472" alt="image" src="https://github.com/user-attachments/assets/c965c8bf-babe-4621-98a1-e2b3019328d1" />
AFTER
<img width="658" height="428" alt="image" src="https://git...
I don't think an emulator would work because I don't know of one that is rigorous enough to get timing right. For performance testing, I think we'd want to do it on actual devices.
FYI, we may have a way to detect the difference. If anyone has an early 2025 magtap please reply here or on Discord: #help-with-circuitpython message
CircuitPython version and board name
Adafruit CircuitPython 10.1.1 on 2026-02-17; Adafruit-Qualia-S3-RGB666 with ESP32S3
Code/REPL
import adafruit_qualia
from adafruit_qualia.graphics import Displays
from adafruit_display_text.label import Label
import terminalio
import displayio
import vectorio
BLACK = 0
TEXT = 1
RED = 2
def make_palette():
palette = displayio.Palette(7)
palette[BLACK] = 0x000000
palette[TEXT] = 0x00FF66
palette[RED] = 0...
Adds basic scanning and advertising support. Uses BabbleSim to test on a host computer.
Automated website update for release 10.2.0-alpha.1 by Blinka.
New boards:
- deshipu_ugame_s3
https://blog.adafruit.com/2026/02/18/circuitpython-10-2-0-alpha-1-released/
Highlights of this release
- Include 10.1.1 fix for performance regression.
- Better entropy for RP2350 os.urandom().
- Add
supervisor.get_setting(), which retrieves a string, boolean, or integer typed value fromsettings.toml.
Instead, delay in a couple spots within Zephyr.
See also:
https://forums.adafruit.com/viewtopic.php?t=222540
https://forums.adafruit.com/viewtopic.php?t=222605
The MagTag 2025 has a SSD1680-based e-ink display. Unfortunately, there are at least two slightly different versions of this display on MagTag 2025 boards. The newer boards need a colstart of 8; older boards need 0. If colstart of 0 is used when 8 is needed, you get artifacts like this:
It seems the ribbon cables are labeled differently:
Older SSD1680:
Newer SSD1680:
To distin...
- Fixes #10835
Attempts a display register on the MagTag e-ink, which returns different values on IL0373, older SSD1680, and new SSD1680. Choose the correct display type based on the register value (or lack of it). See #10835 for details.
Supersedes #10831, which was not automatic.
I think we can do this automatically. Closing in favor of #10836.
- Slipped 10.1.1 in when I wasn't looking!
- Installed 10.1.1 and still get crashes to safe mode, but conditions under which crashes happen are different. See below.
- Note that this is the same system associated with issue #10680
Testing with 10.1.1: Test script is as follows...
# Hardware:
# (1) QT Py ESP32-S3 with 8Mb Flash, no PSRAM
# (2) QT Py EyeSpy BFF
# (3) 1.28 inch round 240x240 TFT display with microSD card slot
# (4) APDS9960 light/color/proximity/gesture ...
Closing in favor of #10836, which autodetects the display type.
Random question:
I've been doing a lot of work with dof sensors and have noticed that the Adafruit libraries are designed to be human readable vs performant (lots of lookups, multiple function calls, etc).
Trying to figure out if optimizations would be accepted, or if I should make my own forks
BobG from discord says it works on their November 2025 MagTag, which is the only kind I don't have. It works on my original IL0373, and on the sample I just got. So the code is doing what I intended on the three different kinds.
Do you mean with the Register library? It would be nice to figure out how to do that more compactly. If Python had macros...
So both that and the sensor libraries themselves.
For example in the Adafruit_CircuitPython_LSM6DS library for the gyro it does:
@property
def gyro(self) -> Tuple[float, float, float]:
"""The x, y, z angular velocity values returned in a 3-tuple and are in radians / second"""
raw_gyro_data = self._raw_gyro_data
x, y, z = (radians(self._scale_gyro_data(i)) for i in raw_gyro_data)
return (x, y, z)
def _scale_gyro_data(self, raw_measurement: int) -> float:
return raw_measurement * GyroRange.lsb[self._cached_gyro_range] / 1000
We could, first store this on range change:
self._gyro_multiplier = radians(GyroRange.lsb[self._cached_gyro_range] / 1000.0)
And then do this in the property:
rx, ry, rz = self._raw_gyro_data
scale = self._gyro_multiplier
return (rx * scale, ry * scale, rz * scale)
And remove a ton of overhead (lookups, math, generators, etc)
Consistent emulator runs in the same environment would be the key.
At leat one emulator for one port needs to produce reasonably consistent timestamps for a performance test run, in the same CI environment on the same hardware. No need to match the exact timestamp for a run on real device. Then it could say "Loop test is up by 10%", "BLE serial slowed down by 20%", "Overall improvement by 15%".
Tested and works on the two variants I have - original IL0373 and on recently acquired MagTag. I also do not have a circa Nov 2025 variant for testing.
Can Please Someone Build The Bootloader for the Sensorwatch Fork For Me?
https://github.com/joeycastillo/uf2-samdx1
I just want the build from make sensorwatch_pro, which #define LED_PIN PIN_PA12 changed to #define LED_PIN PIN_PB22 on this line: https://github.com/joeycastillo/uf2-samdx1/blob/master/boards/sensorwatch_pro/board_config.h#L13
I tried building uf2-samdx1 on both my laptop with Ubuntu 24.04.3 and via WSL on my Windows PC and cannot get it built.
I also tried running the adafruit/uf2-samdx1 repo, and it fails as well on both machines.
I get a overlaps section .relocate LMA error each time.
In-depth attempt steps can be found here: https://github.com/adafruit/uf2-samdx1/issues/229
**Edit: **Fixed by following this tutorial and using Ubuntu 18 in a virtualbox. https://forum.arduino.cc/t/creating-a-custom-samd-bootloader-and-arduino-board/1094588
Unless corrected, I think the root cause is development mistakes made in newer versions of Ubuntu.
https://bugs.launchpad.net/ubuntu/+source/newlib/+bug/2107222
Thanks. I hope you think the new names clarify things.
Looks good to me. I tested on the two variants I have: original and July 2025. Both work as expected, no extra static on display.
Looks good to me. I tested on the two variants I have: original and July 2025. Both work as expected, no extra static on display.
That is a great example of what could be done. We would welcome such PR's. I don't think the way it was done was necessarily deliberate; it was just done quickly.
The same might be true of the corresponding Arduino library. In the past the Arduino library was written first and then served as the template for the CPy library
Re your comments in the repos: nothing to apologize for! We have cooperated with Microsoft on this in the past. Their initial work was instrumental in getting MSC-based bootloading to be a common thing. The bootloaders work, but don't get a lot of maintenance attention, partly because we haven't shipped SAMD-based boards in a while. There's a recent problem with SAMD bootloaders on ChromeOS, which comes and goes -- it may be some kind of race condition.
That's interesting! I figured that SAMD boards were the go-to board for simple applications due to its versatility, price, and amount of support.
What has Microsoft moved to?
not microsoft, us. The RP2040/RP2350 has been a good substitute. SAMD21 is really too small for CircuitPython except for small applications. SAMx5x is better but the cheaper versions are somewhat flash-flimited.
the uf2 bootloader was someone's side project, they laid off all people who were working on it
Microsoft Research moved to working on JacDac, but I haven't followed what they've been doing recently. The UF2 bootloader was just an enabling technology for MakeCode and the like
I rebased on 10.1.x; that was my intention (and I tested with that), but I forgot when submitting the PR.
Thanks for the nice writeup!
There was a GitHub CI failure. I re-ran the failed jobs and it succeeded.
I was using adafruit-circuitpython-adafruit_magtag_2.9_grayscale-en_US-20260219-main-PR10836-31dd19b.uf2 for the testing I did.
I re-tested the latest UF2 artifacts on both of my MagTag versions. Both still behaving as expected
Peli is working on the github actions AI stuff. Michal is at OpenAI according to LinkedIn
Is there a list somewhere of all the DOF sensors Adafruit has (other them me combing through all the products)? I'd love to see how most have been written and see what standards I can come up with
also adafruit_circuitpython_register is pretty small. has there ever been thought of putting it into CP itself so it can be faster?
ahhh, it has a motion sensor section. That will be a good starting point. and about half I've visited π
I'm building out profiling now. Most of what I build on that will be using a random generator for getting the raw values, so there isn't any i2c issues that skew results
I have hours or recorded readings I'm using to optimize some code I'm writing for am agnostic fusion library
@tulip sleet the zephyr bleio PR is ready for review. Will have smaller follow ups after it
I was dreading fixing the last four build failures... and pi did it all by itself with just a short prompt.
Here's some interesting stuff I've started with
100000 iterations
a:
import math
def test(value):
return math.radians(value)
b:
from math import radians
def test(value):
return radians(value)
c:
from math import radians
local_radians = radians
def test(value):
return local_radians(value)
a) 341.86 ms
b) 257.54 ms
c) 238.25 ms
so things that happen in tight loops like computing sensor data can benefit a lot from some optimizations...
I think a better phrase might be "a new raspberry pi" instead of "the second newest raspberry pi" because it would need to be amended when the Pi 6 comes out, plus if you count things like The Pi Zero 2W, second newest isn't quite correct anyways.
This looks fine to me. The one suggestion I have is to document this somewhere so others can use it. Maybe somewhere in docs/?
Looks good to me too! Thanks!
Only minor questions and nits, mostly about use of printk().
The testing stuff is great!
Get dan's comments from the PR and address them
and it did most of the things
I did have to stop it before it pushed
as long as it did what you wanted to do π
I would have been more explicit. ... yeah, I expected you could easily ask it to do that.
next time I'll tell it to not push the changes
These failures are due to a new version of click and are unrelated.
Is there a suggested way to install arm-none-eabi on Ubuntu 24.04?
I wasn't able to find any official documentation and forums I found warn of many pitfalls in symlinking.
I found this bash script, which uses a version from Summer of 2025, and used it (after reviewing it for any neferious commands, of course).
Is that the method you'd use?
https://github.com/kmhallen/gcc-arm-none-eabi/blob/main/gcc-arm-none-eabi-install.bash
just unpack the tarball and point the PATH to it?
Here is where to download it: https://learn.adafruit.com/building-circuitpython/linux#cortex-m-builds-3049646. Then you can just do as deshipu says: unpack it and add its bin directory to the front of your PATH.
Thanks! Is there a suggested folder it should be in? Does usr/bin make sense?
If usr/bin is in $PATH, does that mean that I just need to unpack it there and run apt update?
Thanks for helping me with my novice questions btw
If I'm not mistaken, it's in the Ubuntu apt-get repos. That said, if you want the newest version, that probably isn't it.
(If you install it by download and unpacking a zip or tar file, apt will not keep track of it or even be aware of it. So apt update won't do anything for it. If you install it using apt or synaptic, then apt will know it is there and update it when it is updated in the repo by running apt update.)
I might be wrong. I'm finding stuff about ARM not hosting a PPA for it anymore, but that doesn't necessarily Ubuntu isn't hosting in their own repos.
Try this to check: apt-cache search arm-none-eabi If there's a package in the repos for your Ubuntu version, it should come up. If it doesn't, then I'm wrong and it isn't in the Ubuntu repos afterall.
Please don't put it in /usr/bin. dpkg assumes that it has control of everything in there, and if you put something in there that overwrites something installed with apt, it can break other applications. It is generally recommended, if you are going to install something outside of apt, to install it in ~/.local for your normal user. That way you don't risk damaging something installed by apt. From there, find the bin directory in the ARM toolchain directory, and add that bin directory to your PATH variable.
Thanks. I've given up on anything related to PPA. All sources show that arm-none-eabi isn't maintained there anymore, and I'd rather learn how to install the tar myself than try to find another host.
Not a bad plan, but yeah, apt update won't do anything for it if you install it manually.
What I would do is upzip the tarball, either in my home directory or in .local under my home directory (if I don't want to clutter my home). Then if you go down into the directory created when unzipping, you'll find a bin directory in there. Get the full path of that directory (you can cd into it and then do pwd to print the full path), and add that to the PATH environment variable. That should do it.
If you need to upgrade to a newer version, you can unzip it in your user .local (or home, if you put it there), and change the PATH entry to use the directory for the new version (usually just changing the version number). Once that is done, you can delete the whole directory tree for the old version, unless you want to keep it. Note that if you are setting and changing PATH in .bashrc or .profile, you'll need to restart your terminal to use the new one. (Or you can run source ~/.bashrc or source ~/.profile, depending in which you are using.)
Personally, I usually drop that one in my home directory, so that if I have a reason to start digging into it, I can find it easily. That said, pick whichever you prefer and then be consistent about it, and you'll be fine!
I have a ~/bin directory which has some executables in it directly, and I also put other local software there and add to PATH as appropriate. It's something I've done for decades, before .local was a convention.
I have reduced this to:
import board
board.I2C().deinit()
This will cause a safe mode, on various ESP32-S2 and ESP32-S3 boards I tried. No crash on SAMD or RP2040.
I've also seen people do a ~/.bin as well. As long as you don't step on the toes of the package manager, any of that works.
Same behavior on RP2040 with adafruit_ov5640
...
[adafruit/circuitpython] New tag created: 7.0.2
[adafruit/circuitpython] New tag created: v1.26.1
[adafruit/circuitpython] New tag created: 7.0.3
- Fixes #10832
common_hal_busio_i2c_unlock() can be called from reset_board_buses() to unlock a board I2C bus. Don't try to unlock if the bus has already been deinited.
This was a somewhat edge case, which came up because the Qualia library does board.I2C().deinit(), which is not that common. But it caused a hard safe mode crash.
@slender iron I'm not sure why we are suddenly having this build problem with click. I guess some other pypi module is now requiring an older click. Click 8.3.1 was released in November, so this is not because of some new release. Maybe some cache expired?
the logs don't say who is requiring click<8.2;>=7.0
Found it, it's in ~/.espressif/espidf.constraints.v5.5.txt. That seems to be generated during install.sh.
I looked at an older working build and it was using some CI caches. The failing new ones are not.
I think maybe this is because requirements-dev.txt reqs are installed after ESP-IDF reqs
maybe we talked about fixing this before?
... Trying a change to actions.yml to do that
now missing dependencies for espressif boards
Run python3 -u build_release_files.py
Traceback (most recent call last):
File "/home/runner/work/circuitpython/circuitpython/tools/build_release_files.py", line 12, in <module>
import build_board_info as build_info
File "/home/runner/work/circuitpython/circuitpython/tools/build_board_info.py", line 13, in <module>
import sh
ModuleNotFoundError: No module named 'sh'
Error: Process completed with exit code 1.
sh is in requirements-dev.txt, so it's not just that it was missing
We definitely have had this issue before where we feel the impact of a new release only after our cache key changes. Could have been a python version bump
there was 3.14.2 to 3.14.3. I'm looking at .github/actions/deps/external/action.yml and trying to see what to do. I think always do pip install -r requirements-dev.txt, even for espressif. Why is it turned off for zephyr-cp? Does that have a completely separate list of dependencies?
I'm not sure why it is off. Zephyr does have its own list of python deps
trying again...
trying to have the port-specific install re-do any installations that the general requirements-dev chose
maybe I will take away that check for zephyr too, if the zephyr builds fail too
I compared the failed run 22229143457 with the last successful Build CI that included espressif (22190907999).
What changed
- Successful run (22190907999) restored IDF python cache with key:
- Linux-/opt/hostedtoolcache/Python/3.14.3/x64-tools-idf-...
- Log shows: βCache hit for β¦3.14.3β¦tools-idfβ¦β
- Failed run (22229143457) looked for:
- Linux-/opt/hostedtoolcache/Python/3.14.2/x64-tools-idf-...
- Log shows: βCache not found for input keys β¦3.14.2β¦tools-idfβ¦β
So it did not reuse cache because the cache key includes env.pythonLocation, and that changed from 3.14.3 to 3.14.2.
Why that caused the build break
After cache miss, it rebuilt/install python deps in the IDF env, which pulled newer click:
- Failed run error:
- Requirement 'click<8.2,>=7.0' was not met. Installed version: 8.3.1
In the successful cached run, the env had click 8.1.8, so dependency check passed.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
If you want, I can propose a workflow fix (e.g. pin Python minor/patch for stable cache keys, and/or prevent requirements-dev.txt from
upgrading IDF-constrained packages like click).
looks like the python update caused the cache miss
the simplest fix is to change our -dev.txt to limit click
though there is a minor idf update we can do too
gonna see if codex can do that
I was thinking of limiting click in that way, but hold on for the build I am doing as part of a PR to fix this
I would like to do a 10.1.2 with the MagTag fix and this fix.
that is a better fix
I wonder what else we can unpin then
this is definitely not the first time its happened
no, it didn't work, problem with nested virtual environments. I will pin click for now, and we can work on a better solution in main.
lemme check what version of click is used my idf 5.5.3
this PR is for 10.1.x
I can't tell where the <8.2 requirement comes from
it is in a constraints file in the idf tools
it is DOWNLOADED from somewhere, it's not in the repo
Fixes MagTag, Qualia and build.
This also fixes the Python requirements problem by setting the constraint file for espressif builds.
Automated website update for release 10.1.2 by Blinka.
Release was wrongly tagged. Closing in favor of 10.1.3.
changes as requested by @makermelissa
Automated website update for release 10.1.3 by Blinka.
Thanks for your comment, @tyeth! I'm on interface version 0258 and it doesn't appear to allow me to downgrade. The device refused to mount after an unsuccessful firmware downgrade to 0255, and I had to reflash it to 0258 to get it to mount.
Does that mean you're using a beta as indicated at the bottom of this page which suggests 258 is in beta.
https://tech.microbit.org/software/daplink-interface/#daplink-software
Where did you get 258 from?
Maybe need to follow the downgrade DAPlink instructions link mentioned on the page.
https://microbit.org/get-started/user-guide/firmware/
Just to also add that I similarly had some failures attempting to do firmware stuff, and getting confused about which mode wants which .hex file, bu...
https://blog.adafruit.com/2026/02/20/circuitpython-10-1-3-released/
Highlights of this release
- Adafruit MagTag: auto-detect different versions of e-ink display on 2025 MagTag.
- Espressif: fix board I2C object deinit(). Fixes crash with Adafruit Qualia library.
CircuitPython version and board name
ESP32-S3 Reverse TFT Feather running any version greater than 10.0.3 starting with 10.1.1.
Code/REPL
No user code has been loaded onto the board. Just than the "Hello World" default code included with all CP .UF2 images.
Behavior
No error messages and on the problem board it may do the sideways display as shown in the video but other times the display doesn't come up at all (backlight is on though). When I first...
Dang. It's late and I'd rather tackle further debugging tomorrow, but I happen to have two ESP32-S3 TFT boards -- one I purchased sometime last year and one I purchased in the past couple of weeks. The old board exhibits the same weird behavior with CP 10.1.3 -- 2nd click gets sideways display and the newer board does not. I'm happy to troubleshoot as a second set of eyes whatever you guys need tomorrow. But I wanted to corroborate @Timeline8's report.
just to add my two cents - I have a Feather ESP32-S2 TFT and I am seeing similar issues. On anything newer than 10.0.3 the screen will stop functioning after a reboot. It will work for the initial run after the flash, but then fail to display after. The backlight will still be on however.
I just read the code change for the MagTag.
Bitbang 4-wire SPI with a bidirectional data line to read the first word of register 0x2e
All I can say is that is some serious code-fu! Congratulations π«‘
That code was already there, written by Scott, to try to read a different register to distinguish first-generation MagTags from 2025 MagTags
Itβs impressive sleuthing! Itβs a trick I will note βfor future useβ ππ»
Our Explorer Badge needed to differentiate various ePaper displays. We hand no idea about reading registers. Fortunately, we caught the scenario before final hardware and added a voltage divider to a pin. (Changing the resistors to yield different voltages based on which display was used in manufacturing.)
Well,apparently that our initial test is not fine-grained enough. Someone has come up with a "new" display whose markings suggest one setting, but it seems to need another setting: https://forums.adafruit.com/viewtopic.php?p=1082017#p1082017 and following. I await the results. It appears the supplier is providing work-different variants for the same part number.
We are encountering similar βvariantsβ. It has made supply chain even more challenging than it was (which for a tiny shop like ours, is saying something).
Anyway, cool trick and if I ever get into this kind of bind, I will remember to do this level of digging.
Many displays have no way of reading anything back: they are write-only. We were just lucky here.
I originally did not try to read a register, and just guessed on a value, but gave the user the ability to override in settings.toml: https://github.com/adafruit/circuitpython/pull/10831
Good to know: I will revisit the use and timing of settings in toml file. (another good detail to remember for future use)
@brentru let's review this next week, we probably need similar!
Turns out the apparent fourth display version was not true; I am relieved π
We had to switch vendors so this topic may become relevant for us sooner than anticipated.
Thanks Blake and Bob for confirming what I was seeing. I was a little worried it might be just my board and no one else would see it.
And Bob thanks for noting which boards it does work on. To confirm your finding, the one I am seeing the problem is my old one I got probably ~2 years ago. The other one, newer one, I still have in the Adafruit bag is date coded 2025-03-06. The newer one works fine.
To add further information, the colors are also wrong when this happens. This is running 10.1.3 and the only difference is the correct display I ran off the battery because it doesn't happen on battery and then the abnormal display I plugged it into USB where it does show the problem.
I'm not sure this helps but I found a few additional behaviors.
My old Reverse TFT that displays the problems I ordered in October 2025.
It is now more often than not starting up when powered on in the backlight on but no display mode. If I hit reset a bunch of times it will come up with the sideways display with noise on the lower 1/2 of the sideways display. Here is the interesting thing. If I do microcontroller.reset() in REPL it always (so far in dozens of tests) starts normally with...
I don't know if my CP GitHub FU is good enough to find where the differences are but I can verify the issue happened between:
- Working: adafruit-circuitpython-adafruit_feather_esp32s3_reverse_tft-en_US-10.1.0-beta.1.uf2
- Broken: adafruit-circuitpython-adafruit_feather_esp32s3_reverse_tft-en_US-10.1.0-rc.0.uf2
I surprised myself and figured out how to compare different Circuit python commits. The changed behavior on the Reverse TFT old displays happens between:
- Working: adafruit_feather_esp32s3_reverse_tft-en_US-20260203-main-PR10797-57eb925
- Broken: adafruit_feather_esp32s3_reverse_tft-en_US-20260204-main-PR10783-4b7b098
When looking through the differences I saw a change in using a new Digital IO framework and some new casts for FourWire. but I couldn't find anything obvious causing the cha...
I have reproduced this with an older ESP32-S3 TFT. Interestingly I can revive the display by causing a safe mode crash. There is no SD card socket attached to board when I run this, which causes a safe mode crash, but only on 10.1.3. 10.0.3 errors out with OSError: no SD card.
import time
import board
import sdcardio
time.sleep(2)
print("Start")
spi = board.SPI()
cs = board.D10
sdcard = sdcardio.SDCard(spi, cs)
I just tried it and it looks like the safe mode crash does something like a microcontroller.reset() as @grgrant mentioned above?
Earlier today I tried a supervisor.reload() but the soft reboot doesn't help. So you can not do a work around using supervisor.set_next_code_file then supervisor.reload() to fix the display then run the code you actually want to run.
I didn't mean to imply it was a workaround, just that it was an unusual error, and might be a clue as to the problem. The "workaround" is to use 10.0.3 or 10.1.0-beta.0 or beta.1.
I don't know the Circuit Python build environment very well. I saw something in one of the commits about a new ESP-IDF version. Is that something underlying that might cause strange behavior or is it most likely somewhere in one of the Circuit Python code change itself?
I saw something in one of the commits about a new ESP-IDF version.
That is in main, not 10.1.3, which is now on the 10.1.x branch.
There are a lot of changes to GPIO pin handling, including in fourwire in #10783. I tried undoing a few of those to check but haven't zeroed in on the cause yet.
Let me know if you want me to test but I guess you found you have a board that will exhbit the error. Have a good evening.
Many RC hobbyists using the Adafruit ESP32-S3 Feather encounter a common hurdle: SBUS signals from standard RC receivers are inverted, and CircuitPythonβs busio.UART currently lacks a way to handle this inversion in software, forcing the use of external transistor circuits that add wiring complexity, cost, and potential points of failure in compact robot builds.
Adding an invert parameter (or dedicated rx_invert/tx_invert kwargs) to busio.UART would enable native decoding of inverted RC SBUS ...
Related to #4230 and could be a configuration option for #9845. Espressif chips can invert the TX or RX for UART, and can also invert pin inputs/outputs generally, it appears. On, say, RP2040, there is general support for inversion, but not specifically for UART.
This is the kind of thing that is tedious but not hard to add, except tracking down the details for each chip family. The tedious part we might do with an LLM.
On the ESP32-S3 TFT Feathers, there is a separate regulator that must be enabled via a pin level to enable the TFT and I2C power. If I explicitly enable that pin during display setup in the C code in 10.1.3, it works. I'm tracking down why it used to work.
- Fixes #10841.
Before #10699, reset_all_pins() was called in reset_port(). That PR changed things to reset all pins in main()
after the finalizers ran. However, that change only handled pin reset after the VM stopped, and not on power-up or hard reset.
This caused #10841, because the power control pin for Feather S3 TFT was not powering the display as
required before the display was reset. (It's not clear why this only affected older boards, but it may have to do with the some ...
I tested pin alarms on a MagTag with this build, and they are still working fine.
Excellent. Do I have to wait for the PR to be approved to be able to download and try the UF2 build? Or is the build pending approval available now?
The build artifacts are available for any PR that has finished its build, even if not yet approved or merged. Click on any board build in the list of builds in the PR, click "Summary" in the top left sidebar, and find "Artifacts". Those contain UF2's, etc. https://github.com/adafruit/circuitpython/actions/runs/22283806182?pr=10843
Nope. I am crashing into safe mode. First I see in the serial windown `================ Serial reconnected ================
Start
Traceback (most recent call last):
File "code.py", line 11, in <module>
OSError: no SD card
Code done running.
================ Serial disconnected ================`
Then it resets again and comes back with
<img width="1000" height="461" alt="Image" src="https://github.com/user-attachments/assets/20d26d1c-4203-48c7-a5d7-dfce70e4677e" />
Nope. I am crashing into safe mode. First I see in the serial window
Are you using my test program, or one of yours? Could you post it? I think may well be an SD card problem that is different than the display problem.
Dang it. I thought I still had the shark code still on there. I don't recall loading your program. Let me test...
OK all good. Deleted your code and reloaded my shark code. Works fine. Sorry about that.
I used your same test setup. I did get safe mode crashes sometimes on a post-10.1.3 build, but not always. I moved backwards in builds, and started getting hangs where code.py appears not to finish. I think this is the USB connection hanging. Sometimes it can take 20 tries to make this happen. I just keep typing ctrl-D.
The problem seems to have been introduced between 10.0.0-alpha.4 and 10.0.0-alpha.5. I cannot see the "stuck" code.py behavior in alpha4, no matter how hard I try. But I ca...
I was about to request this too. I think I've used this in the past for comms between two boards where I wanted to reduce (but not eliminate) the chance of GPIO back-powering a powered-off board. cf MicroPython's invert arg on machine.UART.
I am facing the same issue on a slightly different setup, but with enough similarities to consider it suits this issue.
Using circuitpython 10.1.3 and having it recompiled with support for 2 displays (on macOS), I get the hard fault when CTRL+D to restart the controller. I tried to check my code, if it might be introducing the bug and only found that the error occurs when in the run before data was written to the secondary display, e.g. the display content was updated. Just creating the disp...
@slender iron do you remember how to get ESP_LOGx() output on a different UART TX line on ESP32-S3, instead of TXD0? I tried:
CONFIG_ESP_CONSOLE_UART_CUSTOM=y
CONFIG_ESP_CONSOLE_UART_TX_GPIO=9
to get it to go to GPIO9. The sdkconfig has those settings in it, but I am still seeing the output on TXD0. This is so I can see logging output on a QT Py, and I have very limited pins and no TXD0 without a tiny bodge wire. (Can't reproduce the problem on a more convenient board.)
that seems right to me. did you clean and rebuild?
oh, yeah, multiple times, trying to get the config right (the CONFIG_ESP_CONSOLE_UART_CUSTOM was not obvious) I was testing on a Feather where I can see output on both TXD0 and 9
and the pin is marked as in use by CPy.
I'll keep trying. the setup is fine. interestingly Espressif's IDF LLM help gave me the CONFIG_ESP_CONSOLE_UART_TX_GPIO, but didn't mention the _CUSTOM, and it was just pointing to a human-written thing that was also inadequate. I had hoped there was some commented-out something in our board files, but nothing there
I'd probably look in menuconfig
and also verify the sdkconfig in the build dir has the right setting
i've looked through the Kconfig's (used by menuconfig)... yup verified in sdkconfig as well. There may be another setting I am missing, but the settings in the generated sdkconfig look fine.
did you try claude code or something in your working directory?
just tried that now, it suggests using a different UART, instead of UART 0 which I was also thinking of. I was just hoping you remembered off the bat, since we've had to do this before.
i trust you more than an llm
it's been a while. I normally use uart0
i think the last time I did this was for a C3 or C6, which has different considerations (JTAG SERIAL)
anyway, I will try UART1, thanks
yes, might be logging directly via the ROM routines or something
Regarding the USB connection during these tests, I normally do not comment on any USB connection issues associated with CircuitPython issues as I do all of my testing on a Raspberry Pi 3B, and I have had some concerns about the stability of the USB ports on this computer. That said, the USB connection during these tests was more unstable than usual. Many instances where I would connect the board to my USB port and either the board would fail to connect, or I would get a serial connection bu...
<@&356864093652516868> We'll have our weekly meeting in about 60 minutes from now in this text channel and in the circuitpython voice channel. Please take the time to add your notes in advance to the document: https://docs.google.com/document/d/1AxFL2PBO0_5sNtGk03McAd9EYIKtvTdZTly28n_SL4U/edit?tab=t.0 -- I look forward to everyone's updates!
Google Docs
CircuitPython Weekly Meeting for February 23, 2026 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you canβt make the meeting and would...
The USB MSC device here has a second LUN (logical unit), which is used to present the SD card as a second filesystem. When the card is mounted manually in user code instead of early on startup (as would be true on, say, Fruit Jam), the host computer has to rescan and notice the new device. That can be flaky. It's also possible there's some latent error here, or some competition for the SPI bus between the the display and SD card.
I am trying to reproduce this, but can only reproduce on the Q...
Thank you @dhalbert . I only mentioned the USB issue in the event that it is related to the issues in this ticket. The much more frequent (and easier to cause) safe mode crashes makes me suspicious of RP USB port flaky-ness rather than CircuitPython issues.
I will try the newest UF2.
@tannewt I changed the merge base to 10.1x.
π
π
thanks for hosting!
Thanks for hosting Liz, have a great week everyone.
thanks folks!
Here is the notes document for next Mondayβs CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Add your hug reports and status updates to the document before the meeting. If you are unable to attend but would still like to contribute, feel free to add your notes and weβll read them off during the meeting. Hope to see you there! <@&356864093652516868>
https://docs.google.com/document/d/1O7WLFJtB-30PoMKpC718f7xujL1zuBMFYD059GWIdZk/edit?usp=sharing
Google Docs
CircuitPython Weekly Meeting for March 2, 2026 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you canβt make the meeting and would st...
I've finally got around to testing the boards, and I located some issues with pin assignments on the Thumby Color. I was able to get a copy of the schematics from TinyCircuits (which was otherwise not fully published) and should have the board definitions updated shortly.
Tried 10.1.3. Same crashes as with 10.1.1, unfortunately.
Creating new PR for RM690B0 display driver for Waveshare ESP32-S3 Touch AMOLED 2.41"
Contains:
- QSPI bus driver
- Waveshare ESP32-S3 Touch AMOLED 2.41" support
The Thumby Color now works and I've validated its operation with the following script:
import board
import keypad
import rainbowio
import time
import adafruit_rgbled
NAMES = ("MENU", "A", "B", "BUMPER_LEFT", "BUMPER_RIGHT", "UP", "DOWN", "LEFT", "RIGHT")
keys = keypad.Keys(
pins=(
board.BUTTON_MENU,
board.BUTTON_A,
board.BUTTON_B,
board.BUTTON_BUMPER_LEFT,
board.BUTTON_BUMPER_RIGHT,
board.BUTTON_UP,
...
Pull request overview
This pull request introduces a new QSPI (Quad-SPI) bus driver for CircuitPython, specifically to support the Waveshare ESP32-S3 Touch AMOLED 2.41" display which uses the RM690B0 controller. The implementation follows CircuitPython's established display bus architecture patterns.
Changes:
- Adds a new
qspibusmodule providing QSPI bus protocol support analogous tofourwirefor standard SPI - Implements ESP32-S3 specific QSPI bus driver using ESP-IDF's LCD pan...
Thanks, definitely worth doing!
Fixed by #10843. Still needs to be merged into main.
@cvmanjoo: according to the schematic, GPIO0 is used for PSRAM CS. You also have this pin in mpconfigboard.h for CIRCUITPY_PSRAM_CHIP_SELECT, this seems correct. Howver, since this pin is used internally, you should not expose it in pins.c (@dhalbert please correct me if I am wrong).
Thank you for your work, @cvmanjoo - I was getting ready to try and do this all myself. Any chance of an update, @dhalbert (please) so we can have official support?
Howver, since this pin is used internally, you should not expose it in
pins.c(@dhalbert please correct me if I am wrong).
That is correct: pins that are dedicated for internal uses, such as connecting to PSRAM or flash, should not be exposed in pins.c. Same of course for pins that are unconnected.
zephyr bleio PR is finally ready
This is definitely getting closer! Please prevent additional error messages from being added. You likely can reuse existing ones. Please also iterate with copilot on your own fork before making a PR.
Tests digital input and new rotaryio.
Thank you! CI is broken for other reasons.
Actually, you'll want to change the branch you are targeting. Right now it is set to 9.2.x.
@tannewt Thanks, got it fixed. I'm sure that was due to the age of this PR.
[adafruit/circuitpython] Pull request opened: #10847 Add networking support to the Zephyr native_sim
It uses the host's sockets directly to test our zsock integration. This doesn't test network management. It does also test the web workflow.
[adafruit/circuitpython] New comment on pull request #10845: Translations update from Hosted Weblate
@tannewt note there is a zephyr test failure here.
CircuitPython version and board name
Adafruit CircuitPython 10.2.0-alpha.1 on 2026-02-18; Adafruit Fruit Jam with rp2350b
Code/REPL
# inside settings.toml
CIRCUITPY_TERMINAL_FONT="/fonts/goudy_bookletter_1911_20px_1bit.bin"
Behavior
Running in safe mode! Not running saved code.
You are in safe mode because:
CircuitPython core code crashed hard. Whoops!
Heap allocation when VM not running.
Please file an issue with your program at github.com/ad...
The flaky test is still flaky apparently. I'm not sure how to fix it. I reran it for now.
FYI Don't bother reading the Python script to build all boards in parallel. It's just a tool that works so I didn't look closely either. It does drop the time from ~6 min to 3.4 min though.
@slender iron core lvfontio is already mostly supporting higher bpp fonts I think. However the palette gets defined at compile time inside gen_display_resources.py ultimately. I made a test build with 4bpp and it mostly works.
Do you have thoughts on how the palette could be made more dynamic or influenced by something end user accessible?
looks at gen_resources.py
@lone axle supervisor/shared/display.c needs to be updated to override the palette when setting an lvfont. Is the palette always N bits in the normal pattern or does each index have a custom color?
It looks to me like the palette is always N bits with background at index 0, and foreground at the last index. I've been putting a gradient evently stepped from one to the other in between and it seems to look correct.
but I have not tried to find the converter source/spec to verify
Ahh, the pixel_shader on the terminals TileGrid is writable at runtime, so this is possible in REPL/code.
CIRCUITPYTHON_TERMINAL[0].pixel_shader = gradient.make_gradient_palette(0x0, 0x00ff00, 16)
yup, it is
Do you know what the original font you converted for FJOS was? https://github.com/adafruit/Fruit-Jam-OS/tree/main/fonts I tried a unifoundry/unifont OTF file but I am coming up with considerably different filesizes. I also seem to have some kind of clipping going on for decenders, I'm not sure if that is a result of the font I'm using or something else in the code.
I'm so good at git comments.....
Pull request overview
Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (2)
locale/circuitpython.pot:922
- The error message "Data buffer is null" is added to the locale file but is never used in the codebase. Either remove this unused error message from the locale file or add the corresponding validation check in the code where it's needed.
#: ports/espressif/common-hal/qspibus/QSPIBus.c
msgid ...
in my command history I see python generate_font.py --output fonts/unifont-16.0.02-ja.lvfontbin ja
I got a different version. Will try that one.
looks like the script is in circuitpython-font-generator
Ahhhh, nice that has the ranges also. Thank you!
python generate_font.py --output fonts/unifont-16.0.02-en_US.lvfontbin en_US too
okay I will try some higher bpp of that specific font tomorrow and compare to current default.
π
I was testing the tip of main (with the 5.5.3 update) to compare it with some SD card changes I am making, and hit this error on startup on a Metro ESP32-S3. This was a debug build with CIRCUITPY_ULAB = 0 (to make the debug build fit). This is
@tannewt
Backtrace: 0x420cf330:0x3fcc1080 0x4203879e:0x3fcc10a0 0x420387b5:0x3fcc10c0 0x4203a55a:0x3fcc10e0 0x42023e77:0x3fcc1100 0x42024099:0x3fcc1150 0x42024765:0x3fcc11f0 0x42024bf2:0x3fcc1220 0x4215e4fb:0x3fcc1240
0x420cf330: ble_gap_adv_...
Pull request overview
Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.
π‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Thank you @tannewt for your feedback. I've implemented requested changes and did a couple of sessions with Copilot. Now the code needs some more professional view than me or Copilot :)
Please make sure the automated tests also pass.
Currently the lvfontio module reads the font_size and ascent out of the font file header. https://github.com/adafruit/circuitpython/blob/fd4226bb6e15884e9fa7f7014d54a4bfaf192db1/shared-module/lvfontio/OnDiskFont.c#L110-L114
and it uses the font_size as the height returned by common_hal_lvfontio_ondiskfont_get_dimensions https://github.com/adafruit/circuitpython/blob/fd4226bb6e15884e9fa7f7014d54a4bfaf192db1/shared-module/lvfontio/OnDiskFont.c#L568-L570
But it seems that font_size m...
I've had a look around the hardware this afternoon, with the schematic and a multimeter. I've also built CircuitPython with the pin definitions from @cvmanjoo - my first time building it from scratch!
Unlike something less barebones - like the Feather RP2350, which tucks away GPIO8 purely for the PSRAM option - on this one GPIO0 gets broken out and can be used as a normal pin. They're also not (as far as I've been able to find) sold with a PSRAM chip fitted, so the default configuration is...
I'm fixing the tinycircuits board defs
The two failing tests are fixed by #10851 because they were broken on main.
@relic-se the branch switch got around the CI. This fixes it.
Pull request overview
Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
ports/espressif/common-hal/qspibus/QSPIBus.c:467
- Inconsistent indentation: this line uses 3 spaces instead of 4 spaces for indentation. All other if statements in this function use 4 spaces.
if (!self->has_pending_command) {
π‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how t...
@slender iron I've got some questions about displayio display refreshing and bus competition, if you have time. This is to fix crashes when SD card and displayio are competing for the SPI bus, but could come up in other ways as well.
I'm around
Update on the async busio: I have the DMA working for rp2040 I2C. Strangely it can read upwards of 2400 bytes, but can only write 54. I'm going to verify SPI and UART behavior and then submit a pull request, at which point we can talk about structuring and perhaps do some refactoring.
updated frozen libs for latest changes for bitmap font and display text.
Implemented and tested on rp2040 port. Other ports to come after we settle on the structure of the new additions.
Tested on rp2040 using the examples from the async busio library:
https://github.com/kamocat/CircuitPython_Async_Busio
I have structured the new DMA methods into the existing I2C, SPI, and UART classes, and implemented the actual async functions in a separate Python library. Please let me know if there is a better way.
I need to set up a more robust test suite
- What happens if an I2C slave NACKs early?
- Does UART RX respect the timeout?
- Can I recover the DMA channel after a failure?
- Is the data actually transmitted correctly?
I am working on a PIO I2C device to better test long writes.
You're probably aware that there is a native i2ctarget module, but it has an issue currently for raspberrypi port.
Thanks for this PR. I have some suggestions about the API.
The idea is to implement non-blocking busio operations. DMA is one way of doing that, but it could also be done without DMA, by internal polling, etc.
So instead of exposing the name "DMA" to the user, could you make the API routines just use names like start_read() or non_blocking_read() or something like that?
The handle that is returned is currently an int. However, I think it would be better if it were an object, perhaps ...
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
py/circuitpy_mpconfig.h:407
- The comment says this value can be overridden βfor larger buffersβ, but
shared-module/busdisplay/BusDisplay.cenforces a hard maximum of 2048 words via_Static_assert. Either document the effective maximum here as well, or make the maximum configurable/port-specific so the documentation matc...
is there anyway to turn off ble and ble workflow when building for esp32-c3? when i try CIRCUITPY_BLEIO = 0 i get errors
CircuitPython version and board name
Running ESP32V2 with:
configsip: 271414342, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0040,len:436
load:0x40078000,len:14136
load:0x40080400,len:3116
entry 0x40080554
Serial console setup
Adafruit CircuitPython 10.1.3 on 2026-02-20; Adafruit Feather ESP32 V2 with ESP32
Board ID:adafruit_feather_esp32_v2
UID:8EF9D6023F46
Code/REPL
print "Hello world...
do you want to turn it off to save time, or because it's broken in some way?
it's with the xteink- i keep intermittently hard faulting after setting up web workflow so i was trying to think of ways to make space to see if that was why
by coincidence, do you see the bug just filed above?
I don't think it is necessarily space.
is there a 10.0.x build available?
I would like non-blocking calls for the busio I2C, SPI, and UART modules.
This would be awesome for ports that support asyncio, but could also be used to interleave communication and processing on ports with a little less resources.
I opened PR https://github.com/adafruit/circuitpython/pull/10854 to implement this, but Dan suggested the discussion would be better in an issue.
The question is, what should the API look like to best support all possible ports?
yeah i was just reading that.. i'll try to rebuild on 10.0.x
also can test with a c3 qt py since that isn't a hack
Actually, the behavior is more complex: it recovers after couple of seconds so back to back TCP connections are possible, however there is non-negligible delay between next connection can be made.
Hi @hierophect
I can work on an implementation for this, but STM has a lot of chips and it would be nice to have better coverage than just my STM32F407-Discovery. What boards do you have access to and are willing to test on?
Also, I opened up Issue #10856 to discuss the API, in case you have any input.
Looking at the latencies/packet loss of the ICMP messages in my environment, this could be caused by this, hence closing.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 3 comments.
π‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 4 comments.
π‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
For I2C it could be a start_read() and start_write() which return tracking objects and can be checked with corresponding read_complete() and write_complete() methods.
For SPI the reads and writes happen simultaneously, so maybe just a start_readwrite() with a corresponding readwrite_complete() method. Ideally this would transfer the greater of the written or read buffers, but I suppose it's fine if we require the buffers to be the same size for simplicity, so long as one of the...
Iβm working on a custom RP2350A board and seeing an intermittent SPI bring-up issue when using the C shared-module APIs. Firmware is based on CircuitPython 10.1.2
Summary
About ~50% of cold boots result in my SPI-based ADC driver returning all 0x00 for all reads (both data and register reads). The driver code continues to run and calls to common_hal_busio_spi_write/transfer/read return success, but the device never responds. Running:
import microcontroller; microcontroller.reset()
usual...
Have you captured the bus externally to know to see what is going on? You could check the output pad configuration too. Maybe it isn't set to output for some reason.
My preference would be to make a new abusio module and have the normal methods return coroutines that can be awaited. I know this is the first time we've done this so it'll be tricky. BUT, I think we'll want to do this in many places to make our API async-native.
Can you find the glyphs that descend that far? Maybe the generator is wrong?
I'm looking into the flaky test.
I agree that the abusio should be a separate module, but I don't think the awaitable methods can be written in C. That means it must be a Python module just like asyncio.
Furthermore, I would like to preserve the blocking methods for the likely event that someone will use a blocking and non-blocking driver on the same bus.
but I don't think the awaitable methods can be written in C
That was my conclusion the last time I was working on asyncio. There is not native support in MicroPython for C async methods or functions.
I fixed a pin reset issue across many ports on the 10.1.3 branch a few days ago. This is not in any release yet. Try updating to the tip of 10.1.3.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 1 comment.
π‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Between PR10839 and this one PR10840 my Adafruit QT Py ESP32-S3 4MB Flash 2MB PSRAM resets after loading the uf2 with repeating 5 sets of blue blinking lights and the following looping output on USB serial. This continues to the current main PR10847
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40380726
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce2820,len:0x18...
This is likely this bug: #10849
I'm going to look into it shortly.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
shared-module/busdisplay/BusDisplay.c:220
- The comment has a typo:
uint32_tsshould beuint32_ts (or justuint32_t).
uint32_t buffer_size = 128; // In uint32_ts
π‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 1 comment.
π‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 1 comment.
π‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ble_gap_adv_active() crashes now when BLE hasn't been init. This is likely due to internal memory allocations in esp-nimble.
So, check enabled before calling into it.
Fixes #10849
Now the bsim PHY will stay active until the test harness terminates it. This requires the CircuitPython device process to exit correctly first but is backed up by wall clock timeouts in the harness. (Sim timeouts were in simulated time.)
Please make sure the automated tests also pass.
Hi @tannewt. I did all I could however some tests are failing because of zephyr which I obviously haven't touched.
I did some more sessions with Copilot.
Additionally I've introduced a proper board.DISPLAY implementation which should be more useful than external rm690b0 module.
Is there anything else I can do?
What about a method to tell how many bytes are remaining to transfer? Or one to abort a transfer?
but I don't think the awaitable methods can be written in C
That was my conclusion the last time I was working on
asyncio. There is not native support in MicroPython for C async methods or functions.
Any idea what it would take to make it work? It's the way it should work IMO.
but I don't think the awaitable methods can be written in C
That was my conclusion the last time I was working on
asyncio. There is not native support in MicroPython for C async methods or functions.Any idea what it would take to make it work? It's the way it should work IMO.
If you can find an example I'm happy to try it. In my research I was not able to find one.
Also, what would you do about the asyncio dependency, which itself is written in Python?
Any idea what it would take to make it work?
I don't know. I would say it's a question to take up with the MicroPython folks. It's a bit hard to search for, because "native async" can mean @micropython.native which is about native code generation from Python.
Here is a several-year old MicroPython discussion related to this issue which @tannewt contributed to: https://github.com/orgs/micropython/discussions/13081
I don't care about use without asyncio (like andrew in that discussion) and I'd be willing to migrate actual asyncio to native as well so it'd just work.
This is what pi/Codex came up with and it seems plausible to me. I could give it a shot tomorrow:
Great question. In this tree, asyncio support is split into language/runtime in py/
and scheduler in _asyncio + frozen asyncio Python code.
...
Fixed the crash I mentioned in comment to PR10850.
https://github.com/adafruit/circuitpython/pull/10840#issuecomment-3968539238
A few spots to touch up:
Missing word here:
-If you're not using Mu to edit, are using or if for some reason you are not a fan of its built in serial console, you can run the serial console from a separate program.
Advanced serial console on Linux probably shouldn't be recommending screen:
Connecting ...
Have you captured the bus externally to know to see what is going on? You could check the output pad configuration too. Maybe it isn't set to output for some reason.
Unfortunately, all the traces are buried on the board. Test points next time...
I fixed a pin reset issue across many ports on the 10.1.x branch a few days ago. This is not in any release yet. Try updating to the tip of 10.1.x.
I see no difference between 10.1.2 and 10.1.3 latest.
I will say that it is much more stable on...
I see no difference between 10.1.2 and 10.1.3 latest.
Do you mean you tested 10.1.3 or the tip of 10.1.x?
I fixed these up for Windows, Linux, and Mac. On Mac, I left the screen instructions in, but caveated them, since installing tio or similar is a whole new kettle of fish for many Mac users.
You're probably aware that there is a native
i2ctargetmodule, but it has an issue currently forraspberrypiport (re: PIO I2C device in test suite). (Looking forward to async busio!)
That's an interesting option. Is clock stretching actually supported on the rp2040? I didn't see anything about it in the datasheet.
This is a list of standard ASCII glyphs with cid <0x7e that have descent value below 0.
descent: (8, (, 1)
descent: (9, ), 1)
descent: (12, ,, 2)
descent: (27, ;, 1)
descent: (49, Q, 1)
descent: (59, [, 1)
descent: (61, ], 1)
descent: (63, _, 1)
descent: (71, g, 2)
descent: (74, j, 2)
descent: (80, p, 2)
descent: (81, q, 2)
descent: (89, y, 2)
descent: (91, {, 2)
descent: (92, |, 2)
descent: (93, }, 2)
I think the ones with descent 2 are the ones that are getting the bottom pixel cu...
@tulip sleet should we always rebase our changes onto zephy main or do merges from zephyr/main?
you mean in our fork of zephyr?
yup, that we reference from cp
As long as we can find our changes, rebase is fine and makes the commits list a lot shorter
I was thinking we'd push it as our main branch and force pushing to it seems a bit weird
it does make it clear what is different though
you could make a circuitpython branch that we merge to and use as the submodule, and keep rebasing that from their upstream main.
unlike esp-idf, we wouldn't need to do circuitpython-v1.2.3, etc.
right, ok
@tannewt What's your view on compatibility? Can we allow async and non-async drivers on the same bus?
If "Yes" then the abusio module must also support blocking calls.
If "No" then every SPI or I2C driver in the circuitpython bundle must be updated to support async calls.
For now, I'd just want to test the waters with asyncio. We can worry about bus sharing later. We also need to worry about existing drivers later too.
We can publish these changes as "experimental" with the warning that the API might change in the future.
Hi @hierophect
How big of writes do you need to support? I got 576 bytes pretty easily, but I'm not sure why that's the cap. Larger transfers may require code specific to the chip (F4, F7, or H7).
I suppose six years was too long to wait
I tested both the W55RP20 and the W6300 boards. Some notes:
common-hal/wiznet/wizchip_pio_spi.chas someprintf()-statementsthat should not be thereboards/wiznet_w6300_evb_pico2/mpconfigboard.mkis missing theCHIP_PACKAGE = A(result: no valid pin for analogio)- both are very, very slow. I am just doing normal get-requests, they take an eternity. The W6300 is faster, but still very slow e.g. compared to the W5100S-EVB-PICO
- IMHO the
wiznetmodule should not be port-sp...
CircuitPython version and board name
Board: adafruit_feather_esp32s3_4mbflash_2mbpsram
Version: (10, 1, 3, '')
Build: 10.1.3 on 2026-02-20
Code/REPL
import board
import busio
import sdcardio
import storage
import os
import sys
# Print environment details for the report
print(f"Board: {board.board_id}")
print(f"Version: {sys.implementation.version}")
print(f"Build: {os.uname().version}")
# Setup
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
cs = board....
See if the build with PR10843 in the name fixes this problem: https://adafruit-circuit-python.s3.amazonaws.com/index.html?prefix=bin/adafruit_feather_esp32s3_4mbflash_2mbpsram/. If not I have some other avenues to check.
Images automagically compressed by Calibre's image-actions β¨
Compression reduced images by 40.4%, saving 2.4 MB.
| Filename | Before | After | Improvement |
|---|---|---|---|
| assets/images/boards/original/ugame-s3.jpg | 4.4 MB | 2.3 MB | 46.3% |
| assets/images/boards/original/pimoroni_explorer2350.jpg | 521.3 KB | 377.7 KB | 27.5% |
| assets/images/boards/large/ugame-s3.jpg | 203.8... |
A bisect shows this is due to #10699. I guess the copied BusDisplay SPI object is not getting deinited properly.
I was having trouble loading the build with PR10843
https://github.com/adafruit/circuitpython/pull/10843. But it sounds like
you may have isolated the problem anyway?
On Sun, Mar 1, 2026 at 1:03β―PM Dan Halbert @.***> wrote:
dhalbert left a comment (adafruit/circuitpython#10861)
https://github.com/adafruit/circuitpython/issues/10861#issuecomment-3980922970A bisect shows this is due to #10699
https://github.com/adafruit/circuitpython/pull/10699. I guess the
...
<@&356864093652516868> We'll have our weekly meeting in about 50 minutes from now in this text channel and in the circuitpython voice channel. Please take the time to add your notes in advance to the document: https://docs.google.com/document/d/1O7WLFJtB-30PoMKpC718f7xujL1zuBMFYD059GWIdZk/edit?tab=t.0 Talk to you soon!
Google Docs
CircuitPython Weekly Meeting for March 2, 2026 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you canβt make the meeting and would st...
Good
Adafruit Industries, Unique & fun DIY electronics and kits : -
I cannot hear anyone
I hear Scott.
i can hear
Last week I couldn't hear at first and had to fully close and restart discord.
That worked, thanks
I can't hear either, but I suspect my workplace is blocking it.
You can try the web vs. the app. I had to refresh the window to hear
spring forward!
Spring ahead, Fall back.
Thanks for hosting Scott, have a great week everyone.
@lone axle I wish I had the zephyr display stuff checked in for your font testing
Basic test can be done without any special code for the font. Just need to set a var in settings.toml to point to the custom font file, and then set the palette on the terminal tilegrid to use the right number and value for the colors. Bottom pixels get clipped without more changes but it's enough to check if it works generally.
Are you going to work on the changes needed to fix the clipping? What do you need my help with?
Yeah, I have local changes that resolve it. The main issue IMO is that these changes while fixing the clipping of custom fonts would also change the size that is calculated for the current default font which means it would no longer divide evenly into the Fruit Jam's display sizes.
Ideally I'm hoping to come up with a way that can fix it for custom fonts, but keep the default font at the current 16px size. That way everything default on Fruit Jam would look the same as it does today but other custom fonts would use the new measuring logic to fix the clipping and as a consequence also end up with larger line spacing (bigger vertical gap between rows).
hrm, I wouldn't special case the current font
Okay, I can have the current font use the new logic too but it will result in a bit less room for the serial terminal with the default configuration. Mostly bigger gaps between rows since the majority of glyphs don't actually use the fully allotted space.
Here is the notes document for next Mondayβs CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Check your local time if you are outside the US. The US starts daylight savings time before the meeting. Add your hug reports and status updates to the document before the meeting. If you are unable to attend but would still like to contribute, feel free to add your notes and weβll read them off during the meeting. Hope to see you there! https://docs.google.com/document/d/1fbZVEge03Sl0UyAzeAO9SpFfF3urYhs_GNY5pC2Wbec/edit?usp=sharing<@&356864093652516868>
Google Docs
CircuitPython Weekly Meeting for March 9th, 2026 Here is the notes document for next Mondayβs CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Add your hug reports and status updates to the document before the meeting. If you are unable to ...
Are you taking the bounds of all glyphs into account or some global size instead?
I have local code with both ways actually. One of them just reads ascent and descent from the header and adds them together (adjusted for negative) to get the full size.
And another approach checks the size of each glyph as it loops over them during init to track the maximum space used by any of the glyphs that get iterated.
I haven't checked yet, but if they arrive at the same answer I'm inclined to go with reading data from the header because I think it's more similar to how BitmapFont does it.
I'm not sure how the converter computes the two
Given that unifont is 8x16 or 16x16 monochrome characters I think we should make sure it stays as true 16px high. That may mean we need to hack the lvfontbin converter to work correctly though. I wouldn't try to antialias it since it isn't vector to begin with.
I bet the lvgl converter is using some rendering backend in conversion that is essentially blurring the bitmap font.
(Sorry, I was confusing this with another bug. Please ignore the above. There is an issue I am looking have to do with simultaneous use of the SD card and a display on the same SPI bus.)
I am not seeing ValueError: SCK in use. I am seeing D10 in use or the equivalent, on various boards. You mentioned that above, but then you mentioned SCK in use.
D10 in use makes sense because the SDCard object has not been deinited, either by garbage collection or explicitly. So it still holds ...
You'll need to add qspibus = false to each Zephyr boards autogen to fix the zephyr tests. There is a script in ports/zephyr/cptools that will do it too.
zephyr main PR is green
thank you!
Rework the conn_handle related functions because they are port-internal API.
@lone axle catching up on the weekly today - I can expand the patch to include the changes to .pre-commit-config.yaml - good idea!
@tannewt - done.
All tests passed.
- both are very, very slow. I am just doing normal get-requests, they take an eternity. The W6300 is faster, but still very slow e.g. compared to the W5100S-EVB-PICO
Update: With the newest code from mainline (after 10.2.0-alpha.2) the requests aren't slow anymore.
Thanks for continuing to iterate on this. I'm excited by overlapping sending pixels and computing them.
I canceled the workflow to save CI time. The zephyr test did pass.
Looks clean, just some name style suggestions.
CircuitPython version and board name
Adafruit CircuitPython 10.2.0-alpha.1 on 2026-02-18; Adafruit Fruit Jam with rp2350b
Code/REPL
print(chr(0x961))
Behavior
Only the left half of the glyph is shown in the serial Terminal.
The full glyph can be seen here: https://symbl.cc/en/0961/ and smaller in my terminal to the left of the display screencap
Description
No response
Additional information
This is the font used: https://github.com/...
This PR has 3 fixes for lvfontio.
- Fix
header.default_advance_widthfrom getting set to the wrong value. With Unifont 8x16/16x16 font the value of this was ending up as4which caused the right half of full-width glyphs not to render properly. Resolves: #10864. Fixed by ignoring zero advance glyphs win inferring the cell width. - Fix a call to f_read() with
NULLlast parameter. The LLM suggested this fix without explicit prompt while working on this file. I am unsure about it, but...
@slender iron in https://github.com/adafruit/circuitpython/pull/10607#discussion_r2320342842 you mentioned avoiding MP_WEAK by using a #define instead. I was looking for an existing example of that. I am thinking of adding a new common_hal_busio_spi_wait_for_lock() function that would be the same on all ports except espressif. Was thinking of a flag like CIRCUITPY_BUSIO_SPI_WAIT_FOR_LOCK_PORT_SPECIFIC but I don't know if that's the kind of thing or name you were thinking of.
I think that'd be fine. The goal is to only have one to link against. Otherwise you risk accidentally linking against the weak version
With lots of help from claude I managed to get a core stack trace with debug probe.
stacktrace:
#0 0x10094560 in __reset_into_safe_mode_veneer ()
#1 0x10001b36 in gc_alloc (n_bytes=n_bytes@entry=24,
alloc_flags=<optimized out>) at ../../py/gc.c:930
#2 0x10000f3a in m_malloc_helper (num_bytes=num_bytes@entry=24,
flags=flags@entry=4 '\004') at ../../py/malloc.c:103
#3 0x10000f68 in m_malloc_maybe (num_bytes=num_bytes@entry=24)
at ../../py/malloc.c:133
#4 0x10010374 in m...
Ah! If it is the missing space, then we should check for space before committing to the custom font. We can fallback to the built in font if space is missing.
Thanks for working on this! Just a couple of things.
I believe the font does have a space glyph. As a quick test I tried the same font file with BitmapFont / DisplayText and it can render a space just fine.
The first pair of letters have space between, and the second pair do not. The terminal output also shows that the data in the resulting bitmap does contain empty pixels where the space is at.
<img width="924" height="599" alt="Image" src="https://github.com/user-attachments/assets/93cec510-f171-4cdf-b71b-032300bdfab1" />
Font Forge seems t...
CircuitPython version and board name
adafruit-circuitpython-sparkfun_stm32f405_micromod-en_US-10.1.3.bin
Code/REPL
n/a
Behavior
n/a
Description
See this forum thread:
https://forums.adafruit.com/viewtopic.php?t=222853
Loading the 10.1.3 bin file causes no CP USB drive to be visible.
The bin file appears to be unusable.
Installing the bin file for CP 10.0.3 for the same board was successful.
Additional information
No response
Ok, I've got a better idea of how this works and think there are just a couple small tweaks to make to simplify things. Thanks!
Thank you, @tannewt, for your professional approach. I learned a lot during this PR :)
I think this can be closed as we have ample audioeffects now that can be plugged into AudioMixer!
CircuitPython version and board name
Adafruit CircuitPython 10.1.2-14-gf75864d25f on 2026-03-03; Adafruit PyGamer with samd51j19
Adafruit CircuitPython 10.1.3 on 2026-02-20; Adafruit PyGamer with samd51j19
Adafruit CircuitPython 10.0.1 on 2025-10-09; Adafruit PyGamer with samd51j19
Code/REPL
import time
import board, digitalio
import displayio
import audiocore, audiomixer, audioio
displayio.release_displays() # just in case
SAMPLE_RATE = 22050
CHANNEL_COU...
This adds zephyr_display. It acts similar to BusDisplay because we write regions to update to Zephyr.
We have made great headway with audio effects, and I agree that this can be closed. But there are still a few potential effects which I could see us adding in the future:
- Flanger (Although, I think this can be achieved with the
audiodelays.Echoeffect andsynthio.LFOmodulation) - Compressor
- Limiter
This adds two tracks "Outer Heap Used" and "VM Heap Used" to the output perfetto trace.
Hi @tannewt
Did you try your C implementation of awaitables?
Those changes are made in the latest commit. Updated both spots with modulo logic for wrapping, and changed the structure of the if statement for clarity.
Thanks for the updates. Approving in anticipation of a successful build.
I'm currently thinking it's related to this commit fd2627c that added the very nice mono-to-stereo conversion.
@relic-se would you be able to look at this?
@dhalbert Yes, I'd be happy to dive into the code and @todbot and I have already discussed the problem a bit, but I don't have any SAMD specific hardware to test with.
I have SAMD hardware I can test on if you need. I think I looked at the SAMD specific audio code way back. Ping me here/discord if you need.
[adafruit/circuitpython] New comment on pull request #10870: Translations update from Hosted Weblate
@tannewt there is a zephyr build failure here, not merging yet in case you want to look at it.
CircuitPython version and board name
CircuitPython versions tested: 10.0.3, 10.1.3
Hardware: Adafruit Metro RP2350 (RP2350B)
Code/REPL
import board, rp2pio, adafruit_pioasm, microcontroller, gc, time, digitalio
microcontroller.cpu.frequency = 252_000_000
vga_program = adafruit_pioasm.assemble("""
.program vga_rgb_hsync
.side_set 1
.wrap_target
set y, 15 side 1
pixel_loop:
out pins, 8 side 1 [1]
out pins, 8 ...
A number of *_make_new() functions were calling mp_obj_alloc() or mp_obj_alloc_with_finaliser() before all the argument validation was done. For objects with finalisers which had a validation exception, this meant that a discarded object in a bad state might have a finaliser called on it. For non-finaliser objects, it just mean that garbage was generated.
The general guideline is to allocate as late as possible before the call to *_construct().
Fixing this after diagnosing a spe...
@slender iron if you have time, I have a fairly brief thing to discuss with you re user-created SPI buses used for displays.
Follow-up: corrected test files and updated results
The original report used a solid 0xFF buffer. Due to the 2-bit Red channel in our resistor DAC the output is never pure white, making it hard to distinguish correct output from corruption. Replacing with SMPTE colour bars (8 clearly distinct colours) gives cleaner results. The two standalone test scripts below are the revised versions.
Confirmed working β 150 MHz, CircuitPython 10.0.3
VGA Video OK 150MHz.py β deplo...
Root cause analysis and potential fixes
I've been investigating this while building a VGA signal generator on Metro RP2350 (background_write(loop=full_frame) streaming 168,000-byte framebuffers to a PIO state machine at 25.175 MHz). The failure mode at CPU clocks above ~150 MHz is consistent with PIO TX FIFO starvation during the DMA loop restart.
Why it starves:
The SM pulls one byte from the FIFO every 2 SM cycles (~79 ns at 25.175 MHz). With a 4-entry TX FIFO and
pull_thres...
[adafruit/circuitpython] New comment on pull request #10870: Translations update from Hosted Weblate
@tannewt there is a zephyr build failure here, not merging yet in case you want to look at it.
This one test! I've tried and tried to make it reliable and it still isn't. I reran it.
Potential fix sketch (Claude Code analysis β unverified, for core developer reference)
The following is an AI-assisted code analysis suggesting how the bug might be fixed. It has not been tested or verified and is offered only as a starting point for developers familiar with the codebase.
Option 1: FIFO join β may already be usable with no code changes
fifo_type is already a StateMachine() parameter. Passing fifo_type="tx" maps to PIO_FIFO_JOIN_TX, joining the unuse...
@dhalbert - hopefully this chain is not too scattered, I've looked to refine the issue and in the last post review the rp2pio code to suggest core changes that I myself am not familiar enough to suggest but that a core developer might better see what's going on. Again it's my understanding the PicoDVI implementation uses the chained DMA method to have video written out without stall. At stock clocks I could do it with one DMA channel. Above 640x480 pixel doubled, it needs the additional ump...
Test result: Option 1 (fifo_type="tx") does not fix the issue
Hardware tested: Adafruit Metro RP2350, CircuitPython 10.0.3, 252 MHz system clock.
Added fifo_type="tx" to the StateMachine() call in the broken 252 MHz test file. The parameter is accepted without error and the code runs cleanly:
VGA bug report β 252 MHz with fifo_type='tx' mitigation
CPU: 252 MHz
Free memory: 147488 bytes
PIO: 25,170,503 Hz HSYNC: 31 kHz
Screen should show SMPTE colour bars β testing fifo_type=...
Looks good to me! Thanks!
Hi @tannewt Did you try your C implementation of awaitables?
I haven't gotten around to it. Sorry! I may have time to try it next week.
Very close. One other cleanup to do.
Has anyone tried pinning tasks on esp32 or rp2x in a circuitpython build?
It might be useful for things like jpeg encoding, ulab, bitmapfilter, or audiofilters
I guess Zephyr will solve this for ESP32 but not rp2x
Do we have a Zephyr ESP32 build??
If I understand correctly, CircuitPython uses the second core for USB. USB is pretty timing sensitive, so while it might be possible to throw something else on the second core with USB, doing in a way that keeps the USB stable is not a trivial task.
If you want to use the other core for your own purposes, I've heard that MicroPython has support for that. That might be better suited to your needs, if you want to toss any of the tasks in your list over the second core. (I'd love to be able to use the second core for rendering, but all of my use cases also require USB, so that's not really an option. Maybe the next one in the RPx line will have four cores...)
Do you mean the second core on Espressif chips? It's used for WiFi. The USB task runs on the same core as CircuitPython.
adding xteink x4 ereader board. uses an esp32-c3 and ssd1677 eInk display
WiFi is already pinned to the second core? Thatβs fine then
atmel-samd SPI objects were not being deinited properly. The clock pin was set to NO_PIN prematurely, and the pin The second time this program ran, after a ctrl-C and restart, it would stop with SCK in use.
It has to be being used by a FourWire; just creating spi does not provoke the bug. FourWire makes the SPI bus pins "never reset", and the "never reset" state was not being cleared.
import board
import busio
import displayio
from fourwire import FourWire
impor...
The specific lines to change are:
https://github.com/adafruit/circuitpython/blob/89a726e41760888d1e6dab2292d85cb730120620/shared-module/displayio/__init__.c#L204-L205
I tested making this change while debugging something else, and there was some missing code further down I will include the fixes in a PR I'm working on to fix some display and SD card things.
An update to the behaviour noted in this ticket following update to 10.1.3. When the device is first powered-up, either via connection to computer USB (so SD mount included) or just via power outlet, behaviour noted above still observed. I have found, though, that if I am persistent, and keep trying the NTP and JSON connections, that I am eventually successful. Can take several tries to get successful connections, though. Once I get a successful NTP or JSON connection, I no longer get any...
I am attempting to build CircuitPython for the Raspberry Pi Pico 2 with the 1-second startup delay disabled, which requires enabling a specific compile flag (CIRCUITPY_SKIP_SAFE_MODE_WAIT). However, the build process does not appear to be clearly documented (unless I have missed something). Could the team either:
- Provide pre-built releases with this flag enabled, or
- Offer clearer documentation or guidance on how to build the firmware with custom compile flags?
Any assistance would ...
CircuitPython version and board name
Adafruit CircuitPython 10.1.3 on 2026-02-20; Adafruit-Qualia-S3-RGB666 with ESP32S3
Board ID:adafruit_qualia_s3_rgb666
Code/REPL
Paint demo at https://learn.adafruit.com/adafruit-qualia-esp32-s3-for-rgb666-displays/circuitpython-touch-display-usage
Behavior
After activating the touch sensor (do some finger painting), leave the touch sensor alone for about one minute. The touch sensor will start recording touche...
Closing for now, but happy to reopen as needed. I am working on some other issues with SD card support and there will be some fixes soon.
Have you seen https://learn.adafruit.com/building-circuitpython ?
Thank you, I hadn't noticed this before.
Thanks Dan,
Sounds good. I don't think the issue was related to D10 specifically,
though I was using that since the adalogger defaults to D10 on the esp32-s3
feather. I've since switched to D12 as my project only has that pin
available.
I just wrote my code with a workaround as there seems to be issues with
initializing and using an sd card twice in one session, so I just had to
be careful about only calling it up once. I'd be happy to post some of my
new code if you would like m...
<@&356864093652516868> weekly public meeting is in about 1 hr 45 min, at 2 pm US ET / 11 am US ET. Note that US went to Daylight Saving Time early yesterday, so those outside the US, recheck the time.
No, but you should be able to do west -b in the zephyr port with any zephyr supported board and it'll do its best.
@tulip sleet we can hear you
I admire your patience :)
Thank you very much for your time and professional insights.
@tulip sleet a few of us spoke but seems like you do not hear.
i am going to reboot
@danh I spoke but seems like you still don't hear
I started working on Circuit Studio an IDE for CircuitPython built on top of the Rovari platform that features things like error highlighting, library manager, and safe writes for CircuitPython. It's built from the ground up for circuitpython development. Here are some of the features
-- Full Desktop Offline
-- Error line highlighting: noth...
thanks for hosing Dan, have a great week everyone π
Thanks all!
@lone axle I could use your backup recording; there was an input problem until I changed some settings partway through. Thanks - I'm very grateful.
all set - you can delete now - thanks!
Automated website update for release 10.1.4 by Blinka.
Merge #10843, #10872, #10874 from 10.1.x into main.
#10872 in particular made small changes to many files, so that's why so many are changed in this PR as well.
This fix is now released in CircuitPython 10.1.4.
CircuitPython 10.1.4 Released!
https://blog.adafruit.com/2026/03/09/circuitpython-10-1-4-released/
Highlights of this release:
- Fix pin-reset regression which caused display problems on some boards.
- Fix object creation and deinitialization problems, most notably when SPI was used for displays on SAMD.
Weird behavior of Build CI - it fails for two boards.
I did compile both of them on my PC and both are fine...
Are there any optimizations that circuitpython makes when accessing variables? For example if self.foo is accessed multiple times in a method or loop, will it create a temporary record on the stack, or will it look it up each time?
circuitpython code is not executed line-by-line, it's first compiled to bytecode, which looks a bit like assembly language, and that is executed in a vm
the compiler might do all kinds of optimizations, but I'm not aware of it doing the particular optimization you mention
you can read about the passes the compiler does here https://docs.micropython.org/en/latest/develop/compiler.html#compiler-passes
That optimization is normally performed by the CPU cache, not the compiler
PYthon allows you to change the object dict at runtime, so theoretically you have to do a lookup each time. __slots__ avoids this in CPython, but is not implemented in CircuitPython/MicroPython: https://github.com/adafruit/circuitpython/issues/10517
So, it seams that no, this isn't. And yes that's what I'm doing now, but wanted to make sure it was needed.
Thanks for all those links. Super helpful
it does help, but it's worth doing a little benchmarking to see how much it helps. In a loop of many iterations, it could make a significant difference
yeah, I'm specifically looking at loops (either in the class, or that are called in code)
CircuitPython version and board name
Adafruit CircuitPython 10.1.3 on 2026-02-20; micro:bit v2 with nRF52833
Code/REPL
Ctrl+C (in serial connection)
Behavior
micro:bit v2 does not respond to Ctrl+C, even though the action was sent.
Description
- When the Ctrl+C signal is sent to the micro:bit v2, the yellow data LED blinks, but nothing else happens
Additional information
Putting the micro:bit v2 into safe mode interrupts it.
[adafruit/circuitpython] New comment on issue #10878: micro:bit v2 does not support Ctrl+C interrupt
Which serial program connection are you using, on what operating system and version?
[adafruit/circuitpython] New comment on issue #10878: micro:bit v2 does not support Ctrl+C interrupt
I have tried both PuTTY and Thonny on Windows 11. Neither of them have been able to interrupt the micro:bit.
[adafruit/circuitpython] New comment on issue #10878: micro:bit v2 does not support Ctrl+C interrupt
Also, for Windows, do mBed-running devices need USB drivers?
Now it's ok. Some caching issue?
[adafruit/circuitpython] New comment on issue #10878: micro:bit v2 does not support Ctrl+C interrupt
Also, for Windows, do mBed-running devices need USB drivers?
No, that should not be necessary for Windows 10 and later. Windows 10 came with a universal USB CDC driver.
[adafruit/circuitpython] New comment on issue #10878: micro:bit v2 does not support Ctrl+C interrupt
I reproduced this with tio and also with Thonny. I also went all the way back to the first build we have: https://adafruit-circuit-python.s3.amazonaws.com/bin/microbit_v2/en_US/adafruit-circuitpython-microbit_v2-en_US-7.0.0-alpha.5.combined.hex, and it does not work for that build either. So it never worked (!). I tried various builds in between as well.
[adafruit/circuitpython] New comment on issue #10878: micro:bit v2 does not support Ctrl+C interrupt
I looked at this a little bit and this is not something that is just a bug that is easy to fix. The REPL console is supported by sending data over a busio.UART() internally. There is no support right now to monitor that connection for ctrl-C interrupts asynchronously.
Espressif boards that use special serial console connections (CIRCUITPY_ESP_USB_SERIAL_JTAG boards like ESP32) do this differently, and have an interrupt handler for incoming UART bytes that checks for ctrl-C.
It would be ...
CircuitPython version and board name
n.a.
Code/REPL
n.a.
Behavior
see below.
Description
Running
git describe --tags
10.1.2-105-g35de08db7e
on main is a bit surprising. I did fetch the new tags (make fetch-tags) and I can see newer tags like 10.1.3 and 10.1.4, 10.2.0-alpha.2.
This generates the wrong CircuitPython version number when compiling the current main branch (in my case "10.1.2-20-g35de08db7e").
Additional informa...
I was hoping for this! @dhalbert Any reasoning this hasn't been picked up?
This will be in the Zephyr port that @tannewt is working on.
Being able to easily play WAV files with audiocore.WaveFile is amazing,
but there's no way to change the playback speed of the WAV playback.
If WaveFile had a .rate property that could be adjustable in real-time,
it opens up many creative / musical uses:
- "ROMpler" sample player keyboard (single sample repitched across a key range)
- Drum loop BPM matching
- Tuning drum samples for drum machines
- Fun dynamic pitch effects for recorded audio
The WAV repitch algorithm can be pretty ...
This adds support for adjustable playback speed / rate to audiocore.Wavefile,
addressing issue #10881.
Tested on the following platforms: RP2040, SAMD21, SAMD51. Specifically:
| Device | Size change | Percent used change |
|---|---|---|
raspberry_pi_pico RP2040 |
925256 to 925856 | 88.59% to 88.64% |
qtpy_m0_haxpress SAMD21 |
251760 to 252280 | 99.24% to 99.44% |
pygamer SAMD51 |
491932 to 492380 | 98.44% to 98.53% |
(numbers are ...
CircuitPython version and board name
Adafruit CircuitPython 10.2.0-alpha.1 on 2026-02-18; Adafruit QT Py ESP32S2 with ESP32S2
Code/REPL
import displayio
import bitmaptools
displayio.release_displays()
# Load the seconds hand BMP
sec_bmp = displayio.OnDiskBitmap("red_second_hand.bmp")
# Full-size canvas β affordable with PSRAM
canvas = displayio.Bitmap(240, 240, 2)
canvas_palette = displayio.Palette(2)
canvas_palette[0] = 0xFF00FF # magenta = transparent...
I do believe this is indeed caused by wrong type being passed to rotozoom(). It doesn't seem to do validation of the type at all. Passing an unrelated type produces the same hard crash sec_bmp = digitalio.DigitalInOut(board.A0)
From the code It looks like both source and dest bitmaps have the same issue but I have only confirmed source.
The Zephyr port will have our regular displayio to start with. I have a branch with LVGL-based displayio but I haven't reviewed it. I wasn't planning on adding extra APIs for LVGL specifically.
Resolves: #10883
Adds type validation to rotozoom() and a few other places inside bitmaptools functions where it was not handled.
A bunch of the builds failed for weird non-PR reasons. ( Error: The process '/usr/bin/git' failed with exit code 128 in the "Set up repository" step)
Is this my fault? I don't think so. Seems like github in general is having issues.
How does this approach compare to having a separate class that would take in any sample and do this? That'd apply to mp3 then too.
Is this my fault? I don't think so. Seems like github in general is having issues.
I doubt it. We can rerun when we're closer. I replied on the issue (#10881) about approach.
@dhalbert This was mistakenly done on the wrong branch right? We could tag another 10.2 on main.
How does this approach compare to having a separate class that would take in any sample and do this? That'd apply to mp3 then too.
I had initially investigated it and thought it may not work correctly for looping WAVs and cause too much increase in code size. I'll look at it again and report back.
Code size will be easier since we can omit it for small boards.
Right, 10.1.2 was tagged on main by mistake. I didn't delete the tag at the time, but I did just now. You can delete the tag locally to fix that: git tag -d 10.1.2.
I've been looking into switching over to containers but don't think it's worth it now. So, I'm going to close this issue but have my reasoning here for future reference.
The core issue is that CircuitPython's source tree mixes dependencies into the source tree using submodules. We do this to fix our versions of the deps in the relevant place of the tree. When containers mount the active source to work on into the container, they shadow everything in that part of the filesystem. This makes it...
I'm going to close this because it currently looks fine for most boards. If they want to see the full image, they can go to the board page.
Okay I made a audiocore.SpeedChanger module that works with any audio source. And looping of WAVs works correctly.
Looks like it adds 1.5kB to a RP2040 build and needs ~40 bytes + a 512 byte buffer RAM.
This is compared to 600 bytes and 8 bytes of extra RAM of the WaveFile only impl.
It's a LOT of fun. Doing turntable-like effects on an MP3 is pretty dope.
CircuitPython version and board name
Adafruit CircuitPython 10.1.3 on 2026-02-21; Wemos Lolin C3 Mini with ESP32-C3FH4
Code/REPL
import asyncio
import wifi
import socketpool
import ssl
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import usyslog
BROKER = "192.168.0.1"
MQTT_PORT = 1883
MQTT_TOPICS = [
"inverter/total/P_AC",
"battery/1/relay/set",
"battery/2/relay/set",
]
sl = usyslog.UDPClient(socketpool.SocketPool(wifi.radio), ip='1...
That's awesome! I'd just make a new module for it instead of putting it in audiocore. I'd definitely go this direction. Thanks!
This PR aims to improve SDCard-over-USB handling, and sharing an SPI bus with other devices, including a display. The fixes prevent some crashes, hangs, and intermittent errors. I'll go through the relatedissues later and close those that seem like they were fixed by this; for some it is a bit hard to tell and will require some more testing.
MP_WARN_UNUSED_RESULT added
- in
py/mpconfig.h, I addedMP_WARN_UNUSED_RESULT, which expands to__attribute__((warn_unused_result)). A...
I think something upstream there is broken temporarily. Also githubstatus.com is showing degradation for CI due to download failures
A couple minor things. Overall, it looks good. Thanks for getting into these weeds!
FYI this PR is hung up because the zephyr apt-get installs work on the 3/2 runner image but not the 3/9 image. I'm trying to determine why that is and how to work around it.
This warning just started showing up in builds:
Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected: actions/cache/restore@v4, actions/checkout@v4, actions/setup-python@v5, actions/upload-artifact@v4, carlosperate/arm-none-eabi-gcc-action@v1. Actions will be forced to run with Node.js 24 by default starting June 2nd, 2026. Please check if updated versions of these actions are available that support Node.js 24. To opt into Node.js 2...
Is it expected behavior that the following actions will result in "locale/circuitpython.pot" having changes?
git checkout main
git pull
make translate
...
git diff
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index bf4c5d110f..09371d2a6a 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -113,6 +113,7 @@ msgstr ""
#: ports/espressif/common-hal/espulp/ULP.c
#: ports/espressif/common-hal/mipidsi/Bus.c
+#: ports/espressif/common-hal/qspibus/QSPIBus.c
#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c
#: ports/mimxrt10xx/common-hal/usb_host/Port.c
#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c
@@ -856,8 +857,7 @@ msgstr ""
msgid "Coordinate arrays types have different sizes"
msgstr ""
-#: shared-module/usb/core/Device.c
-#: ports/espressif/common-hal/qspibus/QSPIBus.c
+#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-module/usb/core/Device.c
msgid "Could not allocate DMA capable buffer"
msgstr ""
[and a few more changes]
oh! Scott's livestreaming sorry. I'm not able to watch. I'll ask later
Tried with 10.1.4. Same crashes as with previous 10.x versions. Now crashes to safe mode immediately when spi = board.SPI() used and apds = APDS9960(i2c) enabled (see above). Same "SCK in use" error when spi = busio.SPI(board.SCK, board.MOSI, board.MISO) used.
A new feature to these failure modes is that if I use spi = busio.SPI(board.SCK, board.MOSI, board.MISO) and include a wifi and ntp connection, the script immediately crashes to safe mode when attempting to make the ntp conn...
Call displayio.release_displays() near the top of the program, before creating the SPI object. Otherwise you will be competing with what the display is holding on to.
Thank you @dhalbert . Moving displayio.release_displays() up to before the SPI object creation seems to have fixed the "SCK in use" issue. Still get immediate crashes to safe mode, though.
Are you getting the safe mode crashes only some of the time?
Does it happen after a hard reset or power-cycle, or does it only happen after a ctrl-D restart?
I only got a safe mode crash once.
I want to confirm that this is really an 8MB flash / no PSRAM QT Py ESP32-S3 as opposed to the 4MB flash / 2MB PSRAM version. Physically the only way to tell is by the part number on the Espressif chip: https://learn.adafruit.com/adafruit-qt-py-esp32-s3/pinouts#esp32-s3-chip-3119656. See the photos th...
First the chip confirmation. Inspected the ESP32-S3 chip and it has the "FN8..." part number.
To verify the behaviour I did two sets of tests:
Connected to computer USB:
- With the test code above, runs correctly at connection. Successive ctrl-D restarts also succeed until about the 5th or 6th attempt, at which point the board crashes to safe mode and drops the USB mount.
- With a version of the test code where I add a wifi and ntp connection, the board always crashes to safe mode at con...
Could you try https://adafruit-circuit-python.s3.amazonaws.com/bin/adafruit_qtpy_esp32s3_nopsram/en_US/adafruit-circuitpython-adafruit_qtpy_esp32s3_nopsram-en_US-20260313-main-PR10887-d1255a5.uf2 ? This incorporates PR #10887, with a number of USB SDCard improvements.
Host computer OS: Raspbian GNU/Linux 11 (bullseye)
Tried your 10.2 alpha uf2 and both of my test scripts ran flawlessly, even with 20+ ctrl-D reloads. Yay!
I then ran my full-up script that uses wifi, ntp, and loads images from the SD card (description with some pictures, but no code yet, at https://jmangum.github.io/fun/BedsideClock/). The project script runs fine, with no crashes. The image loading is significantly slower than before, though. Takes about 10-15 seconds to load an image...
I can post a new issue for the slow bitmap loading if appropriate.
Glad to hear that it solves the crashes!
How is the image loading speed if you are not connected to the host via USB? How fast was the image loading when it was crashing :) ?
Hmmm. Tried to get the project to run by connecting to power-only USB. Did not display an image at all. I could see the board boot, but nothing on the display. No blinking LED on the board which would indicate that the script has crashed. Tried hitting the reset button on the board, but that yielded the same behaviour. Just could not get the project to run on power-only USB, and also no indication that the script had crashed. Waited about 10 minutes before giving up. Seemed to be just...
Thanks, that is a helpful pointer to what sounds like a bug. The retry logic in SDCard changed a lot.
...associated with the following code block...
Does this sample code have the release_displays() moved up? What happens if you use board.SPI() instead?
Yes, displayio.release_displays() is the first command after importing libraries and defining some async functions.
Tried spi = board.SPI() with a couple of different starting points:
- With board still connected to computer USB (and running project from earlier), made code.py change and reloaded. Ran fine and loaded image properly, but still took 15-ish seconds to load image. Code did a spontaneous auto-reload, and again ran fine, but with a rather long (30-ish second) image load ti...
It would be nice I I could could program my Pi Pico 2W without needing a computer, but at the moment it only supports the web editor.
I'll mark this as a duplicate of #7693. Feel free to add comments there.
Here is the notes document for Mondayβs CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Add your hug reports and status updates to the document before the meeting. If you are unable to attend but would still like to contribute, feel free to add your notes and weβll read them off during the meeting. Hope to see you there! <@&356864093652516868>
https://docs.google.com/document/d/1GeBRhF1Mp4S-fEACLCzU_XVjj7yNxlFZuYesaJ1g9Rw/edit?usp=sharing
<@&356864093652516868> the weekly meeting will occur here in #circuitpython-dev at normal time 2pm US Eastern / 11am Pacific. About 90 minutes from now. Add your hug reports and status updates to the notes doc if you'd like to participate https://docs.google.com/document/d/1GeBRhF1Mp4S-fEACLCzU_XVjj7yNxlFZuYesaJ1g9Rw/edit?usp=sharing. We look forward to hearing from any who can attend.
Google Docs
CircuitPython Weekly Meeting for March 16, 2026 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you canβt make the meeting and would st...
The CM0IQ is a compact carrier board designed for the Raspberry Pi CM0 compute module and measures 42 Γ 36 mm, placing it among the smallest boards built around the platform. The design exposes several interfaces typically associated with larger Raspberry Pi boards while maintaining a minimal footprint. The board is based on the Raspberry [β¦]
I think that's a very common issue in CP native code
thanks for hosting!
Thanks everyone, have a great week π
Here is the notes document for next Mondayβs CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Add your hug reports and status updates to the document before the meeting. If you are unable to attend but would still like to contribute, feel free to add your notes and weβll read them off during the meeting. Hope to see you there! <@&356864093652516868> https://docs.google.com/document/d/10W0TOyUCAml9Tc6jSNZa5mgK05YGfCPuexfbpSFLteE/edit?usp=sharing
Google Docs
CircuitPython Weekly Meeting for March 23, 2026 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you canβt make the meeting and would st...
I don't seen to be able to pin/unpin messages currently. When I try to unpin previous meeting message it gives this fairly unhelpful error message. When I open the context menu on the new meeting message I don't see the "pin message" action in there like I would normally. Not sure if Discord made some change to permission behavior under the hood or if this is just a temporary issue, will try again in a while.
I'll try
worked for me. not sure if it is a permission thing or just a client issue
Can I grab someone to re-review/merge this as it's been mentioned as released in this weeks python newsletter. https://github.com/adafruit/circuitpython/pull/10778
GitHub
Tested buttons, i2c, gpio0-5, display and speaker.
I'll stick up a board page on circuitpython-org at some point soon.
Otherwise it's https://shop.pimoroni.com/products/explorer?var...
I'll look now
Thanks Scott 
np, feel free to ping me whenever something isn't getting a response but you are waiting for one
anything longer than 24 hours (assuming it is over a business day)
[adafruit/circuitpython] New comment on issue #10888: Update CI actions to versions that use Node.24
A PR is open for the update in carlosperate/arm-none-eabi-gcc-action here. If accepted, no version bump will be required on your end, and https://github.com/carlosperate/arm-none-eabi-gcc-action/issues/86 will be closed.
In case it helps, actions/upload-artifact and actions/download-artifact seem to be safe to bump from v4 to v6, my org just did without breaking our CD. I can't personally confirm anything about cache...
CircuitPython version and board name
Adafruit CircuitPython 10.1.2-16-ga2532bd537-dirty on 2026-03-04; Adafruit Fruit Jam with rp2350b
Code/REPL
import adafruit_lis3dh
import board
import digitalio
from adafruit_debug_i2c import DebugI2C
i2c = DebugI2C(board.I2C())
int1 = digitalio.DigitalInOut(board.D8)
accelerometer = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1)
print(accelerometer.acceleration)
for i in range(2):
print(accelerometer.ac...
Does it work if you add probe() to DebugI2C?
I'm not really sure what should be inside the implementation of probe() I tried adding a blank function to DebugI2C:
def probe(self):
pass
And it raises a different exception that points to the same line where I2CDevice gets created:
ode.py output:
Traceback (most recent call last):
File "code.py", line 35, in <module>
File "/lib/adafruit_tcs3430.py", line 258, in __init__
TypeError: function takes 1 positional arguments but 2 were given
Code done running.
...
I have realized that board.I2C() is the object that actually does have probe(). And of course it has it regardless of whether python or core implementation of adafruit_bus_device is used.
I think the thing causing the difference in behavior is that the core implementation is seemingly trying to load the method probe() here: https://github.com/adafruit/circuitpython/blob/39597dc72688e28a6532bd929eca4f461823f62c/shared-module/adafruit_bus_device/i2c_device/I2CDevice.c#L45
But the pytho...
Is anyone else having their GitHub Actions running crawling and not starting jobs? It says I'm at my job concurrency limit but that doesn't appear to be true as far as I can tell.
check you actions tab for other stuff running
The return type List[int] and declared :rtype: bool in the docstring differ.
This changes the type annotation to match the correct type bool
Confirmed proper type in REPL:
>>> board.I2C().try_lock()
True
>>> board.I2C().probe(0x39)
True
I didn't see anything in that repository, so maybe it was something else under my account? Seems to have resolved now.
But I do finally have a prototype for the imported memory analysis: https://github.com/adafruit/Adafruit_CircuitPython_ImageLoad/pull/104
CircuitPython version and board name
Adafruit CircuitPython 10.1.4 on 2026-03-09; Adafruit Feather ESP32-C6 4MB Flash No PSRAM with ESP32C6
Code/REPL
# No code changes
Behavior
Not a code issue
Description
I have several (4) Adafruit Feather ESP32-C6 and all of them exhibit the same behavior: the WiFi is unusable and very flaky with all versions of CircuitPython >= 10.1.
I have tried 10.0.1 (good), 10.0.3 (great), 10.1.1 through 10.1.4 (...
I am having this issue is there a solution now ?
Nice! I think it is across all of your repos
This includes the following:
adafruit_tinychad_rp2350
native_native_sim (hidden)
nordic_nrf54h20dk (zephyr)
nxp_frdm_mcxn947 (zephyr)
nxp_mimxrt1170_evk (zephyr)
st_nucleo_n657x0_q (zephyr)
yoto_mini_2024
yoto_player_v3
When using Circup, when the version of CP is out of date, the URL to the board's download page on CircuitPython.com displayed by Circup is determined by
if board_id:
url_download = f"https://circuitpython.org/board/{board_id}"
(source: https://docs.circuitpython.org/projects/circup/en/stable/_modules/circup.html#Module)
and currently the board_id and URL do not match.
Correct URL for this board is https://circuitpython.org/board/seeed_xiao_esp32s3_sense/ so the bo...
The board_id should match the board in CircuitPython: https://github.com/adafruit/circuitpython/tree/main/ports/espressif/boards/seeed_xiao_esp32_s3_sense
So, I think the file name is incorrect and should be changed to seeed_xiao_esp32_s3_sense.md
The board_id should match the board in CircuitPython: https://github.com/adafruit/circuitpython/tree/main/ports/espressif/boards/seeed_xiao_esp32_s3_sense
So, I think the file name is incorrect and should be changed to seeed_xiao_esp32_s3_sense.md
Change the file name but leave the ID change as I have it?
FWIW, I have been seeing similar issues with a FeatherS3. 10.0.3 code running great and subsequent 10.1.3 and .4 upgrades make for a super slow startup and inability to connect to wifi.
...
The next step would be to load a DEBUG=1 build to see if you can get a backtrace during the crash.
Are you able to provide some pointers here? I'd prefer to avoid having to build micropython if that's possible.
Added pin definition "GP29" and "GP29_A3" for the ADC3 pin.
Are you able to provide some pointers here? I'd prefer to avoid having to build micropython if that's possible.
It'd involve building CP.
What wifi routers are you both using? I feel like I saw this at my house with Ubiquiti but not at my office with a CenturyLink provided router.
Expands all 31 amzn.to affiliate shortlinks across 30 board/blinka files to direct amazon.com/dp/ASIN URLs.
What changed:
- Every
amzn.to/XXXXXβhttps://www.amazon.com/dp/ - Removes tracking parameters, affiliate tags, and query strings
- Consistent minimal URL format
Files: 20 in _blinka/, 10 in _board/
cc @ladyada
No, please leave it as it originally was. Otherwise it would be different from the one in circuitpython, which causes duplicate boards to appear.
But the problem is that Circup generates the URL for that board over at circuitpython.org using the board_id. If I leave the ID as is, then it does not fix the problem I am reporting. Currently circup generates an invalid address of where to go to get the latest version of CP for that board.
Alternatively someone could change the URL for that board at circuitpython.org but then that may break bookmarks and embedded web page links.
Alternatively someone could change the URL for that board at circuitpython.org but then that may break bookmarks and embedded web page links.
Changing the filename will change the URL at circuitpython.org and that's fine.
Can this just be installed via the USB-C on the device?
FYI: Installed 10.1.4 and see same behaviour.
@alistair23 I do not think it can. The guide here: https://learn.adafruit.com/hacking-the-yoto-music-players/building-a-serial-programmer-breakout Mentions this:
The Yoto Mini does not have a USB to serial converter chip to access the ESP32 via USB. However, it does have the programming pins broken out at the top edge of the PCB. To make uploading firmware easier, you can solder together a quick programmer breakout.
[adafruit/circuitpython] New comment on issue #10888: Update CI actions to versions that use Node.24
carlosperate/arm-none-eabi-gcc-action@v1 has been updated, thanks @ETSells!
Ah I didn't realize the file name here was directly linked to the URL. I am trying to figure out how to revert the previous change of the board_id but I can not figure out how to revert it. I'll keep poking.
tannert, two things. I think I found the bug in my code where I was continously polling a webserver and this was causing dropped connections or difficulty reconnecting. things work a lot better now. router is googleWifi mesh.
Espressif just release IDF 6.0 so I'm trying to update to it. (via Claude) I'm curious to see if these wifi issues are fixed by it.
Just change it back in your code, change the filename and then commit and push the changes.
Adds a new board-level module mtm_hardware with a DACOut class that provides non-blocking audio playback through the slightly strange MCP4822 dual-channel 12-bit SPI DAC on the Music Thing Modular Workshop Computer.
DACOut follows the same API as audiobusio.I2SOut, accepting any AudioSample (WaveFile, RawSample, Mixer, MP3Decoder) and plays it non-blocking via DMA to a PIO state machine.
Adds a new board-level module mtm_hardware with a DACOut class that provides non-blocking audio playback through the slightly strange MCP4822 dual-channel 12-bit SPI DAC on the Music Thing Modular Workshop Computer.
DACOut follows the same API as audiobusio.I2SOut, accepting any AudioSample (WaveFile, RawSample, Mixer, MP3Decoder) and plays it non-blocking via DMA to a PIO state machine.
Before:
#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico"
#define MICROPY_HW_OBJ_NAME "RP2040"
after:
#define MICROPY_HW_BOARD_NAME "NOT So Bad USB - 0x29 VHC"
#define MICROPY_HW_OBJ_NAME "NotSoBadUSB-BootMode"
Howdy! There's a couple PRs that would be good to merge today before the next bundle cronjobs, otherwise I am pretty sure it will think each bundle was entirely updated:
https://github.com/adafruit/Adafruit_CircuitPython_Bundle/pull/543
https://github.com/adafruit/CircuitPython_Community_Bundle/pull/274
Thank ya kindly 
<@&356864093652516868> We'll have our weekly meeting in about 1 hour and 15 minutes from now in this text channel and in the circuitpython voice channel. Please take the time to add your notes in advance to the document: https://docs.google.com/document/d/10W0TOyUCAml9Tc6jSNZa5mgK05YGfCPuexfbpSFLteE/edit?tab=t.0#heading=h.jb0k8k2z2vqn -- I look forward to everyone's updates!
Google Docs
CircuitPython Weekly Meeting for March 23, 2026 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you canβt make the meeting and would st...
Are you looking to change the USB name only? What exactly do you want to change?
For USB you can do: https://docs.circuitpython.org/en/latest/shared-bindings/supervisor/index.html#supervisor.set_usb_identification
alarm.sleep_memory not preserved across microcontroller.reset()
Summary
On ESP32-S2 (and likely all Espressif targets), alarm.sleep_memory is zeroed by
microcontroller.reset() despite the hardware being capable of preserving RTC memory
across a software reset. This is because the backing storage uses RTC_DATA_ATTR
instead of RTC_NOINIT_ATTR, causing the ESP-IDF bootloader to zero-initialize it
on every boot.
There is currently no way for CircuitPython code to persist data acro...
going to need a minute or 2 to setup, previous meeting ran a little over
I retrofitted a 1990s 1G brick style cell phone using a Raspberry Pi Pico microcontroller and a bunch of supporting parts. (see below) Once the phone was in working condition, I took it out in public to see if anyone would notice this retro tech work of art. See their reactions and learn how I rebuilt this phone.
Parts list:
Raspberry Pi Pico 2...
Instructables
Sony Infrared Remote Control Shutter Using Circuit Playground Express (CPX): The shutter for cameras sometimes needs to be fired remotely or without a physical press to avoid jogging the camera risking blur on long exposures or changing the position of the camera. In the past mechanical shutter releases with a physical push β¦
π
thank you!
Thanks for hosting Liz, have a great week everyone.
thank you!
This is way more detailed than it needs to be. Please don't just copy and paste verbose LLM output. Instead, please open a PR with the proposed fix after you've reviewed all code written and tested it on a device to make sure it works. If you want an LLM pre-review, please do that in your fork before making a PR here. Thanks!
I think this should be reorganized so that it can be use elsewhere besides this board.
I'd put it in shared-bindings under the mcp4822 name unless this is a common SPI DAC protocol. If it is, then use a more generic name with any mcp4822 specific settings.
Then, move this implementation to common-hal for rp2 (since it is PIO based). Could it be SPI based if we had an internal async SPI API? Maybe have it take in the bus to use?
The board will init it and add an entry to board for usi...
Here is the notes document for next Mondayβs CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Add your hug reports and status updates to the document before the meeting. If you are unable to attend but would still like to contribute, feel free to add your notes and weβll read them off during the meeting. Hope to see you there! <@&356864093652516868>
https://docs.google.com/document/d/17MhtQLKxqw0RLkAXOwIhFo6tgUB7oy7ZhBopKIDmMEU/edit?usp=sharing
Google Docs
CircuitPython Weekly Meeting for March 30, 2026 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you canβt make the meeting and would st...
The bootloader_id should stay the same.
I don't see it being of much use to others. This is not a good DAC for doing audio on. We already have the mcp48xx library for more traditional uses.
This DAC frustratingly requires per-sample manipulation (bit sets for channel selection & bit shifts for 16-bit->12-bit conversion) that makes it difficult to use for audio on any other port in CircuitPython that doesn't have a PIO-like module to handle that sample manip...
If you insist, then ok. How about still initing it in board_init and adding it to board? That way folks don't need to know about this module at all.
I'm also currently trying to put it in audiobusio. Seems like the correct place to put it? Or should it be top level? (I'm not clear what you meant in your original comment)
I'm also currently trying to put it in
audiobusio. Seems like the correct place to put it? Or should it be top level? (I'm not clear what you meant in your original comment)
Not in audiobusio because we don't want it enabled everywhere audiobusio is. A new module at the top level please.
Is it possible to pass in arguments in objects defined in board_init()?
E.g. could a Feather user do spi = board.SPI(half_duplex=True)?
I ask because this DAC takes an optional gain parameter during object instantiation (because it changes the PIO program)
Is it possible to pass in arguments in objects defined in
board_init()? E.g. could a Feather user dospi = board.SPI(half_duplex=True)? I ask because this DAC takes an optionalgainparameter during object instantiation (because it changes the PIO program)
No, it's meant to just work. I'd suggest making gain an attribute on the object.
Okay, the 'mcp4822' module is in its own namespace.
However, I was having some weirdness with make translate where it was picking up changes to files I did not touch. Almost like another commit had not run make translate. In my trying to figure it out I ended up deleting and restoring circuitpython.pot.
If that's too much churn for a PR, I can resubmit this as one change. But I still may get the weird translation changes.
I want to change the name the operating system uses when it "recognizes" the hardware, in this case as CYCUITPY. And also how the hardware is recognized when it enters "configuration" mode via the IDE.
I managed to make the change, but using reverse engineering with Ghidra, so I wondered, if the software is open source and I can directly modify the C code, wouldn't it be possible to automate this change? My expectations increased when I forgot that Windows is terrible when it comes to CMake ...
Just FYI, supervisor.set_usb_identification() needs to be done in boot.py, not in code.py (which is what it looks like you're doing above). And the change only happens after a full reset of the board. You cannot just press "Run" in Thonny.
Also note that depending on your OS, you may not see the change immediately. You may need to use a different USB port or power cycle your computer.
Thank you for your contribution, but it was created correctly following the documentation. I also didn't understand why it didn't work, regarding the code above. Its purpose is to show in the terminal how it was being interpreted, that is, it's merely illustrative.
The points are:
-
I have a complex language for creating the firmware, and the device depends on it for name configuration.
-
The solutions you showed me have already been tested and didn't work (at least not for me).
-
...
Let's shift our focus from the past to the future.
Wouldn't it be extremely simple to add two input boxes where I could enter this information, and the site would return the already modified code to me?
I'll bring up another interesting point.
We wouldn't need to mark or add stickers to our hardware when participating in events anymore, just a notebook. Simply plug it in and read the TXT file, or the output of IDE.
I know people might insert Command Controllers or something similar, but that would already create a problem between the hardware owner and the notebook.
supervisor.set_usb_identification() changes the values (at run-time) that are defined in mpconfigboard.mk. For example:
USB_VID = 0x239A
USB_PID = 0x80F4
USB_PRODUCT = "Pico"
USB_MANUFACTURER = "Raspberry Pi"
These are the USB string values that are presented to host, over USB, to identify the device. They are not the strings printed when the REPL starts up, etc.
What is your goal here? Do you want the host to see the device identified as something else, or are you trying to chan...
Should I consider this abandoned, or do we want to move forward with an easier approach?
Yeah I didn't mean to change the board ID. That was an accident. I have not had any luck being able to change back the code. It may be due to me only using the Web interface (I don't have git installed on my computer) and all the examples I see on how to roll back edits involve git commands from the terminal/cmd prompt.
When I get some time I will try it again. If I can't make it work then i will close out this issue and open a new one and do it correctly. Thanks you for your assistance a...
The CIRCUITPY name is the fat filesystem label that can be changed with mklabel IIRC. If CircuitPython creates the FS then it sets the label to CIRCUITPY. If it is changed, then CircuitPython will still work and not change it. (Unless you prompt CP to recreate the FS.)
To fix the zephyr builds you'll need to run: https://github.com/adafruit/circuitpython/blob/main/ports/zephyr-cp/cptools/update_board_info.py
(We cache what modules are enabled on zephyr and have a check to make sure every module is listed. We should likely relax it.)
I usually use dosfslabel as it comes with Ubuntu. I use it like this (assuming your drive is mounted at /dev/sda1):
umount /dev/sda1
sudo dosfslabel /dev/sda1 BOOP
unplug and replug device and the automounter picks up the new name
To fix the zephyr builds you'll need to run: https://github.com/adafruit/circuitpython/blob/main/ports/zephyr-cp/cptools/update_board_info.py
Should I be running this before every commit, as an adjunct to pre-commit?
Allows building and upload the Zephyr native-sim executable to S3, which will make the actions both faster and require much less cache space.
A few minor things. Getting close! Thanks!
@tulip sleet I'm having claude work on the idf6 update
I saw that in notes π
I'm poking the asyncio stuff too
To fix the zephyr builds you'll need to run: https://github.com/adafruit/circuitpython/blob/main/ports/zephyr-cp/cptools/update_board_info.py
Should I be running this before every commit, as an adjunct to pre-commit?
Maybe? It only matters when adding a new module but it should be fast to run.
[adafruit/circuitpython] Pull request review submitted: #10868 Add support for fixed Zephyr displays
Not tested, but I don't see any issues with what's there.
It looks like you successfully changed the board_id back. If you go to the file changes tab on this request, you can see which changes would be made by merging it. It currently shows no changes to the board_id, which is what we want.
Ok I applied your changes (oddly gives an error but then when I went back in apparently it took. Now under files changes it says "File renamed without changes" which is what we were aiming for, correct?
I may be slow but I get there eventually. π
Fixes #685. I used Claude Code to cross-reference the boards in the circuitpython repo and update the family to make searching for boards by processor more granular. I also updated any pages that relied on this and the bootloaders.json.
Ok, I've sketched out what I'm thinking here: https://github.com/tannewt/circuitpython/commit/80d1555b2452cf9a498dc9f1fb89b7d57e2c1637
It uses a macro to define a "function" that returns an awaitable with C calls into start, end, and cancel. There is an OS dependent flag to indicate when end should be called.
Should I make a draft PR to get feedback? I don't intend to actually merge the example module. I'd prefer a real use.
Hi Tanner,
Thank you for the example.
I'm struggling to figure out where the work actually happens. Is it in a callback to timer_expiry() from the k_timer instance? Will this mean tasks are completed by callbacks rather than the asyncio event loop?
@relic-se I'm getting back to some synthio work. Just tested changing the start/end with LFO and works well, thanks.
A zephyr build is still failing but I can't tell how it's failing or see how I can fix it.
@devout jolt Scott is off until next week so you won't get PR feedback for a bit.
ah thanks. It's not a big deal. I think I found the problem. A bunch of new zephyr boards were added in the time between when I rebased and ran update_board_info.py.
I'm using 10.1.4 on a Pi Pico W and I'm seeing Biquad and not BlockBiquad. The 9.2.x docs claimed former was supposed to go and be replaced by latter but 10.1.4 docs only mentioned Biquad.
Adafruit CircuitPython 10.1.4 on 2026-03-09; Raspberry Pi Pico W with rp2040
>>> import synthio
>>> dir(synthi...
Code you please share the file of demo codes for the esp32 s3 sim7670x 4g board by waveshare.
Thanks!
Oh, ignore me, I've now spotted what's going on. Biquad() changed from
class synthio.Biquad(b0: float, b1: float, b2: float, a1: float, a2: float)
to
class synthio.Biquad(mode: FilterMode, frequency: BlockInput, Q: BlockInput = 0.7071067811865475, A: BlockInput = None)
Change the "sleep memory" linker attribute from RTC_DATA_ATTR to RTC_NOINIT_ATTR.
Also, the ESP-IDF bootloader will no longer zero-initialize sleep memory on software reset (microcontroller.reset()), watchdog, or panic resets.
Added explicit clearing in alarm_sleep_memory_reset() for reset types where RTC SRAM contents are not known to be intact.
Sleep memory now persists across microcontroller.reset(), watchdog, and panic resets. This is now the same as existing deep-sleep behavior ...
I first made this change against main then rebased to 10.1.x.
I may need to go through the full build and test cycle again with a clean build to make sure that there aren't extraneous changes (e.g. '*.pot' files).
Thanks for the PR.
The PR commit was based on main, so it will have mains circuitpython.pot. You could try rebasing your PR branch onto 10.1.x, but I'm not sure if that would work out. Another thing to do is to create a new local branch off of 10.1.x and then git cherry-pick 2e0250f into it. Resubmit as a new PR and close this one.
The docs build failed due to a temporary failure. I re-ran it to confirm that was temporary.
After thinking about this some more, I would rather have this as a PR against main instead of 10.1.x, so that it will appear in 10.2.0. It is a behavior change that is not necessarily a bugfix, and might break some existing code. I looked at the Learn Guide code and I don't any effects on those uses of sleep_memory, but there might be user code.
Hey @tulip sleet or anyone else with merge privs on the "circuitpython" repo: Are squash merges done? I've got a PR with a mess of commits, some caused by rebasing while chasing zephyr updates, and I'd hate for all that to end up in the git history. Should I close that PR and offer up a cleaner one or will the mess get squashed?
No, we don't squash. We don't really care about all the commits. If you want to rebase and squash and then do a git push -f, that's OK, but we won't hold it against you for multiple commits.
we decided years ago not to squash
good to know, thanks!
I have had to rebase and force push more times then I want to admit, because me and git are not always friends
In that case I should just be able to move this out of draft state.
Looks like the reports for https://circuitpython.org/contributing failed to generate
This adds support for adjustable playback speed / rate to audio streams (Wavefile, MP3Decoder, etc),
addressing issue https://github.com/adafruit/circuitpython/issues/10881.
It is a reworking of the idea from #10882 to apply to more than just WaveFile.
New CIRCUITPY_AUDIOTOOLS definition added, only enabled for raspberrypi builds.
Closing in favor of #10900
@tulip sleet I have a couple of quick PRs up for circup that should be easy hammer ins.
pre-commit fix:
https://github.com/adafruit/circup/pull/272
error message adjustment:
https://github.com/adafruit/circup/pull/271
Thanks!
CircuitPython version and board name
Adafruit CircuitPython 10.0.3 on 2025-10-17; stm32f411ce-blackpill-with-flash with STM32F411CE
Board ID:stm32f411ce_blackpill_with_flash
UID:230057000451353031363535
Code/REPL
print("Hello World!")
Behavior
Hello, I'm having a problem with an STM32F411CE WeAct BlackPill with 8MB SPI flash, version 3.1. The CIRCUITPY drive isn't showing up.
I have successfully tested the following CircuitPython versions: 8.2.0, 9...
CircuitPython version and board name
Adafruit CircuitPython 10.1.4 on 2026-03-09; Raspberry Pi Pico W with rp2040
Code/REPL
Adafruit CircuitPython 10.1.4 on 2026-03-09; Raspberry Pi Pico W with rp2040
>>>
>>>
>>> import synthio
>>> test_env1 = synthio.Envelope(release_time=1.0)
>>> test_env1.release_time
1.0
>>> test_env1.release_time = 2.0
Traceback (most recent call last):
File "", line 1, in
AttributeError: can't set attribute
>>> test_env2 = synthio....
As a workaround I have discovered I can make a new synthio.Envelope based on the existing one but with a new release_time and then assign that to the applicable synthio.Note objects (oscillators).
Board: Adafruit Qualia ESP32-S3 RGB666 (adafruit_qualia_s3_rgb666)
Display: HD458002C40 4.58" 320x960 bar (PID 5805)
CP version: 10.1.4 (2026-03-09)
Bug
Intermittent single-frame jumps visible on DotClockFramebuffer-driven display when moving a displayio.Group. Occurs even with WiFi disabled, USB disconnected, and gc.collect() in loop. Severity increases significantly with WiFi on or CIRCUITPY_WEB_API enabled.
Repro
Minimal reproducible example by forum user **...
@tannewt any chance 10.1.4 was built with ESP-IDF 6.0?
I'm working on my first library (https://github.com/prcutler/CircuitPython_bambulabs/) that queries a BambuLabs printer over MQTT, which returns a JSON blob. My library handles the MQTT connection, processes the JSON and has a method to return each key in the JSON, like this:
def bed_temperature(self):
"""Current bed temperature in degrees Celsius."""
return self._print.get("bed_temper")
But ruff is complaining: bambulabs.py:60:1: PLR0904 Too many public methods (26 > 20) and so GitHub actions errors out. Is there a different way I should be doing this that to reduce the number of methods? Or is there a way around this?
I'm seeing this issue also on a Feather M4 Express, using 10.1.4:
self.wav_file = open(self.sound_files[sound], "rb")
self.wav = WaveFile(self.wav_file)
print(f"sample_rate: {self.wav.sample_rate}, channel_count: {self.wav.channel_count}, bits_per_sample: {self.wav.bits_per_sample}")
self.mixer = audiomixer.Mixer(voice_count=1, sample_rate=self.wav.sample_rate, channel_count=self.wav.channel_count, bits_per_sample=self.wav.bits_per_sample, samples_signed=True)
if BUG:
# This so...
near the bottom of ruff.toml there is an ignore list. You can add PLR0904 to it to get the tool to skip that rule. https://github.com/adafruit/Adafruit_CircuitPython_VCNL4030/blob/main/ruff.toml#L91
the file could be split into two separate ones. But I don't think it would really improve the readability or organization in this case. Not necessarily worth it just to appease the checker IMO. For community libraries you can always feel free to ignore any of the rules that you don't care about in your own code.
thank you!
If anyone has a chance, I'm stuck on GitHub actions for creating my library and not sure how to troubleshoot: https://github.com/prcutler/CircuitPython_bambulabs/actions/runs/23710945555/job/69070471870 - it appears to be failing because it can't import my library bambulabs and wifi: WARNING: autodoc: failed to import 'bambulabs'; the following exception was raised: and ModuleNotFoundError: No module named 'wifi' - but isn't wifi a native module? And I've looked at other community libraries, and they seem to import themselves, so I thought I was doing that right
Since this seems to be about autodoc (I think?) is it just lines 1187/1188 about the TODO entries, the warnings are probably treated as errors?
As a total side note your copyright line in the your .py file is not updated either, just happened to see that.
Thanks
Removing the TODO entries from the README didn't seem to fix it, it's still giving me autodoc errors trying to import the two classes in bambulabs.py: https://github.com/prcutler/CircuitPython_bambulabs/actions/runs/23713090916/job/69075817995 - sorry for the repeat question, but I'm not getting it yet
Which file did you see that in? In bambulabs.py I have # SPDX-FileCopyrightText: Copyright (c) 2026 Paul Cutler - is that incorrect?
Okay maybe I need more caffeine, I saw the first line with Scott's name and missed yours below, oops
yeah, I wasn't sure why that was there either, but I checked some random community libraries and they all had it. π
for CircuitPython core modules that aren't part of CPython we have to add them to this list of "mock imports" in docs/conf.py https://github.com/prcutler/CircuitPython_bambulabs/blob/main/docs/conf.py#L28
it looks like wifi is the only one that needs to be mocked for your library I think.
Neat utility by the way. Thanks for publishing it!
Thanks, I appreciate the help. And it's my pleasure - todbot found an Arduino library that inspired it
Ok, so autodoc doesn't complain about wifi anymore, but it still complains about the bambulabs library itself: WARNING: autodoc: failed to import 'bambulabs'; the following exception was raised: on line 1123, and then fails on the 2 classes within the library. Right above that on line 1122 it says reading sources... [ 67%] examples - is it reading the simpletest I made that imports bambulabs and failing there? I feel like I'm so close and missing something obvious
I see this now I didn't before ValueError: Unsupported radio class: radio does that also need to be included in that autodoc line?
trying now
Nope, didn't seem to matter, same error: https://github.com/prcutler/CircuitPython_bambulabs/actions/runs/23714395801/job/69079062794 - line 1124: WARNING: autodoc: failed to import 'bambulabs'; the following exception was raised:
Not sure if I know much more, if you look down line 1205/1207 it tries to show the root cause. I think
ah, missed that
The only time radio is called is as wifi.radio when setting up wifi so it can use MQTT in bambulabs.py in lines 39 & 40. I have no idea why it's failing as ImportError: (ValueError('Unsupported radio class: radio'), as it's not a class (I think)
I thought Radio in radio is a class but I haven't got into autodoc so kinda at my limit of knowledge
no problem, I appreciate the help - thank you!
I think this may be a bug or issue with connection manager and/or the docs build, not on your end. I'm not positive though. I'll try to look further into it when I can.
Thank would be great, thanks in advance
Hi Tim - todbot helped me out and suggested I move the pool, ssl_context, and MQTT setup into the BambuPrinter class and it passed! So I'm good, unless there's a different way I should be doing it. Thanks again.
Nice, glad it was easy to work around.
I'm trying to publish this library to pypi and getting a 403 forbidden error. The Learn Guide just says Note: for a release to be deployed to PyPi, it requires the PyPi credentials to be added to the repository secrets. - is that as simple as creating two different secrets, pypi_username and pypi_password in Settings / Secrets & Variables? The pypi docs reference using tokens, so I'm a bit confused: https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
Also new accounts require 2FA, which makes me wonder if that might be the culprit
IIRC you need to use an "API token" in the password field. And I think they are upper-case but I'm not sure if it actually matters. like PYPI_USERNAME, PYPI_PASSWORD. The password gets set to the API token which can be generated when you are logged in to a pypi account. It's down some ways on the account settings page.
aha, tokens! I see it now, trying again, thank you
and I do think setting up 2FA is required, though I'm not sure of that either.
it worked! Thanks again for all the help
π You're welcome
Right now it's impossible to use the Stage library, because it always throws a validation error.
Yes, this has been an issue for a while. I'd love to see it modified to support mutable properties, and I don't see any reason why it wouldn't be able to with a little bit of elbow grease.
I'm not going to be able to have access to the hardware to properly diagnose this hardware in the near future, and @Sporking's findings make me think that it may not be related to the changes made by https://github.com/adafruit/circuitpython/commit/fd2627cf950d4a0987b3b79a0ad12f019be8a1dd and it instead might be connected to the changes to the audiosample API in https://github.com/adafruit/circuitpython/pull/10036.
Oops, this should have been a draft because I hadn't tested it on any hw. I...
and it instead might be connected to the changes to the audiosample API in https://github.com/adafruit/circuitpython/pull/10036.
Nevermind, those changes were active on 9.2.5. So if 9.2.6 doesn't produce the error, that likely rules this hypothesis out.
This is against main, but my understanding is that it's also broken in 10.1.x. Should it be backported to that, or the base changed on this PR?
There aren't any other 10.1.x changes pending right now.
If it is the mono to stereo conversion, there is assembly in AudioMixer for the SAMD51 and it isn't quite straight-forward. I'm sure there was an assumption for speed in that assembly that wasn't considered. If I have a chance I'll try to look at it but it won't be this week for sure.
Even the sound files included by default for the Feather M0 Express (laugh.wav and rimshot.wav) show this behavior.
@Sporking Did you test this issue on the M0 (ATSAMD21) itself? Or were the files just pulled from the M0 and tested on the Feather M4 Express?
@gamblor21 I didn't include any SAMD-specific operations in the following functions:
Do you think the fix may be to include the equivalent operations as is with other methods? Ie:
It would be great if it could be backported. I'm not entirely familiar withe the process, so I don't know what is the difference.
If you made a PR against 10.1.x instead of main, then it would go into the next 10.1.x release, and we'd also forward-port it to main, just by merging 10.1.x into main.
It's possible to change the base for the PR by clicking Edit on the title, but that often doesn't work if there are other changes.
I changed the base, it seems to have worked.
Changing the base brought in all the changes to main, so that didn't work. I changed it back. You could make a new PR using a new branch off of 10.1.x, or we can just merge this and then cherry-pick the change from this PR into another PR against 10.1.x.
uGame S3 is a handheld game console with an ESP32-S3 chip. More information at https://deshipu.art/projects/project-178061/
Lower SPI speed on uGame S3 to avoid display glitches.
(cherry picked from commit a2ab5536c857ea401058c609bf0f4d2f24f4fc86)
Thanks for submitting a pull request to CircuitPython! Remove these instructions before submitting.
See https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github for detailed instructions.
- Consider whether to submi...
<@&356864093652516868> We'll have our weekly meeting in about 80 minutes from now in this text channel and in the circuitpython voice channel. Please take the time to add your notes in advance to the document: https://docs.google.com/document/d/17MhtQLKxqw0RLkAXOwIhFo6tgUB7oy7ZhBopKIDmMEU/edit
Google Docs
CircuitPython Weekly Meeting for March 30, 2026 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you canβt make the meeting and would st...
fyi this is not high priority or likelyhood of long-term resolution as TFT support on S3 is pretty hacky!
@tannewt any chance 10.1.4 was built with ESP-IDF 6.0?
It is not. My working branch is https://github.com/tannewt/circuitpython/tree/idf6
My idea is that you'd trigger DMA in _start and then when it is done a callback sets the flag. _start is called when the object is awaited. The flag marks it as ready and then _end is called. It returns the object that is return in the await. _cancel is called to stop the transaction when in flight.
I wasn't thinking the object would call repeatedly into C to check done state. By using a flag, we can later support sleeping while waiting.
In MicroPython already:
https://docs.micropython.org/en/latest/library/asyncio.html#class-event
Event.wait() is awaitable.
https://docs.micropython.org/en/latest/library/asyncio.html#class-threadsafeflag
ThreadSafeFlag() is awaitable.
Changelog for Espressif products and software
Next week's episode of The CircuitPython Show , I interview Esha Patel who is in that article, along with her classmate Abby Bergman
GitHub
micropython Amiga 68k port. Contribute to OoZe1911/micropython-amiga-port development by creating an account on GitHub.
Updates made within https://github.com/adafruit/circuitpython/pull/10529 may have caused audio corruption on the SAMD51 platform as reported by https://github.com/adafruit/circuitpython/issues/10867. This update adds ARM-specific operations to copy16lsb and copy16msb to attempt to fix this regression.
This update has not yet been tested on the target hardware. Any assistance from @todbot or @gamblor21 would be greatly appreciated.
yah - a pico build seems like a good idea
whatever version/flavor makes sense
^^ of pico. 1 or 2. wifi or non-wifi. etc.
π
Thanks for hosting Scott, have a great week everyone.
Thinking out loud a bit here. I don't see anything wrong in your change, but I'm not sure the distortion would be fixed by just a speed up of what amounts to a basic bit copy (but it may).
I think there is an issue in the SAMD51 ASM code, with mult16signed. The old code would take a 32bit value HHHHLLLL and multiply both halves by loudness returning a 32-bit result.
The new code gets HHHHHHHH and then LLLLLLLL as two values (because of the copy16lsb and msb). So the result is HHHH*loudn...
Here is the notes document for next Mondayβs CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Add your hug reports and status updates to the document before the meeting. If you are unable to attend but would still like to contribute, feel free to add your notes and weβll read them off during the meeting. Hope to see you there! <@&356864093652516868> https://docs.google.com/document/d/1rLHPbsMA2tOnUd3Ok-1xXsTQ9ts8WD4ZetJRcW7pmIE/edit?usp=sharing
Google Docs
CircuitPython Weekly Meeting for April 6th, 2026 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you canβt make the meeting and would s...
Some ReadTheDocs builds were failing with these warnings:
WARNING: the `rstjinja` extension does not declare if it is safe for parallel reading, assuming it isn't - please ask the extension author to check and make it explicit
WARNING: doing serial read
Weirdly, when I re-ran a failing build it worked and did not generate the warnings.
Nevertheless, the fix appears to be to have rstjinja declare it self as safe for parallel read and write. (I had to look up what the warnings ...
Has anyone taken a video of this?
Cool! Looks good. Doc build issue is unrelated.