#circuitpython-dev

1 messages Β· Page 94 of 1

thorny jay
#

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.

manic glacierBOT
#

Why not add a tomllib module 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.

lone axle
tulip sleet
lone axle
lone axle
#

Thanks for hosting Dan, have a great week everyone πŸ‘‹

tulip sleet
#

@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

lone axle
tulip sleet
#

thank you!

tulip sleet
tulip sleet
#

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

manic glacierBOT
#
[adafruit/circuitpython] New tag created: 10.1.1
orchid basinBOT
tulip sleet
#

@slender iron have you got some time for a video checkin about short-term PR discussions, etc.?

slender iron
#

yup!

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

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 ...
surreal perch
# manic glacier

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.

manic glacierBOT
#

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 ...
tulip sleet
manic glacierBOT
manic glacierBOT
#

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?

manic glacierBOT
#

@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 ...

manic glacierBOT
#

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 ...

manic glacierBOT
manic glacierBOT
#

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...

manic glacierBOT
#

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...
manic glacierBOT
#
[adafruit/circuitpython] New tag created: 10.1.2-alpha.0
manic glacierBOT
#
[adafruit/circuitpython] New tag created: 10.2.0-alpha.1
orchid basinBOT
manic glacierBOT
#
[adafruit/circuitpython] New tag created: 10.2.0-alpha.0
tulip sleet
manic glacierBOT
manic glacierBOT
#

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...

#
  • 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 ...
short tendon
#

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

manic glacierBOT
tulip sleet
short tendon
# tulip sleet Do you mean with the Register library? It would be nice to figure out how to do ...

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)

manic glacierBOT
#

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%".

manic glacierBOT
faint wadi
#

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

manic glacierBOT
manic glacierBOT
tulip sleet
#

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

tulip sleet
# faint wadi Can Please Someone Build The Bootloader for the Sensorwatch Fork For Me? <https...

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.

faint wadi
tulip sleet
#

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.

stuck elbow
#

the uf2 bootloader was someone's side project, they laid off all people who were working on it

tulip sleet
#

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

manic glacierBOT
slender iron
short tendon
#

also adafruit_circuitpython_register is pretty small. has there ever been thought of putting it into CP itself so it can be faster?

slender iron
#

how are you profiling it?

short tendon
#

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

slender iron
#

@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.

short tendon
#

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...

slender iron
#

I totally believe that πŸ™‚

#

there is always room for optimization

orchid basinBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
slender iron
#

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

tulip sleet
slender iron
#

the copyright changes were an easy win

#

others weren't quite what I wanted

tulip sleet
#

I would have been more explicit. ... yeah, I expected you could easily ask it to do that.

slender iron
#

next time I'll tell it to not push the changes

manic glacierBOT
faint wadi
# tulip sleet not microsoft, us. The RP2040/RP2350 has been a good substitute. SAMD21 is reall...

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

stuck elbow
tulip sleet
faint wadi
serene token
# faint wadi Is there a suggested way to install arm-none-eabi on Ubuntu 24.04? I wasn't able...

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.

serene token
# faint wadi Thanks! Is there a suggested folder it should be in? Does `usr/bin` make sense? ...

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.

faint wadi
serene token
#

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!

tulip sleet
manic glacierBOT
serene token
manic glacierBOT
manic glacierBOT
#
[adafruit/circuitpython] New tag created: 7.0.2
#
[adafruit/circuitpython] New tag created: v1.26.1
#
[adafruit/circuitpython] New tag created: 7.0.3
manic glacierBOT
tulip sleet
#

@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

tulip sleet
#

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?

tulip sleet
#

... Trying a change to actions.yml to do that

tulip sleet
#

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

slender iron
tulip sleet
slender iron
#

I'm not sure why it is off. Zephyr does have its own list of python deps

tulip sleet
#

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

slender iron
#

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

tulip sleet
#

I would like to do a 10.1.2 with the MagTag fix and this fix.

slender iron
#

that is a better fix

#

I wonder what else we can unpin then

#

this is definitely not the first time its happened

tulip sleet
slender iron
#

lemme check what version of click is used my idf 5.5.3

tulip sleet
#

this PR is for 10.1.x

slender iron
#

I can't tell where the <8.2 requirement comes from

#

it is in a constraints file in the idf tools

tulip sleet
slender iron
#

yup

#

we may be able to have our requirements install respect it though

manic glacierBOT
orchid basinBOT
manic glacierBOT
#
[adafruit/circuitpython] New tag created: 10.1.3
tulip sleet
#

I accidentally tagged 10.1.2 off of main instead of 10.1.x 🀦

#

so now it's 10.1.3

orchid basinBOT
manic glacierBOT
#

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...

tulip sleet
manic glacierBOT
#

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...

manic glacierBOT
#

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.

manic glacierBOT
empty salmon
#

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 🫑

tulip sleet
empty salmon
# tulip sleet That code was already there, written by Scott, to try to read a different regist...

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.)

tulip sleet
empty salmon
tulip sleet
empty salmon
manic glacierBOT
tulip sleet
empty salmon
manic glacierBOT
#

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.

manic glacierBOT
#

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...

manic glacierBOT
manic glacierBOT
#

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...

manic glacierBOT
#

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)
manic glacierBOT
#

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.

manic glacierBOT
surreal perch
# manic glacier

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.

manic glacierBOT
#

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 ...

manic glacierBOT
#

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.

manic glacierBOT
#
  • 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 ...

manic glacierBOT
manic glacierBOT
#

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" />

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

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...

manic glacierBOT
manic glacierBOT
#

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...

tulip sleet
#

@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.)

slender iron
#

that seems right to me. did you clean and rebuild?

tulip sleet
#

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.

slender iron
#

I don't have any ideas. Try an LLM πŸ™‚

#

make sure you are in the right repo....

tulip sleet
#

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

slender iron
#

I'd probably look in menuconfig

#

and also verify the sdkconfig in the build dir has the right setting

tulip sleet
#

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.

slender iron
#

did you try claude code or something in your working directory?

tulip sleet
#

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

slender iron
#

it's been a while. I normally use uart0

tulip sleet
#

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

slender iron
#

the bootloader could be complicating things

#

or even the ROM

tulip sleet
#

yes, might be logging directly via the ROM routines or something

manic glacierBOT
#

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...

candid sun
#

<@&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!

manic glacierBOT
#

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...

wraith crow
#

πŸ‘‹

lone axle
tidal kiln
#

πŸ‘‹

slender iron
#

thanks for hosting!

lone axle
#

Thanks for hosting Liz, have a great week everyone.

candid sun
#

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

manic glacierBOT
manic glacierBOT
#

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 qspibus module providing QSPI bus protocol support analogous to fourwire for standard SPI
  • Implements ESP32-S3 specific QSPI bus driver using ESP-IDF's LCD pan...
manic glacierBOT
manic glacierBOT
manic glacierBOT
slender iron
#

zephyr bleio PR is finally ready

manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

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...
manic glacierBOT
lone axle
#

@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?

slender iron
#

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?

lone axle
#

but I have not tried to find the converter source/spec to verify

lone axle
#

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)
slender iron
#

yup, it is

lone axle
#

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.

slender iron
#

I'm so good at git comments.....

manic glacierBOT
#

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 ...
slender iron
#

in my command history I see python generate_font.py --output fonts/unifont-16.0.02-ja.lvfontbin ja

lone axle
#

I got a different version. Will try that one.

slender iron
#

looks like the script is in circuitpython-font-generator

lone axle
#

Ahhhh, nice that has the ranges also. Thank you!

slender iron
#

python generate_font.py --output fonts/unifont-16.0.02-en_US.lvfontbin en_US too

lone axle
#

okay I will try some higher bpp of that specific font tomorrow and compare to current default.

slender iron
#

πŸ‘

manic glacierBOT
#

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_...
lone sandalBOT
manic glacierBOT
#

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...

slender iron
#

I'm fixing the tinycircuits board defs

manic glacierBOT
#

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...

tulip sleet
#

@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.

modern sundial
#

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.

manic glacierBOT
manic glacierBOT
#

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.

manic glacierBOT
lone sandalBOT
manic glacierBOT
manic glacierBOT
#

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 ...

manic glacierBOT
#

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.c enforces 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...
candid sun
#

is there anyway to turn off ble and ble workflow when building for esp32-c3? when i try CIRCUITPY_BLEIO = 0 i get errors

manic glacierBOT
#

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...
tulip sleet
candid sun
tulip sleet
#

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?

manic glacierBOT
#

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?

candid sun
#

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

manic glacierBOT
#

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...

#

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.

manic glacierBOT
#

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...
#

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_ts should be uint32_ts (or just uint32_t).
    uint32_t buffer_size = 128; // In uint32_ts

πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

manic glacierBOT
manic glacierBOT
#

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?

manic glacierBOT
#

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

manic glacierBOT
#

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.
...

manic glacierBOT
manic glacierBOT
#

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...

manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

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...

slender iron
#

@tulip sleet should we always rebase our changes onto zephy main or do merges from zephyr/main?

tulip sleet
slender iron
#

yup, that we reference from cp

tulip sleet
#

As long as we can find our changes, rebase is fine and makes the commits list a lot shorter

slender iron
#

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

tulip sleet
#

unlike esp-idf, we wouldn't need to do circuitpython-v1.2.3, etc.

slender iron
#

right, ok

manic glacierBOT
manic glacierBOT
manic glacierBOT
modern sundial
#

I suppose six years was too long to wait

manic glacierBOT
#

I tested both the W55RP20 and the W6300 boards. Some notes:

  • common-hal/wiznet/wizchip_pio_spi.c has some printf()-statements that should not be there
  • boards/wiznet_w6300_evb_pico2/mpconfigboard.mk is missing the CHIP_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 wiznet module should not be port-sp...
manic glacierBOT
#

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....
orchid basinBOT
manic glacierBOT
manic glacierBOT
#

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-3980922970

A bisect shows this is due to #10699
https://github.com/adafruit/circuitpython/pull/10699. I guess the
...

lone sandalBOT
slender iron
#

<@&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!

turbid radish
#

Good

lone axle
turbid radish
#

I cannot hear anyone

lone axle
#

I hear Scott.

tidal kiln
#

i can hear

lone axle
#

Last week I couldn't hear at first and had to fully close and restart discord.

turbid radish
#

That worked, thanks

lone axle
modern sundial
#

I can't hear either, but I suspect my workplace is blocking it.

turbid radish
#

You can try the web vs. the app. I had to refresh the window to hear

tidal kiln
#

spring forward!

crimson ferry
#

Spring ahead, Fall back.

tidal kiln
#

fall back πŸ™

#

πŸ‘‹

lone axle
#

Thanks for hosting Scott, have a great week everyone.

slender iron
#

@lone axle I wish I had the zephyr display stuff checked in for your font testing

lone axle
#

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.

slender iron
lone axle
# slender iron Are you going to work on the changes needed to fix the clipping? What do you nee...

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).

slender iron
#

hrm, I wouldn't special case the current font

lone axle
#

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.

slender iron
#

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>

slender iron
lone axle
# slender iron 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.

slender iron
#

I'm not sure how the converter computes the two

manic glacierBOT
manic glacierBOT
#

(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 ...

manic glacierBOT
slender iron
#

zephyr main PR is green

slender iron
#

thank you!

manic glacierBOT
proven garnet
#

@lone axle catching up on the weekly today - I can expand the patch to include the changes to .pre-commit-config.yaml - good idea!

manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

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/...

manic glacierBOT
#

This PR has 3 fixes for lvfontio.

  • Fix header.default_advance_width from getting set to the wrong value. With Unifont 8x16/16x16 font the value of this was ending up as 4 which 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 NULL last parameter. The LLM suggested this fix without explicit prompt while working on this file. I am unsure about it, but...
tulip sleet
#

@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.

slender iron
manic glacierBOT
#

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...
#

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...

manic glacierBOT
#

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

manic glacierBOT
#

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...
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

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 ...
manic glacierBOT
#

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...

tulip sleet
#

@slender iron if you have time, I have a fairly brief thing to discuss with you re user-created SPI buses used for displays.

manic glacierBOT
#

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...

slender iron
#

@tulip sleet I'll have time in a bit

#

just got to the maker space

manic glacierBOT
#

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...

manic glacierBOT
manic glacierBOT
#

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...

manic glacierBOT
#

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=...
modern sundial
#

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??

serene token
#

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...)

tulip sleet
manic glacierBOT
modern sundial
#

WiFi is already pinned to the second core? That’s fine then

manic glacierBOT
#

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...
manic glacierBOT
manic glacierBOT
#

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...

manic glacierBOT
#

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:

  1. Provide pre-built releases with this flag enabled, or
  2. Offer clearer documentation or guidance on how to build the firmware with custom compile flags?
    Any assistance would ...
manic glacierBOT
#

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...

manic glacierBOT
#

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...

tulip sleet
#

<@&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.

slender iron
slender iron
#

@tulip sleet we can hear you

lone axle
#

@tulip sleet a few of us spoke but seems like you do not hear.

tulip sleet
#

i am going to reboot

lone axle
#

@danh I spoke but seems like you still don't hear

lone axle
#

thanks for hosing Dan, have a great week everyone πŸ‘‹

slender iron
#

Thanks all!

tulip sleet
#

@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.

tulip sleet
manic glacierBOT
#
[adafruit/circuitpython] New tag created: 10.1.4
orchid basinBOT
manic glacierBOT
manic glacierBOT
tulip sleet
manic glacierBOT
short tendon
#

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?

stuck elbow
#

the compiler might do all kinds of optimizations, but I'm not aware of it doing the particular optimization you mention

modern sundial
tulip sleet
short tendon
#

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

tulip sleet
#

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

short tendon
#

yeah, I'm specifically looking at loops (either in the class, or that are called in code)

manic glacierBOT
#

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.

manic glacierBOT
#

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 ...

manic glacierBOT
#

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...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

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 ...

manic glacierBOT
#

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...
manic glacierBOT
#

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)

https://github.com/adafruit/circuitpython/blob/35de08db7e0c407f3e1e8213b85fc4d606344009/shared-bindings/bitmaptools/__init__.c#L209-L211

From the code It looks like both source and dest bitmaps have the same issue but I have only confirmed source.

manic glacierBOT
manic glacierBOT
#

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...

manic glacierBOT
manic glacierBOT
#

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...
manic glacierBOT
#

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 added MP_WARN_UNUSED_RESULT, which expands to __attribute__((warn_unused_result)). A...
slender iron
#

Any apt/Ubuntu experts. My display work is stuck with apt-get instability

tulip sleet
#

I think something upstream there is broken temporarily. Also githubstatus.com is showing degradation for CI due to download failures

manic glacierBOT
#

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...

devout jolt
#

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]
devout jolt
#

oh! Scott's livestreaming sorry. I'm not able to watch. I'll ask later

manic glacierBOT
#

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...

manic glacierBOT
dense glacier
#

sorry wrong channel

manic glacierBOT
#

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...

manic glacierBOT
#

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...
manic glacierBOT
#

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...

manic glacierBOT
manic glacierBOT
#

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...

manic glacierBOT
manic glacierBOT
#

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:

  1. 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...
manic glacierBOT
tulip sleet
#

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

lone axle
#

<@&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.

slender iron
#

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!

lone axle
#

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

#

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.

slender iron
#

I'll try

slender iron
#

worked for me. not sure if it is a permission thing or just a client issue

willow totem
willow totem
slender iron
#

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)

manic glacierBOT
#

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...

manic glacierBOT
#

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...
#

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.

...

manic glacierBOT
#

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...

proven garnet
#

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.

slender iron
#

check you actions tab for other stuff running

manic glacierBOT
proven garnet
manic glacierBOT
#

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 (...

manic glacierBOT
slender iron
manic glacierBOT
orchid basinBOT
orchid basinBOT
#

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...

orchid basinBOT
orchid basinBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
orchid basinBOT
orchid basinBOT
orchid basinBOT
#

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.

orchid basinBOT
manic glacierBOT
manic glacierBOT
#

@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.

manic glacierBOT
orchid basinBOT
manic glacierBOT
manic glacierBOT
orchid basinBOT
manic glacierBOT
#

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.

orchid basinBOT
proven garnet
#

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

GitHub

Fixes issue identified and addressed in the generation script in adafruit/adabot#411

GitHub

Fixes issue identified and addressed in the generation script in adafruit/adabot#411

proven garnet
#

Thank ya kindly kgsThankYou

candid sun
#

<@&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!

manic glacierBOT
#

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...

candid sun
#

going to need a minute or 2 to setup, previous meeting ran a little over

lone axle
tidal kiln
#

πŸ‘‹

slender iron
#

thank you!

lone axle
#

Thanks for hosting Liz, have a great week everyone.

candid sun
#

thank you!

manic glacierBOT
#

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...

candid sun
#

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

manic glacierBOT
#

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...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

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.

orchid basinBOT
#

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:

  1. I have a complex language for creating the firmware, and the device depends on it for name configuration.

  2. The solutions you showed me have already been tested and didn't work (at least not for me).

  3. ...

#

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.

orchid basinBOT
#

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...

manic glacierBOT
orchid basinBOT
#

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...

orchid basinBOT
manic glacierBOT
orchid basinBOT
manic glacierBOT
slender iron
#

@tulip sleet I'm having claude work on the idf6 update

tulip sleet
slender iron
#

I'm poking the asyncio stuff too

orchid basinBOT
orchid basinBOT
orchid basinBOT
manic glacierBOT
#

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.

manic glacierBOT
tulip sleet
#

@devout jolt Scott is off until next week so you won't get PR feedback for a bit.

devout jolt
manic glacierBOT
manic glacierBOT
#

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 ...

manic glacierBOT
#

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.

manic glacierBOT
devout jolt
#

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?

tulip sleet
#

we decided years ago not to squash

devout jolt
blissful pollen
#

I have had to rebase and force push more times then I want to admit, because me and git are not always friends

manic glacierBOT
lone axle
manic glacierBOT
kindred wren
manic glacierBOT
#

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...

manic glacierBOT
#

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....
manic glacierBOT
#

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 **...

manic glacierBOT
random junco
#

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?

manic glacierBOT
#

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...
lone axle
#

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.

random junco
#

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

blissful pollen
#

As a total side note your copyright line in the your .py file is not updated either, just happened to see that.

random junco
random junco
blissful pollen
random junco
#

yeah, I wasn't sure why that was there either, but I checked some random community libraries and they all had it. πŸ™‚

lone axle
#

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!

random junco
#

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

blissful pollen
#

I see this now I didn't before ValueError: Unsupported radio class: radio does that also need to be included in that autodoc line?

random junco
#

trying now

blissful pollen
#

Not sure if I know much more, if you look down line 1205/1207 it tries to show the root cause. I think

random junco
#

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)

blissful pollen
#

I thought Radio in radio is a class but I haven't got into autodoc so kinda at my limit of knowledge

random junco
#

no problem, I appreciate the help - thank you!

lone axle
#

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.

random junco
#

Thank would be great, thanks in advance

random junco
lone axle
#

Nice, glad it was easy to work around.

random junco
#

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/

random junco
#

Also new accounts require 2FA, which makes me wonder if that might be the culprit

lone axle
random junco
#

aha, tokens! I see it now, trying again, thank you

lone axle
#

and I do think setting up 2FA is required, though I'm not sure of that either.

random junco
#

it worked! Thanks again for all the help

lone axle
#

πŸŽ‰ You're welcome

manic glacierBOT
manic glacierBOT
#

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...

manic glacierBOT
manic glacierBOT
#
#

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...
slender iron
#

<@&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

manic glacierBOT
manic glacierBOT
#

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.

lone axle
random junco
#

Next week's episode of The CircuitPython Show , I interview Esha Patel who is in that article, along with her classmate Abby Bergman

lone axle
manic glacierBOT
#

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.

Fixes https://github.com/adafruit/circuitpython/issu...

tidal kiln
#

yah - a pico build seems like a good idea

#

whatever version/flavor makes sense

#

^^ of pico. 1 or 2. wifi or non-wifi. etc.

#

πŸ‘‹

lone axle
#

Thanks for hosting Scott, have a great week everyone.

lone sandalBOT
manic glacierBOT
#

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...

slender iron
#

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

manic glacierBOT
#

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 ...