#circuitpython-dev

1 messages · Page 89 of 1

wraith crow
#

no voice

lone axle
#

Thanks for hosting Liz! have a great week everyone 👋

thorny jay
#

Thank you @candid sun for hosting/reading.

manic glacierBOT
main furnace
#

Where do I file Open Installer issues?

slender iron
manic glacierBOT
#

Claude helped with initial prompt:

Refactor common_hal_epaperdisplay_epaperdisplay_construct so that the current arguments are struct fields and then the function only takes the struct. Also add a macro that initializes it to default values.

And one follow up prompt before minor manual cleanup and testing:

Clean up board files by removing settings that match the default. In particular bools that are false should be default, commands with NO_COMMAND and highlight color as 0.

Fo...

candid sun
#

Here is the notes document for the next CircuitPython Weekly Meeting in two weeks on August 25, 2025. 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/1YxMrgfSw5AcotMzRo8oWV4AOjsYhb9v2mWQmUSDRz9E/edit?tab=t.0

manic glacierBOT
#

it happens when running from fruit jam power on with thonny not running. doesn't happen every time but just did a set of 10 power on, see what happens, power off.... and 4 out of the 10 times errored with the code.py line 40 memory allocation failed error. this is with the font used in the irc client mentioned above with the code.py that i added the onDiskFont() and the fonts to

`# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries

SPDX-License-Identifier: MIT

from os import ge...

tiny peak
#

Does anybody know if CircuitPython already uses some kind of compression on QSTR strings (e.g. Hamming Huffman coding, LZW, or whatever)?
As I begin looking into fixing USB host glitches, I'm getting the sense I'll need to find ways of offsetting code size increases from any error handling code I might add.

#

It seems like most the stuff that can be turned off for the SAMD21 M0 boards has already been turned off.

tiny peak
#

thanks

#

does it seem plausible that error string compression is totally bypassed for non-ASCII strings? I'm looking at check_non_ascii().

#

by my casual reading of makecompresseddata.py, it looks like there might be a significant opportunity for improving the coding of non-english text.

manic glacierBOT
manic glacierBOT
#

After more research, this looks a bit more complicated: 1) The full zlib API isn't available in CircuitPython core. Instead it has the more limited uzlib. 2) zlib and uzlib both use LZ77/DEFLATE with a sliding window (not LZ78 or LZW), so building a good shared dictionary to use with random access decompression of individual strings might be a little tricky. Plausibly doable, but tricky.

manic glacierBOT
lone axle
manic glacierBOT
#

This update allows the tempo of a synthio.MidiTrack object to be manipulated after it has been constructed.

In my use case, I wanted to gradually increase the speed of a song within a game as it progresses.

Here is a demonstration of this property written for the Fruit Jam:

import audiobusio
import audiomixer
import board
import synthio
import time

import adafruit_tlv320

# configure dac
i2c = board.I2C()
dac = adafruit_tlv320.TLV320DAC3100(i2c)
dac.configure...
onyx hinge
#

@candid sun if the fruit jam schematic is up on Learn, can you point me at it .. and if not, can you send me a copy as png/pdf/whatever?

onyx hinge
#

@candid sun no, I can't see unpublished guides anymore either

onyx hinge
manic glacierBOT
#

So, in that case, it looks like everything is just Huffman coded? It seems plausible there might still be benefit in switching to LZ77/DEFLATE using uzlib with a shared preset dictionary? In theory, that might save more bytes for redundant substrings across error messages? Does that sound interesting? I'm worried that the USB error handling stuff I want to add may not fit if I end up needing to upstream stuff to TinyUSB rather than adding it to usb_host.

grizzled maple
#

Where's the best place to ask about the MatrixPortal S3 and its behavior with CircuitPython?
I get flickering updates in circuitpython, but not in C++

manic glacierBOT
#

CircuitPython version and board name

Any version

Code/REPL

example:

import adafruit_fruitjam

vs

from adafruit_fruitjam import peripherals

Behavior

I was asked to post this issue for CircuitPython core developers by @ladyada.

In the Adafruit Learning System Guide Memory-saving tips for CircuitPython
https://learn.adafruit.com/Memory-saving-tips-for-CircuitPython/optimizing-memory-use

By selectively importing only the functions you need, you m...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

If the RTOS is premptive, BusDisplay has a race condition that may caused faults on shared buses. displayio_display_bus_begin_transaction may return false indicating that the lock could not be acquired. As _refresh_area does not respect the return value of displayio_display_bus_begin_transaction, _send_pixels will try to write to the bus without a lock. A guard is present in the code, but it is implemented in a way that is not thread safe.

https://github.com/adafruit/circuitpython/blob/117b5...

manic glacierBOT
#

I finally figured out a serviceable workaround for this, at least for gamepads. Basic idea is to count the number of consecutive calls to Device.read() that rase a USBTimeoutError exception. I haven't encountered a gamepad that will return more than maybe one or two timeouts in a row unless it's been unplugged. Keyboards on the other hand will do many timeouts until you press a key, so timeout counting doesn't work as well. This is a working example of the consecutive timeout counting met...

manic glacierBOT
tiny peak
#

For people who've worked on USB stuff:
Do you have any favorite books or other reference documentation for understanding the USB specs?

stuck elbow
#

the usb spec itself is a good starting point

tiny peak
#

Anybody have experience with "USB Complete" or "USB Embedded Hosts", both by Jan Axelson?

slender iron
tiny peak
#

okay. thanks. I'll probably get a copy of that then.

slender iron
#

did you get a sniffer?

tiny peak
#

yeah. talked to pt and ordered one today.

slender iron
#

k, great!

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

I'd be happy to create a PR but I've spent a couple of hours trying to get a build environment working, but haven't succeeded as of yet. I'm reluctant to submit a PR without testing it first.

Feel free to make a draft PR and let the CI build for you. You can download artifacts from the CI run to test on your boards.

When you circle back to running it locally, jump on Discord and we can help get you set up. https://adafru.it/discord

manic glacierBOT
#

A second ?= in a makefile for the same variable is ignored, per https://www.gnu.org/software/make/manual/html_node/Setting.html

If you’d like a variable to be set to a value only if it’s not already set, then you can use the shorthand operator ‘?=’ instead of ‘=’. These two settings of the variable ‘FOO’ are identical (see The origin Function):

FOO ?= bar

and

ifeq ($(origin FOO), unde...
manic glacierBOT
lone sandalBOT
manic glacierBOT
lone sandalBOT
manic glacierBOT
manic glacierBOT
#

Fixes #10569

I've tested on a m5stack_cores3 with no apparent regressions on display handling. This strangely does not resolve #10536 so some other issue must also be present, however I can see on an oscilloscope that the SPI bus is now being shared correctly between busdisplay and sdcardio. One thing to note is running spi = board.SPI(); spi.try_lock() will now prevent the screen from being updated until the lock is released - this is a limitation of the the hardware.

I have also appli...

manic glacierBOT
tulip sleet
#

I'll wait for more info.

lone axle
#

Thank you

tulip sleet
manic glacierBOT
#

Ideally setting up NTP on a integrated AirLift enabled board like Fruit Jam, PyPortal or MatrixPortal M4 would be as easy as (which will also ready a few env vars from settings.toml).

import adafruit_airlift_ntp as ntp
ntp.sync()  # done

It actually takes quite a bit of setup currently. Bruce pointed this out and we put together a little helper library. Would it make sense for me to test and submit an adafruit_airlift_ntp librar...

ionic elk
#

is there a requirement to keep use of float and int64_t to the port level? I don't see references to them in the shared-bindings layer.

slender iron
ionic elk
#

Ok, maybe should just throw a NotImplemented for Int64 message types like I do with Float64 then

#

I'd like to keep float, so I'll ask in my PR whether I need to reshuffle stuff down to the common-hal

slender iron
#

int64 should be fine. the vm supports them. they just aren't small ints

#

not sure what it does for float64

ionic elk
#

For context, I'm storing values from Circuitpython variables to internal objects that will be passed to micro-ROS. My impression was that this would be port-agnostic so I haven't put it in the common-hal so far, but I could be wrong. I don't think Circuitpython floats support double precision, right? If circuitpython has no vm variable for a double precision integer, there's no point in me supporting that either

#

Unless I offered something kind of janky like a manual byte array. Doing that would depend on whether there's a use case for it. Could always revisit later.

slender iron
#

right, no double support that I know of. MP might have it. I haven't looked. long ints should be on

stuck elbow
#

weren't long ints disabled on samd21?

#

(not that this will ever fit there)

slender iron
#

ya, I think they are

#

mostly enabled

manic glacierBOT
tulip sleet
manic glacierBOT
#

Based on preliminary printf debugging, TinyUSB may sometimes call tuh_umount_cb() later than it should, or not at all. Not confident about that yet though. The latency I saw could also be from buffering of mp_printf() before it made it out over the USB device interface.

This is a patch for the mp_printf() stuff I was using to check when the tuh_mount_cb() and tuh_umount_cb() callbacks were being called:

diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Devic...
devout jolt
#

Has anyone on MacOS been seeing CIRCUITPY drives not being mounted (or even visible from df) after a few unplug/replug cycles? I've been getting it a lot these past few days, with nothing I can think of having changed on my Macbook. A reboot of the Mac will fix it for a while. Killing the Finder doesn't help. It's not a TinyUSB issue, even the RP2 ROM UF2 bootloader won't show up.
Edit: The board is still there: shows up in USB Prober, can connect to via USB CDC if CircuitPython, just no USB MSC

ebon horizon
#

I can't replicate when and why though

devout jolt
ebon horizon
devout jolt
ebon horizon
#

Ah, that's interesting.

devout jolt
#

Yeah super weird and frustrating

manic glacierBOT
#

I'm confident now that TinyUSB is not calling tuh_umount_cb() when it should. This diff has pico-sdk gpio code to turn the Fruit Jam's red LED (pin 29) on when tuh_mount_cb() is called and off when tuh_umount_cb() is called:

diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c
index c9df0cf738..f650ed318a 100644
--- a/shared-module/usb/core/Device.c
+++ b/shared-module/usb/core/Device.c
@@ -18,16 +18,35 @@
 #include "supervisor/shared/tick.h"
 #include "su...
manic glacierBOT
manic glacierBOT
#

CircuitPython version and board name

* ✅ A: `CircuitPython 9.1.0-beta.3-6-gc2443f993f` → BLE File Transfer Service (UUID `0xFEBB`) **appears as expected**
* ❌ B: `CircuitPython 9.2.4-154-gbd572f86f9` → BLE File Transfer **does not appear**, despite identical board configuration and settings

Code/REPL

*Expected**: BLE service UUID `0xFEBB` should be visible on  CircuitPython 9.2.4-154-gbd572f86f9 after preforming 
1. Custom UF2 built with the following settin...
tulip sleet
#

@lone axle re the TLV gain settings and the speaker: It appears that the power-up value for the speaker amp gain is 6dB (lowest), and for the attenuator, the power-up gain is -78dB. That is, it is as quiet as possible when first powered up. The CircuitPython driver does not mess with these values on instantiation. So I'm not sure there's anything to do except maybe add some warnings. If there is a volume setting API in a particular Fruit Jam library, it could do some range limiting (and there could be a boolean to override that, for instance). Not sure if that makes sense or not

lone axle
#

that will include Fruit Jam library and OS, and any other project code.

tulip sleet
#

Are you saying there would be a new API that can set new ceilings on the various gains (volume control and speaker gain)? If you don't change the ceilings, it will limit the gain to the set ceilings and print a warning. I think that's what you mean?

#

the default ceilings would be safe for the included speaker

#

a ceiling on headphone volume would probably be good too, to save people's ears, though headphones have different characteristics.

lone axle
#

Maybe a loud_volume_protection boolean or similar as an init argument that defaults to True and disallows setting the level over a threshold.

tulip sleet
#

A printed warning is not going to be seen unless someone has the terminal open. And if they want to go above the ceiling (because they have a big speaker or whatever), then warnings you can't turn off would be annoying.

#

I was thinking of more quantitative limits instead of just a boolean. But the defaults would be appropriate for the supplied speaker. Could add .*_max setters/getters for each gain setting, or have a single call that sets them all (with optional arguments whose default values are the default ceilings)

lone axle
#

Okay, yeah re-reading your comment and thinking more I was coming to the same conclusion about numeric values instead of boolean.

We'll need to check how dac_volume interplayes with speaker_volume and headphone_volume.

tulip sleet
#

left/right, manual headphone, regular headpohone

lone axle
#

yeah that makes it trickier to effectively limit / warn

tulip sleet
#

does fruit jam os or the fruit jam library have a simplified volume/gain API?

#

The TLV library does not really need this API, I think.

#

It just needs warnings in the guides

lone axle
#

Not currently. It just exposes fruit_jam.dac currently and user code can do whatever with it.

tulip sleet
#

we are really talking about a particular speaker

lone axle
#

So, that is the place to start maybe. A helper volume function in adafruit_fruit_jam(and maybe helpers for setting headphone / speaker while at it) that simplifies the volume API down to only 1 thing, and then put the warning and enforcement there.

tulip sleet
#

a simple volume API for speaker and headphones (that does left/right together, etc.) might be welcome. And that API can do the limiting. This is off the top of my head. I haven't looked at the libraires at all

#

if the user wants finer control, it is up to them to use the .dac safely

#

what do all the non-Python ported games, etc., do?

#

did someone just choose appropriate volume ranges?

lone axle
#

I think so. For all of mine I believe I just copied the code from the TLV320 guide which included setting the volume levels. I assume Liz chose those values when writing the guide but havn't discussed with her.

#

Some of the existing projects use TLV320 library directly, they were written before the fruit_jam library. Once this change is in we ought to probably change them to use adafruit_fruit_jam so that all of our projects come with the warning / cieling mechanism that we add.

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 10.0.0-beta.2-7-g117b5d1ed9 on 2025-08-12; Adafruit Fruit Jam with rp2350b

Code/REPL

import audiobusio
import audiocore
import audiomixer
import board
import time

import adafruit_tlv320

# setup audio
i2c = board.I2C()
dac = adafruit_tlv320.TLV320DAC3100(i2c)

# load wave file
wave = audiocore.WaveFile("test16.wav")

# set sample rate & bit depth
dac.configure_clocks(
    sample_rate=wave.sample_ra...
lone axle
#

@wraith crow maybe hold off on further audio changes in your PRs for the moment. We are going to refactor the volume handling in Fruit Jam OS and existing apps to use a new simplified API in adafruit_fruitjam (see above conversation for details). I'm working on this now and it would be good to just do any changes to the apps afterward ideally.

turbid radish
#

I think an API for handling the sound would be welcome and provide a common codebase. The tvl320 is kinda tricky in some of its settings.

manic glacierBOT
manic glacierBOT
#

See https://github.com/adafruit/circuitpython/issues/10522#issuecomment-3132579164

As of https://github.com/adafruit/circuitpython/pull/9344 (included in 9.1.0-beta.4), we no longer always start the BLE workflow, including the file transfer service you mention. Read that PR and see https://docs.circuitpython.org/en/latest/docs/workflows.html#ble for information about how to enable the BLE workflow when booting.

manic glacierBOT
tiny peak
#

foamyguy & dan, re: discussion on DAC volume... FWIW, in my experience with doing a portable synth project for Fruit Jam, it was pretty useful to be able to directly access dac.speaker_mute, dac.dac_volume, and dac.headphone_volume. In my case I only cared about line level or headphone level output, but I can see how other projects might want to make more use of the built in speaker. I really like the idea of having the FruitJamOS API provide a simplified volume control interface with guard rails, but also letting people use adafruit_tlv320 directly if they want finer-grained control for synth projects.

lone axle
# tiny peak foamyguy & dan, re: discussion on DAC volume... FWIW, in my experience with doin...

I have submitted with some proposed changes. https://github.com/adafruit/Adafruit_CircuitPython_FruitJam/pull/13 This adds a new unified and simpler 1-20 volume scale on the adafruit_fruitjam.peripherals object with a limit argument to prevent it from going too loud without deliberate action from user code.

The dac remains accessible directly via fruit_jam.dac so all control that is possible with it can still be done too, but it will bypass the new simpler audio API and thus be a bit more "use at your own risk" with regards to damaging speakers.

#

Once the API is settled and merged I intend to go over the existing projects from Fruit Jam OS / learn and change any that access the dac directly to use this new API instead.

tiny peak
#

@lone axle Nice. After reading some of your and others' comments, I'm starting to suspect that the current adafruit_tlv320 library may include some AI hallucinated stuff, or maybe things with swapped endianness. For example, the Functional Block Diagram on page 19 of the datasheet shows that the left and right DAC blocks go to the speaker outputs by way of a 0 dB to -78 dB attenuation stage followed by a 6 dB to 24 dB class-D amplifier stage. That does not match the API documentation for dac.speaker_volume

#

similar problem with dac.headphone_volume: API docs say

The current headphone volume in dB. :return: The volume in dB (0 = max, -78.3 = min)

but the Functional Block Diagram shows a 0 dB to -78 dB attenuation stage followed by a 0 dB to 9 dB Class A/B amplifier stage

lone axle
#

@tiny peak It's possible there are bugs in the driver. I don't have any real knowledge or experience with audio or DACs so all of the different ranges listed are a bit of a mystery to me. If you find parts that don't match the datasheet feel free to submit PRs if you end up finding changes that make it match the datasheet more closely.

tiny peak
#

I may look into this some more. The datasheet is a 111 page monster and this DAC has quite a lot of features. It's not exactly straightforward.

lone axle
#

yeah, it's definitely got a lot going on inside of it. Docstrings and implementation details may have come from the Arduino version of the driver as well which the CircuitPython ones are typically ports of/from.

tiny peak
#

reading some more of the datasheet... there may actually be a third gain stage... sounds like maybe the chain is digital volume control for each of the left/right DAC, then analog attenuation, then analog amplification.

#

It kinda sounds like the designers' intended way for applications to control volume is to mainly adjust the digital left/right volume registers because those include a "soft-stepping" feature to spread the changes out over many samples to avoid clicks and pops. So, like, maybe you're supposed to dial the analog stuff in for your hardware in a semi-set-and-forget kinda way, then use the digital gain at runtime? Not sure yet.

manic glacierBOT
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.8 on 2025-05-28; Raspberry Pi Pico with rp2040

Code/REPL

# boot.py for pm2be_emulator

import supervisor
import usb_hid
...

PM2BE_REPORT_DESCRIPTOR = bytes((
0x05, 0x01,        # Usage Page (Generic Desktop Ctrls)
0x09, 0x00,        # Usage (Undefined)
0xA1, 0x01,        # Collection (Application)
0x05, 0x08,        #   Usage Page (LEDs)
0x09, 0x4B,        #   Usage (Generic Indicator)
0x15, 0x...
manic glacierBOT
#

indeed usage is currently limited to the range 1-65535 from the code here: https://github.com/adafruit/circuitpython/blob/117b5d1ed9bab67f91f852777bf4cec8ee8b53e4/shared-bindings/usb_hid/Device.c#L101

Page 32 of https://www.usb.org/sites/default/files/hut1_4.pdf does seem to indicate that 00 is a valid usage value for undefined.

If you want to try it out and are able to build circuitpython you could try changing the 1 here to a 0 and see if it allows proper emulation of your USB devi...

upper radish
#

It's early stages, but it builds

tiny peak
#

woah... what's that? do you have any plans for hooking it up to WebUSB, WebAudio, and such?

upper radish
#

(The broad strokes are blocked in: the REPL terminal, serial port connection, data plotting, syntax highlighting, and workspace management. Now working on refining everything. I've playfully been calling it Mu 2)

orchid basinBOT
orchid basinBOT
#

I think the JavaScript in download.js is not setting the OPEN INSTALLER buttons properly.
code is:

// update the links of the download buttons for the given langage menu item
function updateFileLinks(option, language) {
  var files = option.value.split(',');
  parentNode = option.parentNode.parentNode.parentNode;
  files.forEach(function(file) {
    var extension = file.substr(file.lastIndexOf('.') + 1);
    parentNode.querySelector(".download-button." + extension).href = file;
    if...
tulip sleet
manic glacierBOT
tiny peak
manic glacierBOT
#

Yes

On August 19, 2025, at 5:28 PM, Mikey Sklar @.***> wrote:

mikeysklar left a comment (adafruit/circuitpython#10572)

@b-blake what else are you modifying? Did you update the code.py as well?


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.Message ID: @.***>

[ { @.": "<a href="http://schema.org">http://schema.org</a>", @.": "EmailMessage", "potentialAction": { @.***": "ViewAction",...

thorny jay
#

I am slowly catching up on CPday video, and in the "What is new in 10.0" there was discussion about /sd and another partitions that would be visible (at least with the FruitJam) when you connect to your computer.
So I was wondering on the (new) meaning of storage.disable_usb_drive() would that hide all the USB partition, or do we need more granularity (like I want SD card to be visible but not CIRCUITPY drive).

tulip sleet
manic glacierBOT
manic glacierBOT
#

If everything in EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS is all zeros, then we could get away with not having this macro and instead using standard designated initializer syntax like below. I think this is easier to read.

epaperdisplay_construct_args_t construct_args = {
    .bus = display_bus,
    .start_sequence = display_start_sequence.
    .start_sequence_len = sizeof(display_start_sequence).
...
}

In C, if any fields are initialized, then the unmentioned fields in the i...

tiny peak
#

huh... that's weird

tulip sleet
#

you mentioned tinyusb when we talked

slender iron
#

Yes please

tiny peak
#

I think I may try hooking the Saleae up to the SDA and SCL pins on the GPIO header to see if I can watch what the driver is actually doing for the volume setters and getters

manic glacierBOT
tulip sleet
tiny peak
#

no. probably won't get to looking at it until tomorrow

tulip sleet
manic glacierBOT
tiny peak
#

@tulip sleet skimming through Adafruit_CircuitPython_TLV320
/adafruit_tlv320.py
, I see that def speaker_volume() calls self._page1._set_spk_volume(), which includes the line:

self._write_register(_SPK_VOL, value)

Then, _SPK_VOL is defined as _SPK_VOL = const(0x26) (page 1, register 38). On the Functional Block Diagram in section 1.4, Page 1 / Register 38 is "Analog Attenuation" for the left speaker channel (range 0 dB to -78 dB). That path also goes through the "Mono Class-D Speaker Driver" stage (Page 1 / Register 42=0x2A, range +6 dB to +24 dB). That register gets set by _configure_spk_pga(), which gets called by speaker_gain().

#

It's not clear to me why the registers for the right channel attenuation and speaker gain seem to be ignored.

#

but... it does seem at first glance that the bitfield shifting and masking for Page 1 / Register 42=0x2A are implemented correctly for the amplifier gain bits and mute bit

#

The most suspicious thing I see is this:

    @speaker_volume.setter
    def speaker_volume(self, db: float) -> None:
        """

        :param db: Volume in dB (0 = max, -63.5 = min)
        """
        if db > 0:
            db = 0
        gain = int(55 + (db * 1.14))
        gain = max(0, min(gain, 127))
        self._page1._set_spk_volume(route_enabled=True, gain=gain)

The comment says 0 dB to -63.5 dB, but that's the range for the digital volume control (Page 0 / Register 65=0x41 and Page 0 / Register 66=0x42). Also, the gain scaling and clipping does not seem appropriate. The correct range for Page 1 / Register 38=0x26 is 0 dB to -78 dB (table 6-106 in the datasheet)

#

So, it looks like the driver is conflating the digital volume adjustment stage (Page 0, registers 64..66) with the analog attenuation stage (Page 1, registers 38 and 37 for speakers plus maybe 36 for headphones)

lone axle
#

@tulip sleet do you know if there is any support in CircuitPython for hmac? Ladyada mentioned it may have been added at some point in the crypto stuff for matter or something else perhaps.

tiny peak
#

The proper values for setting Page 1 / Register 38=0x26 are listed in Table 6-24

tulip sleet
tiny peak
#

I made a scatter plot of TLV320 datasheet table 6-24 for the speaker volume register value vs. analog gain dB. It turns out to be a non-linear piecewise function, so the linear formula in speaker_volume() can't be right.

tiny peak
manic glacierBOT
#

Sorry, I do not have any link. PM2BE is just a name made up for the need to have some file name that makes some DIY context sense. It corresponds to Python Micro To Be Button Emulator where the number 2 means both “To” and “Two”. I do not currently know what the buttons do in context with the device’s real use. My impression is it is a controller with buttons. Why it is not using something like a game controller USB usage is a question.

manic glacierBOT
manic glacierBOT
#

from this explanation i didnt undersdtand what i need to do when build circuitpython image and inside ciircuitpy drive need add to enable frp ?

The BLE workflow is enabled for Nordic boards. By default, to prevent malicious access, it is disabled. To connect to the BLE workflow, press the reset button while the status led blinks blue quickly after the safe mode blinks. The board will restart and broadcast the file transfer service UUID (0xfebb) along with the board’s [Creation I...

manic glacierBOT
#

You don't need to change anything in the build, or add anything special to settings.toml unless you want to change the advertised name. But now, what you do need to do is to press the reset button when your status LED blinks blue. If you don't have an RGB status LED, then I think the plain status LED blinks.

We changed this so you have to take an action to start using the BLE workflow, because it was otherwise a security issue. Once you're paired/bonded, then it should start up automatic...

fiery pecan
#

Does CircuitPython make use of RTT (https://www.raspberrypi.com/documentation/pico-sdk/runtime.html#group_pico_stdio_rtt)? I think it would be a more effective alternative to https://adafruit-playground.com/u/SamBlenny/pages/circuitpython-core-dev-debug-tricks#fruit-jam-led-debugging-3205599. You don't even need the official Raspberry Pi Debug Probe. See the section labeled "Debug with a second Pico or Pico 2" under Appendix A of Getting started with Raspberry Pi
Pico-series
and the comments on https://github.com/raspberrypi/debugprobe/issues/175.

tiny peak
# fiery pecan Does CircuitPython make use of RTT (<https://www.raspberrypi.com/documentation/p...

woah... I didn't know about that! It sounds potentially really useful. Have you used that before with Pico-SDK on an RP2350? Do you have an impression of how much delay it adds? Does it work inside interrupt handlers? Do you need some special software to get the RTT messages? I actually have a pico debug probe, and the Fruit Jam board I'm using has a debug port. So, if that all works, it might be an interesting solution for me.

#

My tentative plan is to do some profiling in the USB stack using several GPIO pins and Saleae's Logic 2 software. If I set it up right, I'm expecting the resulting logic analyzer trace pulse waves will act kind of like a flame graph showing how much time gets spent in which function. Can RTT be used to do that sort of thing?

fiery pecan
fiery pecan
tiny peak
#

Do you have software you like for viewing RTT messages?

fiery pecan
tiny peak
#

ah... okay. I just came across a mention of that in connection with probe-rs as I've been reading up on RTT tools. Sounds like Segger has a tool called J-Link RTT Viewer for Linux that might possibly work, but it's not clear to me if that is tied down to only support their own debug probes.

tiny peak
#

hmm... interesting. I used openocd with the Raspberry Pi debug probe and a Feather RP2350 when I was messing with Zephyr stuff a while back. That worked pretty well. Thanks for the tips!

manic glacierBOT
manic glacierBOT
#

I believe I now understand the root cause of this problem. It has to do with priority inheritance and mutexes on FreeRTOS, which is the RTOS used by ESP-IDF.

FreeRTOS has some protection against priority inversion problems caused by mutexes. This is explained in detail here:
https://en.freertos.org/Documentation/02-Kernel/02-Kernel-features/02-Queues-mutexes-and-semaphores/04-Mutexes
A task holding a mutex can have its priority raised temporarily to prevent priority inversion deadlocks. It "...

tiny peak
tidal meteor
manic glacierBOT
#
  • Fixes #10570.

Use CIRCUITPY_AUDIOIO ?= 1 as the default, then turn it off for chips that don't have it with CIRCUITPY_AUDIOIO = 0. That way, it can also be turned off selectively as needed.

Also add some prominent comments to fence the choices for each chip type, to make it easier to find a particular chip's settings.

Also conditionalize CIRCUITPY_ALARM_TOUCH as being dependent on CIRCUITPY_ALARM on boards that support it.

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

I do not have the device that is to be emulated. I am investigating the emulation feasibility using Circuitpython on an RP2040/2350 class device. Thanks to you all and Frank Zhao it is possible to create the usb event driver side of the task needed to match the usb descriptor. Feasibility is being investigated on a pico with a few button switches. If successful, then the next platform will be an Adafruit Macropad running Circuitpython.

On Aug 20, 2025, at 11:45 PM, Dan Halbert @.**...

manic glacierBOT
#

This is a minor bug fix for the changes introduced in https://github.com/adafruit/circuitpython/pull/10567.

When adjusting the tempo on a MidiTrack source that is actively playing, the current note (or pause) is set to a duration defined by the previous tempo value until it runs out and a new note (or pause) is played and the duration is recalculated. This can cause de-synchronization if two MidiTrack sources are playing concurrently.

This update simply scales the remaining duration (wh...

manic glacierBOT
tiny peak
#

@lone axle are you actively working on volume setting fixes in the Adafruit_CircuitPython_TLV320 driver? (asking to avoid duplicating work)

lone axle
# tiny peak <@382939733107408897> are you actively working on volume setting fixes in the Ad...

I am not. My primary aim is to get the simplified version in the Fruit Jam library in place and then update the rest of our existing code to use it. It seems to work as is for moving the volume up and down. And we had some folks get blown out speakers so having the limiter in place will be good I think.

Improvements to the base TLV driver are welcomed but not something I'm actively working on at the moment.

tiny peak
#

okay. I'll continue with what I'm doing. There appears to be at least one significant bug in calculating speaker_volume register values. Maybe other things.

lone axle
#

Thank you for looking into it!

tiny peak
#

Yeah. This is fun stuff. Excited to see it all up and working and boards in stock in the shop.

#

Is there a guide somewhere that says how to do test builds for libraries to see if the .mpy and documentation builds will run without errors?

lone axle
manic glacierBOT
#

CircuitPython version and board name

LILYGO T-Display S3, ESP32S3

Code/REPL

async def _discover_services_task(self):
        if hasattr(self._connection, "_bleio_connection"):
            bleio_conn = self._connection._bleio_connection
            if hasattr(bleio_conn, "discover_remote_services"):
                # іноді треба трохи зачекати
                await asyncio.sleep(1.0)
                try:
                    await asyncio.sleep(1)
            ...
lone axle
#

@tiny peak The code that does it inside of the actions task is here: https://github.com/adafruit/workflows-circuitpython-libs/blob/3413c80af1b610fba8d653deec5bd9014a16895d/build/action.yml#L106-L110. I'm not 100% certain what all of the arguments get used for in that context but I've not found them to be terribly important for local testing. I usually do something like:

circuitpython-build-bundles --filename_prefix adafruit_fruitjam --library_location .

with filename_prefix filled in for whatever library I'm working in. This command gets run in the root of the library repo and builds the 9.x and 10.x mpy bundles. It requires https://github.com/adafruit/circuitpython-build-tools

manic glacierBOT
tiny peak
manic glacierBOT
#

Could you give an example that is not using your bleak layer, but just _bleio or adafruit_ble?

Yes, simply

from _bleio import UUID
from adafruit_ble import BLERadio
from adafruit_ble.advertising import Advertisement
from adafruit_ble.advertising.standard import (
    ProvideServicesAdvertisement,
    SolicitServicesAdvertisement,
)

radio = BLERadio()


scan_results = radio.start_scan(
    Advertisement,
    ProvideServicesAdvertisement,
    SolicitServicesAdvertisement,
   ...
#

Could you show a complete simple example to reproduce?

Where are you getting HCI TIMEOUT from? ESP32-S3 has native BLE and does not use HCI. But there are multiple LILYGO Display boards, both ESP32 and ESP32-S3. What is the exact name of the .uf2 or .bin file you're loading onto the LILYGO? I want to confirm it is the S3 Lilygo.

Possibly i'm wrong, but i found that: A Bluetooth error 0x07 indicates that a device is out of range or Memory Capacity Exceeded

#

Could you show a complete simple example to reproduce?

Where are you getting HCI TIMEOUT from? ESP32-S3 has native BLE and does not use HCI. But there are multiple LILYGO Display boards, both ESP32 and ESP32-S3. What is the exact name of the .uf2 or .bin file you're loading onto the LILYGO? I want to confirm it is the S3 Lilygo.

The latest one from https://circuitpython.org/board/lilygo_tdisplay_s3/
v9.2.8

orchid basinBOT
tiny peak
#

@tulip sleet what's the proper procedure to fix stuff like this after pulling newly merged upstream PR's into a local fork feature branch:

$ git status
On branch usb-find-unplug
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   frozen/Adafruit_CircuitPython_DotStar (new commits)

There were initially a bunch of git status lines about modified: frozen/... stuff. When I ran make update-frozen-libraries, it fixed most of them. But, the dotstar one is still left over.

tulip sleet
tiny peak
#

does what I saw mean there needs to be a PR to update the DotStar version in the CircuitPython repo?

#

kinda looks like the submodule commit ref is one tag behind the latest in the DotStar repo?

#

When I did this, it got git status to stop complaining:

$ cd frozen/Adafruit_CircuitPython_DotStar/
$ git checkout 163f2f166aee11d82303492bb1e5af4937e57b62
#

looks like that was something about fixing SPI locking to fix a funhouse crash

crimson ferry
tulip sleet
tulip sleet
crimson ferry
#

I checked it too, thought it would be a quick PR, but wasn't sure how to make it right

#

//| class UART.Parity and busio gets automagically pre-ended?

tulip sleet
crimson ferry
#

I'm not set up to build right now, but I could try that somewhat blindly... I don't suppose there's a way to test docs non-locally

tulip sleet
#

not that I know of. I'll take a look in a bit

#

fixing another problem now 🙂

tiny peak
#

danh, thanks for all the work wrangling releases. makes my head hurt just watching from the sidelines.

#

so. many. dependencies.

#

exciting to get all the new synthio stuff though

manic glacierBOT
tulip sleet
lone sandalBOT
manic glacierBOT
wraith crow
#

I'm working on a new board (https://www.olimex.com/Products/RaspberryPi/PICO/RP2350pc/) and I've got an initial CP firmware working with the DVI display, but when I try to enable PS RAM using #define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO8) the only thing I get on the serial console is "Serial console setup", nothing comes up on the USB console. Assuming their documentation is correct and the CS line is indeed GPIO8 is there anything else needed to get SPI PSRAM working on an RP2350 board?

#

ah ha 😁 I was just cleaning up and not expecting any change but the serial console displayed "tlsf_add_pool: Memory size must be between 20 and 9 bytes." A lead to follow......

#

and with CIRCUITPY_DEGUG_TINYUSB 1.... This prints continually

Serial console setup
*** PANIC ***
HardwSerial console setup
wraith crow
#

I believe I'm crashing on this instruction:

    // Try and read the PSRAM ID via direct_csr.
    qmi_hw->direct_csr = 30 << QMI_DIRECT_CSR_CLKDIV_LSB |
        QMI_DIRECT_CSR_EN_BITS;

in ports/raspberrypi/supervisor/port.c
This is deeper into the hardware than I was hoping to have to look :/

tiny peak
#

perhaps I'm misreading it. not sure

#

oh... I did miss some other stuff on the PSRAM_CS net. Looks like the Fruit Jam has that going to GPIO47 on the RP2350. hmm

#

What are you basing the new board off of? Is your source build defining some serial console stuff for TinyUSB debug or ESP32 AirLift serial out?

#

maybe those are trying to use GPIO8? I say that because the Fruit Jam ESP32-C6 module uses that pin for serial debug

wraith crow
#

Looking at the two schematics it did look like psram should work fine, I think the Metro RP2350 even used GPIO8

#

for the PSRAM chip select

#

My first message was probably misleading, the Olimex board is the new board (new for me 😁)

tiny peak
#

yeah, I got that part, I'm just wondering if you copied an existing board def to create the olimex board that you're working on

#

like, maybe there's some lingering use of GPIO8 defined in a spot that you overlooked?

wraith crow
#

I think I started from the Metro RP2350 but it could have been the Fruit Jam, I definitely borrowed from both

#

I looked pretty carefully for any GPIO8 conflicts, but I'll give it another look

tiny peak
#

what serial pins is tinyusb set to use?

wraith crow
#

I get a bit confused about the differences between tinyusb/uart/usb resources. The serial UART is using 0 & 1

tiny peak
#

I see in ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.h that there's a #define DEFAULT_UART_BUS_TX (&pin_GPIO8)

wraith crow
#
#define DEFAULT_UART_BUS_RX (&pin_GPIO1)
#define DEFAULT_UART_BUS_TX (&pin_GPIO0)
tiny peak
#

I'm trying to remember where I found the uart pin config stuff for TinyUSB. I was just looking at that the other day. Might be off in lib/tinyusb somewhere.

wraith crow
#

I think there's a way to turn off USB serial, maybe I'll dig up the setting and give it a try just to make sure there's no conflict from there....

#

err, I'm thinking that was on ESP and you could use the esptools to flash the bin. I don't know if there's an easy option on the RP2350 to do the same....

tiny peak
#

When you saw the error messages after doing the CIRCUITPY_DEGUG_TINYUSB 1 thing that you mentioned, are you sure that was the same error as was happening without enabling tinyusb logging?

#

I'm wondering if there's some lurking thing that defaults to sending TinyUSB uart logging data to GPIO8.

wraith crow
#

I decided the tinyusb PANIC message was a red herring and didn't really think about it much more. GPIO8 is used on the Fruit Jam to communicate with the ESP network coprocessor though so I suspect that would have problems if there was a conflict with tinyusb.

tiny peak
#

how long after the board boots are you hitting these errors? As I mentally review things I've heard people mention in relation to weird low-level bugs with bringing up different boards, I remember sometimes there's talk of adjusting oscillator startup delays.

#

that's about the extent of my knowledge on such things. curious to hear what you come up with if you figure it out.

wraith crow
#

Maybe a second after power up, I am using the PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 setting from the Fruit Jam and the PSRAM is the same part number.

#

Thanks, I appreciate the brainstorming, if I get it figured out there will probably be a PR to add the board 😁

tiny peak
#

yeah. good luck. I'm very curious to learn more about weird ways things can go wrong as I'm presently trying to track down some odd behavior in the USB stack.

wraith crow
tiny peak
#

nice!

#

I suppose you could just do a recursive diff on the board directories for the feather and your new-board-in-progress

#

maybe something will jump out

#

rogue ifdef... who knows

wraith crow
#

Yep, but unfortunately one of the first things that jumps out is that the feather is an rp2350a and this board is the rp2350b so there's going to be differences in how the port does things even if the board files are exactly the same. But at least I know the chip works and can be seen by CP

wraith crow
#

Well that was a lot of wasted time and noise for nothing, it had something to do with my build environment. I now have the dvi and the psram working, on to the next peripheral 😁 but that's enough for tonight!

crimson ferry
wraith crow
tiny peak
#

For people interested in improved TLV320DAC volume controls
( 🔥 🔊 😱 🚒 ), I've got a draft PR in progress at https://github.com/adafruit/Adafruit_CircuitPython_TLV320/pull/10

It's pretty far along. I found a few issues with the headphone signal chain, which my PR has fixes for. That includes a lower default volume for safe use with earbuds. I've tested that part, and I'm reasonably confident it's good. I also revised the doc-comments so the html docs built by Sphinx will be more complete (include some constants that got left out, etc).

Speaker signal chain still needs testing.

tiny peak
#

I tested the speaker, fixed a bug, and now it's ready for review and testing. Could probably use several sets of eyes and ears reviewing the proposed changes. From looking at the driver code, it seems like the default speaker volume was actually increased at one point, so there may be a project guide somewhere that uses the TLV320DAC with a higher wattage speaker. These changes are aimed at the 8Ω 1W speaker for Fruit Jam, so I'm not sure what the effect on other projects might be.

orchid basinBOT
#

As noted by a user on discord:

FYI, on the Circuitpython Downloads page for the Elecrow 3.5" touch LCD, https://circuitpython.org/board/elecrow_crowpanel_3.5/, the image is completely wrong - it's showing an epaper display iwth a case, not the 3.5" board with a touch LCD.

It turns out we did already have a crowpanel 3.5 photo, but the .md file had been pointing to the wrong image. But I did swap it to a new image that shows the LCD rather than the back of the board along with correcti...

lone axle
#

@tulip sleet when you have a moment I'm curious about hmac from back on the Matter work. Is/was it ever usable from CircuitPython? or how big of a barrier would there be to enabling it? The interest arises now because it seems to be necessary for modern AWS auth. The AWS_IOT library uses an older one that is no longer supported I think. I am looking into using amazon polly TTS service for a project idea from Limor.

lone axle
#

Yeah, following up on this. Between the micropython hmac implementation and adafruit_hashlib I was able to successfully make a request to AWS 🎉 blinkacomputer

tiny peak
#

that might also be useful for generating TOTP codes?

lone axle
tiny peak
#

can it do hmacsha1 and hmacsha256? IIRC, that should cover what most auth services need.

lone axle
manic glacierBOT
#

The unknown error here is "not connected". I'm not sure why you became disconnected. Can you try it with something other than the bitchat app, like some simple BLE peripheral?

Normally one wouldn't call connection._bleio_connection.discover_remote_services() directly, but instead use the adafruit_ble API. Some examples are in https://github.com/adafruit/Adafruit_CircuitPython_BLE/blob/main/examples. For instance ble_uart_echo_client.py does scanning, and ble_uart_echo_test.py acts as...

lone axle
#

@tiny peak is dac_volume intended to control output from the speaker? In testing it seems like raising and lowering it does not change how loud the audio coming from the small JST speaker is.

tiny peak
#

speaker chain is dac_volume -> speaker_volume -> speaker_gain, and 1 dB of change to any of those should sound approximately the same as 1 dB of change to another (note that speaker_gain step size is 6 dB though)

#

What code are you using to test with?

#

if you're using my test code, the "q" for +1 dB and "z" for -1dB dac_volume adjustments are pretty subtle. You should be able to hear a definite change by the time you move ±6 dB though

#

Also, when you say "small JST speaker", do you mean the 8Ω 1W mini speaker from the Fruit Jam kit? That's what I calibrated to.

lone axle
# tiny peak What code are you using to test with?
from adafruit_fruitjam import FruitJam

fj = FruitJam()

print(f"dac_vol: ", fj.peripherals.dac.dac_volume)
fj.peripherals.dac.dac_volume = -40
print(f"dac_vol: ", fj.peripherals.dac.dac_volume)

fj.peripherals.dac.headphone_output = False
fj.peripherals.dac.speaker_output = True

print(fj.peripherals.dac.speaker_volume)
# fj.peripherals.dac.speaker_volume = -1
print(fj.peripherals.dac.speaker_volume)

fj.peripherals.play_mp3_file("saves/awspollyoutput.mp3")

But play_mp3_file() is new and not in the released library. It is the mp3 version of play_file() which does wav files.

lone axle
tiny peak
#

dac.speaker_output is a magic change-lots-of-stuff-at-once property that will overwrite previous changes to dac_volume

#

I'd recommend having a go with the test code that I posted in the PR, or at least using the same order of property setting calls

#

the tester is set up with a continuous tone, then you can use keys above the QWERTY left hand home row to increase various volume / gain settings and keys below the home row to decrease them.

#

spacebar will toggle the speaker amp power, so you can compare headphone jack noise level with and without the speaker turned on

lone axle
#

Okay, I commented over on the PR, I'd like to add that as an example in the repo if possible.

tiny peak
manic glacierBOT
manic glacierBOT
tulip sleet
#

Thanks @lone axle !

lone axle
#

Thanks everyone. Have a great week 👋

uncut nexus
#

thanks @lone axle

tiny peak
#

@lone axle I'm working on example code for you for the TLV320 PR. Ruff absolutely despised my coding style for the existing example code, so I'm having to rework it a bit.

lone axle
tiny peak
#

I tried that, but it didn't seem to work. do you have examples of known working noqa comments?

lone axle
# tiny peak I tried that, but it didn't seem to work. do you have examples of known working ...

There is a line that disables one of the rules: https://github.com/adafruit/Adafruit_CircuitPython_Display_Text/blob/7d1f187aac8e899e791324cc78633bf4f32c984b/adafruit_display_text/text_box.py#L267 you can specify different or multiple rules by changing F841 to whatever rule you want it to ignore. Then by custom we put a "human readable" comma seperated list of the disabled rules at the end of the comment as well.

tiny peak
#

okay, thanks. I'll have another go at that. Might be I put the comment on the wrong line

lone axle
#

Here is the notes document for the next CircuitPython Weekly Meeting. It is in two weeks on September 8, 2025 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/10SvxnkxPP0HhgSv0_x4WXYV0ySvnUcm6KjmpRXEPlUQ/edit?usp=sharing

tiny peak
tiny peak
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.8 on Pico W RP2040
Hard fault: memory access or instruction error.

Code/REPL

# This script supports the Raspberry Pi Pico board and the Lilygo ESP32-S2 board
# Raspberry Pi Pico: http://educ8s.tv/part/RaspberryPiPico
# ESP32-S2 Board: http://educ8s.tv/part/esp32s2
import board, busio, displayio, os, fourwire
import adafruit_ili9341

import time, rtc
import wifi
import socketpool
import microcont...
#

The unknown error 7 here is a Nimble "not connected" error. I'm not sure why you became disconnected. Can you try it with something other than the bitchat app, like some simple BLE peripheral?

Normally one wouldn't call connection._bleio_connection.discover_remote_services() directly, but instead use the adafruit_ble API. Some examples are in https://github.com/adafruit/Adafruit_CircuitPython_BLE/blob/main/examples. For instance ble_uart_echo_client.py does scanning, and `ble_ua...

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

I was able to approximately reproduce this problem on 10.0.0-beta.2. The original test program has some extra complications that were unrelated problems. For instance, doing list(connection) fais in any case because a connection is more like a dictionary than a sequence. I will be adding some type-checking code to adafruit_ble to make that error more obvious.

The fundamental problem is that this particular device, the LEGO WeDo 2.0 BLE thing, causes a `MemoryError: Nimble out of memory...

manic glacierBOT
manic glacierBOT
#

It was coded/programmed to pin GP5 and GP7. It crashed immediately at startup

Van: Dan Halbert @.>
Verzonden: dinsdag 26 augustus 2025 19:05
Aan: adafruit/circuitpython @.
>
CC: marcelwijn @.>; State change @.>
Onderwerp: Re: [adafruit/circuitpython] Core code crashed (Issue #10583)

https://avatars.githubusercontent.com/u/2847802?s=20&v=4 dhalbert left a comment (adafruit/circuitpython#10583) <https://github.com/adafruit/circuit...

slender iron
manic glacierBOT
#

-- Fixes #10533

On Fruit Jam and Metro RP2350, a usb_host.Port object is always created on restart, using board.USB_HOST_DATA_MINUS and board.USB_HOST_DATA_PLUS. However, the pins were not claimed in common_hal_usb_host_port_construct(). This made them accidentally available for other uses, such as trying to create an I2C object, and could cause crashes.

This PR claims the pins so they can never be used for anything else, and prevents crashes. Perhaps it should be possible t...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

CircuitPython version and board name

CircuitPython 9.2.8 on Pi Pico RP2040 with adafruit_irremote 5.0.5

same behaviour:
10 beta 2 on Feather RP2040
10 beta 2 on WeAct STM32F411CEU6

Code/REPL

print("code.py")

import board,time
import pulseio,adafruit_irremote

# Maxlen is set high to mitigate a separate hard fault issue encountered, Adafruit_CircuitPython_IRRemote issue #76
pulsein = pulseio.PulseIn(board.D4, maxlen=600, idle_state=True)
decoder = adafruit_...
manic glacierBOT
lone axle
#

Would we want to bring the micropython implementation of hmac into the bundle as adafruit_hmac.py? Or if I am going to use it within a project should I just include hmac.py in with my project files?

manic glacierBOT
#

Thanks for the testing! I saw similar issues on the C5 and assumed it was a C5 issue. So I moved on. I see similar issues on the C6 and ESP32 so I'm hunting it down. I'm hopeful it'll fix all of the different variants and the C5. They added support for picolibc instead of newlib and that may have messed up some of the linking. I'm not sure, and still looking into it. I'll undraft after I've smoke tested successfully on a number of chips.

tulip sleet
#

@slender iron fyi I am working on updating pico-sdk and cyw43-driver because we are behind on these (your inlining of the critical section routines is now in pico-sdk)

#

thought it might fix some RP2 wifi issues but I am not optimistic

slender iron
#

kk, always good to stay up to date on them. I don't really like debugging when we're behind

#

thach merged in the c5 and c61 defs so I can switch back to upstream tinyusb too

empty salmon
#

Status LED Blink Codes

I am sure I asked this before but can't find the prior answer and internet searches failed me.

What are the 'blink codes' for the non-neopixel LED?

I am working on a new M0 board (SAMD21G18).

  • I put it in bootloader
  • I drag/drop my CircuitPython build
  • The upload finishes
  • the board boots
  • the status LED blinks 5 times

UPDATE: I just tested a similar board from last year - my COIN_M0 - and I get the same behavior.

Tested with 9.2.4, 9.2.8, and 10.0.0.b2

empty salmon
slender iron
#

5 blinks at the start is probably the 1 second of safe mode blinking

empty salmon
slender iron
#

I'd use SWD

#

and GDB

empty salmon
#

The plot thickens. I found my original test from the prior release. I didn't load new code.
I connect to a Windows 11 machine and I see CIRCUITPY. I use the same cable and PCB and connect it to MacOS 15.6.1 and no mass storage device.
When I run the same test with my new PCB version I get the mass storage under Windows and no mass storage with MacOS.

manic glacierBOT
#

Update pico-sdk submodule to raspberrypi 2.2.0 and cyw43-driver to v1.1.0, to bring them up to date. I have a tiny hope this might help some wifi problems. But we should be up to date anyway.

I had to do -DUSE_SDIOIT for CYW43 to prevent a compiler warning. See https://github.com/georgerobotics/cyw43-driver/issues/140

Tested on Pico W and Pico 2 W. Both passed a simple wifi test.
Tested on Fruit Jam. HDMI output still works. Also did a small I2C test.

@FoamyGuy If you have a chanc...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

The learn guide here: https://learn.adafruit.com/circuitpython-essentials/circuitpython-mp3-audio mentions:

Because creating an MP3Decoder object takes a lot of memory, it's best to do this just once when your program starts, and then update the .file property of the MP3Decoder when you want to play a different file. Otherwise, you may encounter the dreaded MemoryError.

And the constructor of MP3Decoder notes about the file argument https://docs.circuitpython.org/en/latest/shared-bin...

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 10.0.0-beta.2 on 2025-07-31; M5Stack Cardputer with ESP32S3
Board ID:m5stack_cardputer

Code/REPL

No code

Behavior

With Adafruit CircuitPython 9.2.0 on 2024-10-28; M5Stack Cardputer with ESP32S3 the cardputer v1.0 (S3) and v1.1 (S3A) work fine.

But when upgraded to 10.0.0-beta2, with Open Installer, the board bootloop with the screen blinking with just the boot message, never appeari...

empty salmon
# slender iron I'd use SWD

More testing points to a MacOS issue (I am running 15.6.1 on Apple Silicon).

I have tested my new board, my old board, and an Itsy Bitsy M0.

They all exhibit the same issues: no mass storage device and no serial device.

Using system_profiler SPUSBDataType does show the board.

tulip sleet
manic glacierBOT
#

I am slowly catching up on CPday video, and in the "What is new in 10.0" there was discussion about /sd and another partitions that would be visible (at least with the FruitJam) when you connect to your computer.
So I was wondering on the (new) meaning of storage.disable_usb_drive() would that hide all the USB partition, or do we need more granularity (like I want SD card to be visible but not CIRCUITPY drive).

empty salmon
tulip sleet
empty salmon
tulip sleet
#

and you did reboot already?

empty salmon
#

Yes. Once. I can do it again.

tulip sleet
#

i am at a loss otherwise. I'll upgrade my macOS 26 and see if it's having troubles too. Other mac i have is stuck on Ventura (Intel)

empty salmon
#

There was a post about a week ago ...
#circuitpython-dev message
... that I just found. It sounds similar (but could be a red herring)

empty salmon
devout jolt
tulip sleet
#

@empty salmon @devout jolt I just upgraded to the latest macOS 26 beta, beta 8. I tried an Itsy M0 running 8.2.10 and then upgraded it to 10.0.0-beta.2. I unplugged it and replugged it several times, with and without ejecting properly, and also then wrote some files to it and repeated unplugging and replugging it. It did not disappear, and I was able to see the BOOT drive to, to update it.

#

This is a Mac Mini m1

manic glacierBOT
#

Summary

I added a port-specific module, RTC to ports/analog. Now the analog port can handle rtc.set_time_source(), rtc.RTC() and r.datetime(). Note that the RTC calibration functions (common_hal_rtc_get_calibration() and common_hal_rtc_set_calibration()) are not implemented and are planned for the near future.

The implementation in the RTC module also enables two functions in the time module, which are time.time() and time.localtime().

The following example prints the c...

empty salmon
tulip sleet
#

This would be the fourth or fifth time Apple has broken something about FAT filesystem access.

#

You could try doing a backup on some other machine and then doing storage.erase_filesystem() and see if that helps.

empty salmon
tulip sleet
#

yes

empty salmon
# tulip sleet yes

OK. I will give that a try on my Windows machine. I will also do some testing from Linux.

tulip sleet
#

if you and @devout jolt can file bugs via Feedback Assistant, that would help. You could cross-reference each other's

empty salmon
empty salmon
tulip sleet
#

I looked at the release notes for 15.6 and 15.6.1 and as usual they are useless. I think 15.6.1 was a hurry-up release for that zero-day re image files

devout jolt
empty salmon
empty salmon
#

As an entry for the record, here is the output from system_profiler which shows my M0 board is recognized as a removable media even though Finder does not show the mass storage device ...

        ECCN M0:

          Product ID: 0x5687
          Vendor ID: 0x1209
          Version: 42.01
          Serial Number: F159672950304A46462E3120FF143327
          Speed: Up to 12 Mb/s
          Manufacturer: Bradán Lane STUDIO
          Location ID: 0x02100000 / 1
          Current Available (mA): 500
          Current Required (mA): 100
          Extra Operating Current (mA): 0
          Media:
              Capacity: 8.2 MB (8,192,000 bytes)
              Removable Media: Yes
              BSD Name: disk4
              Logical Unit: 0
              Partition Map Type: Unknown
              S.M.A.R.T. status: Verified
              USB Interface: 2

Important: There is an error in the report. The flash chip on the ECCN M0 is only 4MB. I do not know why it is reporting 8.2MB when in 'bootloader' mode. It does show 4.2MB is 'run' mode.

     Coin M0:

          Product ID: 0x5687
          Vendor ID: 0x1209
          Version: 1.00
          Speed: Up to 12 Mb/s
          Manufacturer: Bradán Lane STUDIO
          Location ID: 0x02100000 / 1
          Current Available (mA): 500
          Current Required (mA): 100
          Extra Operating Current (mA): 0
          Media:
            Coin M0:
              Capacity: 4.2 MB (4,190,720 bytes)
              Removable Media: Yes
              BSD Name: disk4
              Logical Unit: 0
              Partition Map Type: MBR (Master Boot Record)
              S.M.A.R.T. status: Verified
              USB Interface: 2
              Volumes:
                disk4s1:
                  Capacity: 4.2 MB (4,190,208 bytes)
                  File System: MS-DOS FAT16
                  BSD Name: disk4s1
                  Content: DOS_FAT_16
manic glacierBOT
manic glacierBOT
devout jolt
manic glacierBOT
#

A bisect was infeasible because between alpha.7 and alpha.8 was a merge from MicroPython with hundreds of unbisectable commits. However, I found that commenting out this in mpconfigboard.mk:

SRC_C += boards/$(BOARD)/cardputer_keyboard.c

got rid of the boot-loop and allowed input to work again (at the expense of the on-board keyboard, of course). So I'll take a look at that code.

slender iron
#

@lone axle there is an open method on mp3decoder that takes in a new filename

manic glacierBOT
#

The problem is that common_hal_keypad_demux_demuxkeymatrix_construct() allocates heap objects, but cardputer_keyboard.c wants to allocate an object that lives longer than a VM. So the constructor needs to be aware of this, probably in the style of common_hal_lvfontio_ondiskfont_construct(), which as a use_gc_allocator argument. I may want to generalize the allocation/deallocation routines used by lvfontio, since this is pretty much the same thing.

lone axle
empty salmon
manic glacierBOT
#

Right now the web workflow only works when the ESP32 joins an existing WiFi network.
It would be very useful if CircuitPython on ESP32 could start its own WiFi access point, so a computer/phone can connect directly to it.

This helps in cases where:

1] No router / internet is available (off-grid, field use).

2] User prefers not to connect through external WiFi.

The AP mode wouldn’t need extra features beyond what already exists — just the same web workflow but hosted on the ESP32’s own WiF...

#

In the past, we used cardputer without the keyboard support and keyboard was done with KeyMatrix in software/python.
The next cardputer (cardputer adv) will have an I2C keyboard with a TCA8418 (this is an adafruit supported chip available and with a CP driver)... free GPIO will be exposed for expansion module. So while current cardputer works on v1.0 and v1.1, it will not work the same on "ADV".

If you make the CP10 version of cardputer keyboard less, at least it will work, even if it will n...

manic glacierBOT
manic glacierBOT
#

I've started looking into this but haven't found an obvious issue. I am able to reproduce it.

My theory about interrupts appears to be wrong. If I blink the LED for every interrupt, it appears to continue the same during the black period. I haven't confirmed with a logic analyzer though.

There is also no long SPI transfer. I'm seeing lots of little ones instead.

My next theory is that we're trying to push too much through the memory bus and throwing off the DVI timing. However, slowing the...

manic glacierBOT
#

I have not tried the smaller resolution specifically with the reproducer script but I can tomorrow. I have definitely seen the same issue appear with other projects that use the 320x240 resolution though. The say and spelling project I'm working on now uses that and shows this same behavior when downloading MP3s.

The product overlay project that I've been working on with JP also uses 320x240 resolution and has the same blanking happen.

empty salmon
# tulip sleet I looked at the release notes for 15.6 and 15.6.1 and as usual they are useless....

It's likely unrelated but ...

today, when testing both my COIN_M0 and the Itsy Bitsy M0 running both 9.2.8 and 9.2.1 under Windows 11 (with the most recent major pack?) I was having problems saving code.py - I would throw an error and if the device had disconnected. I would have to unplug / replug to sort it but "save" would cause the problem to occur again. I tested with multiple USB cables and different USB ports.

empty salmon
tulip sleet
#

Thonny does not write to CIRCUITPY directly. It sends invisible commands to the REPL (file.write(...)) etc.

#

it's not a good test of CIRCUITPY access

empty salmon
#

I thought a "file save" from thonny did an actual "file save".

#

I did not use "run".

tulip sleet
#

it still uses REPL commands, I think. That way it runs smoothly on non-USB boards that can't support CIRCUITPY USB access.

empty salmon
#

I will test with a simple file copy then.

tulip sleet
#

maybe not, though, because CIRCUITPY would be read-only to the REPL, on second thought. I may be making this up

somber garden
empty salmon
#

I know thonny's "run" is done by streaming the Python into the REPL.

somber garden
#

Interestingly, it recommends Thonny

tulip sleet
#

I wrote that section 🙂

empty salmon
#

I have used Thonny extensively but to rule it out, I will just try "copy" from the file system.

somber garden
#

That's me taught then :)

tulip sleet
#

no, i appreciate it, and I didn't remember exactly how I recommended Thonny. It was a real problem earlier on with a lot of editors that they didn't flush to disk

somber garden
#

Back when I was using Notepad++ on Windows I noticed the bad disk flushing, so I

  • saved locally
  • created a desktop shortcut to a script that copied files to the circuitpython device
  • Gave a the desktop shortcut a keyboard shortcut
    So all I had to do is save, then do something like "CTRL+ALT+S" or whatever to upload it.
empty salmon
#

I teach my CircuitPython workshops using thonny. For that, I use an RP2040 based design. It's been great.

#

I will focus on getting a reproducible flow on Windows and test with a couple different M0 boards.
Theoretically, they should all be stable.

manic glacierBOT
#

Right now there is no standard hook mechanism to do some C initialization in a general way after the VM starts. That was how I was thinking of creating the cardputer keyboard object on each VM instantiation. I could add something.

MicroPython has a _boot.py file which is usually frozen in that runs startup code for the VM. Often this mounts the filesystem, etc. However, MicroPython runs boot.py, _boot.py and main.py all in the same VM (if I remember right).

We have no such mechanism...

sharp hazel
#

hi friends what's a good font for small text on those 64x32 matrix leds? the default terminalio.FONT builtin is ok but if there were one only like 6 or 7px tall that was still legible i'm curious

#

i want to put 4 lines of text on the screen (or one large one on top and two small below) and i'm not sure how to begin with that. i'm novice to python but do have a little bit going so far just not sure how to properly address matrixportal (using the ESP32-S3 based matrixportal fwiw, the docs seem really towards the M4?)

crimson ferry
#

there are few small fonts around, 5pt and up, not sure where I got them (maybe various learn guides), but if you search you may find them: l_10646, LEDBDREV, MartianMono, NotoSans, PressStart2P, roboto, RobotoMono, tahoma, verdana

sharp hazel
#

THANK YOU! i appreciate you taking the time to distill a shortlist for me , i will search out!

#

i tried the roboto, tahoma, verdana 8pt and wasn't happy, didn't try smaller but lemme try the rest on that list and in diff sizes

crimson ferry
#

there are verdana 5-7, tahoma 5-8, several roboto 5pt and up

sharp hazel
#

ok yeah that's what i found too i just hadnt tried them all yet, and the first few i plucked out didn't seem to be as legible as the default terminalio.FONT builtin

#

ill play with some more and see... next then is to figure out how to address the screen right and i guess that's labels?

#

i'd like to have a simple way to address the rows of the screen and "paint" to them

crimson ferry
#

displayio works the same whether it's M4 or S3

sharp hazel
#

ok thanks, ill look there. maybe that's what ive been missing.

#

brand new to this ecosystem

#

my project is to make a SPL monitor to connect to my Smaart SPL logging system's websockets API... i figure'd there has to be some sort of portable asyncio out there right it's got wifi, could just have it live display in the front of house

crimson ferry
#

there is asyncio, but you're at the mercy of the blocking granularity of each module or library

#

but it can still be a huge help to get things multitasking

sharp hazel
#

which is sorta-ok cuz i dont really expect more than an update every second or three, faster refresh would be ideal but my tolerance is huge here

#

it's just going to be going the whole time at events as a audience display

#

yeah ust 3x values from a json blob from a websockets endpoint printed to the screen, that's basically it

crimson ferry
sharp hazel
#

oh hahaha sorry yes indeed, ill post there - did not realise the distinction

manic glacierBOT
#

My experience: none of my devices can connect for web-workflow. In normal operation, I always need multiple calls to wifi.radio.connect() to establish a connection. This is true for both the Espressif and the RP2xxx port. The web-workflow in contrast uses a single try. This could also explain why this works for your "normal wifi", but not for the hotspot which maybe just needs to try harder.

I analyzed the code (again for both ports) and I think it has a flaw: it bails out on the first err...

manic glacierBOT
#

CircuitPython version and board name

CircuitPython 10.0.0-beta.2-20-gedc82ddfee-dirty on 2025-08-29; linux [GCC 14.3.0] version
Adafruit CircuitPython 9.2.8 on 2025-05-28; S2Mini with ESP32S2-S2FN4R2

Code/REPL

from collections import deque

class Deque(deque):
    def __init__(self, values, maxlen):
        super().__init__(values, maxlen)

    def append(self, value):
        super().append(value)

d = Deque([1, 2], 3)
d.append(3)
print(list(d))

Be...

empty salmon
solar whale
#

Just curious. The Library Bundle has not been updated since August 10. Is that expected? Several libraries have been updatded since then.

lone axle
#

That was due to Github disabling cron actions automatically when there are no commits in a repo for 60 days. These jobs are inside of the adabot repo currently. There is an open issue to move the reports task to a different repo to avoid the problem. Looks like some more tasks will benefit from that move too.

#

I re-activated just now with the button so the tasks should run correctly on their next scheduled attempt.

manic glacierBOT
#

This resolves: https://github.com/adafruit/adabot/issues/373

If merged, should happen at the same time as merging: https://github.com/adafruit/adabot/pull/403 in order to avoid duplicated task runs from the different repos.

The only change made from the original workflow files was the addition of repository: 'adafruit/adabot' inside of the actions/checkout task in two of the workflows.

It seems like the rest should work to me, but it tough to say for sure without having it try t...

lone axle
slender iron
#

@tulip sleet I think I have a fix for the blanking. wait on beta.3 for me please

#

(blanking during esp32spi request)

tulip sleet
empty salmon
#

I think I missed something with my COIN_M0.

Two questions:

Question 1:
I have Adafruit_CircuitPython_NeoPixel frozen and I have CIRCUITPY_FULL_BUILD = 0.

It seems I need to explicitly add neopixel_write to my COIN_M0 board using CIRCUITPY_NEOPIXEL_WRITE = 1.

Is this correct?

Question 2:

I have not built in a while. I now get `Minimum GCC version 14" but I do not see where I get GCC version 14 for atmel-samd boards.

tulip sleet
#

= 1?

empty salmon
#

(sorry, I am so used to Discord on mobile that on desktop, ENTER keeps submitting my post)

tulip sleet
#

CIRCUITPY_NEOPIXEL_WRITE ?= 1 is in py/circuitpy_mpconfig.mk, so it should be on by default. However, neopixel is not frozen in by default.

empty salmon
#

I add FROZEN_MPY_DIRS += to add it to my board. after the build, when I use import neopixel I get the error from neopixel.py line 20 with is the neopixel_write.

tulip sleet
#

if you just do an import neopixel_write in the REPL, does it fail?

manic glacierBOT
tulip sleet
#

could you upload your mpconfigboard.mk using the + to the left or point me to it?

manic glacierBOT
slender iron
empty salmon
#

(and sorry for the slowness but me dev env is a mess because I build in a VM on Mac but mac currently can load CP so I have a remote into a Windows machine for uploads) BLECK!

tulip sleet
#

you can do make print-CIRCUITPY_NEOPIXEL_WRITE BOARD=bradanlanestudio_coin_m0 to see what it thinks the value is

#

do a make clean before a build if you change the .mk files

tulip sleet
empty salmon
tulip sleet
#

so do a rebuild an then try import neopixel_write

keen field
#

Is this the right place to ask about my struggles to get two pi pico cowbell can bus hats to communicate with each other? The write buffers just fill up like nothing is being sent out.

tulip sleet
#

this is more for core development discussions

slender iron
#

@lone axle want to wait on the cron changes until next week when we can watch it to make sure it is working?

lone axle
#

Yep sounds good to me.

slender iron
# lone axle Yep sounds good to me.

I'm not working again until Wednesday but you can do it Tuesday if you like. I'll hold off to approve though so it doesn't get done over the long weekend. Thanks for doing it!

manic glacierBOT
empty salmon
#

sorry for all the bothering. ... I am feleing pretty dumb at the moment.

I now have the newer GCC for atmel. When I build I get an error OPT_OS_ZEPHYR is not defined. It's coming from .../supervisor/shared/usb/usb.c

tulip sleet
#

your submodules may be out of sync: Run this:
alias gitsubupdate='git submodule sync --quiet --recursive && git submodule update --init --filter=blob:none'

#

i mean run what the alias does. You might find the alias useful

empty salmon
#

I get a git usage error

#

when I break it into two commans, the first is good

tulip sleet
#

take out the --filter=blob:none. Sounds like your git is somewhat old

empty salmon
#

FYI: git is 2.34.1

tulip sleet
#

it will save time on git fetches

#

have you consider updating to macOS 26 beta or is that too dangerous?

empty salmon
#

I can not afford to trial beta OS

#

too many other projects coudl break

tulip sleet
#

can you back out 15.6.1? I know Apple makes that hard

empty salmon
#

as it is I have to keep cp dev in a VM

#

apple makies it excrutiation to revert

tulip sleet
#

i do remember that from previous attempts

empty salmon
#

serve me right for accepting the update in the first place

tulip sleet
#

well, it was an important zero-day fix. were you updating from 15.6 or earlier?

#

this is all kinda why I use very standard linux for a dev machine

empty salmon
#

15.6.0 to 15.6.1

#

I may take an old windows laptop and nuke it for linux

#

I have a few that are more than good enough for CP development

#

as a matter of fact, I will add that to my to-do list

slender iron
#

@tulip sleet another fix incoming

#

🙂

tulip sleet
#

I am going to test the FruitJam on a usable monitor...

manic glacierBOT
slender iron
#

I suspect #10564 is the same psram issue

manic glacierBOT
tulip sleet
slender iron
#

ya, it is more complicated because PIO can't just wait for more bytes and work the same

manic glacierBOT
#

Got a Cynthion capture working to see what's going on between the gamepad and the Fruit Jam as I run this test code. Looks like the USB transaction to check the device descriptor is working fine on the wire. So, I'm guessing that means that somewhere in TinyUSB or the CircuitPython USB stack, that data isn't getting copied as it should (hence the all zero buffer thing).

This is the Packetry capture:

<img width="986" height="704" alt="Image" src="https://github.com/user-attachments/assets/2e...

#

Turns out It makes a difference whether I use the Adafruit generic SNES gamepad (low speed USB) or an 8BitDo SN30 Pro wired gamepad (full speed USB). With the SN30 Pro, I get the behavior shown in the previous comment (immediate all zero descriptor reads after the first successful read). With the low speed Adafruit gamepad, the all zero descriptor reads don't begin until I unplug the gamepad.

slender iron
#

w00t. yay for bug fixing

tulip sleet
#

@slender iron ok, I will make a release unless you have anything else.

manic glacierBOT
#

I did another capture for the low speed gamepad. On the Cynthion side, it looked pretty much the same with a long series of successful 18-byte device descriptor read requests happening at about 5ms intervals and lasting until I unplugged the gamepad.

On the serial console side, the descriptor reads were successful (no errors about all zero result) until I unplugged the gamepad. After I unplugged, I started getting all zero descriptor error messages. When I let that run, it lasted until `Cons...

manic glacierBOT
#
[adafruit/circuitpython] New tag created: 10.0.0-beta.3
#

If I change the reproducer code to have time.sleep(0.01) (10ms) before each attempt to read the device descriptor, then the SN30 Pro (full speed) acts like the Adafruit gamepad in that it's fine until I unplug the cable. But, if I increase the sleep to 20ms, then unplugging doesn't cause the all zero descriptor errors. Smells like there's some kind of queue getting backed up or transaction that takes a while to timeout.

orchid basinBOT
manic glacierBOT
manic glacierBOT
#

This pull request is to add the neopixel_write and pixelbuf modules to the build for the COIN_M0. This is to enable 'out of the box' support for neopixels ~(which is already a frozen library for the board)_.

A full new CircuitPython 10 build environment was used to build and deploy. The contents of boot_out.txt are provided for reference:

Adafruit CircuitPython 10.0.0-beta.2-23-g4b2624a27b on 2025-08-29; Bradán Lane STUDIO Coin M0 with samd21g18
Board ID:bradanlanestudio_coin_...
empty salmon
#

I build a new dev environment and have successfully build, deployed, and tested the COIN_M0 with 10.0.0-beta.2.
It goes without saying this is usually a rough step for me but I have submitted the PR.

(The usual thanks yet again to @tulip sleet and @slender iron for patiently working with me to get this fix working).

manic glacierBOT
#

@bradanlane

This board has external flash, so it's more like Feather M0 Express than, say, Trinket M0. So there is a lot more room, and you don't need to turn off so many modules.

I would suggest using something like the feather_m0_express/mpconfigboard.mk. You can turn off modules that are useless, but I'd leave LONGINT_IMPL = MPZ so you can have longints. And don't set CIRCUITPY_FULL_BUILD = 0. Just remove it and it will default to CIRCUITPY_FULL_BUILD = 1. Then you can turn ...

#

The coin m0 was originally based off the Itsy Bitsy (about a year ago).

One reason so much is turned off is the coin m0 is a "feature" board and has no exposed IO pins. It really only has SAMD21 analog audio to an onboard piezo, 3 touch pads, and 9 neopixels.

I am reticent to make too many changes as it should then be fully tested again.

I will change CIRCUITPY_FULL_BUILD = 1

manic glacierBOT
tulip sleet
#

CircuitPython 10.0.0-beta.3 Released!
https://blog.adafruit.com/2025/08/29/circuitpython-10-0-0-beta-3-released/
Highlights of this release:

  • Convert mono audio to stereo when going through a stereo audiomixer.Mixer.
  • Add audiomixer.MixerVoice.panning, with synthio.BlockInput support.
  • Add synthio.MidiTrack.tempo.
  • Restore missing audioio module on ESP32 and ESP32-S2.
  • RP2xxx DVI now works on more monitors and has fewer glitches.
thorny jay
manic glacierBOT
manic glacierBOT
frail widget
tulip sleet
# frail widget Hey team, I've been working through some type issues with 2 minor PRs ^ and a qu...

I think the BlockDevice protocol description was swiped from MicroPython, and includes things that are not used in core CircuitPython and in libraries like Adafruit_CircuitPython_sd. For instance, ioctl() talks about littlefs, which we don't use at all. I think you can remove the ioctl method. As for start_block vs block_num, they mean the same thing but start_block is more descriptive. For ReadableBuffer / WriteableBuffer vs bytearray, the ...Buffer is more precise.

frail widget
# tulip sleet I think the BlockDevice protocol description was swiped from MicroPython, and in...

Thank you for this. I have put up a proposed resolution in https://github.com/adafruit/Adafruit_CircuitPython_Typing/pull/52

GitHub

Resolves #51
This PR modifies BlockDevice so that sdcardio.SDCard adhears to the protocol.
This will prevent type errors from showing when providing an sdcardio.SDCard as an argument to storage.Vfs...

orchid basinBOT
tiny peak
#

Is there some magic to enabling CIRCUITPY_DEBUG_TINYUSB ? I tried uncommenting the #define lines in ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.h for CIRCUITPY_CONSOLE_UART_TX, CIRCUITPY_CONSOLE_UART_RX, and CIRCUITPY_DEBUG_TINYUSB. Tried it with the default ..._TINYUSB 0 and also with ..._TINYUSB 1. In both cases, I can get a copy of the normal console output on the A4 (GPIO44) pin with 115200 serial into a rpi debug probe. But, there's no sign of TinyUSB debug stuff.

tulip sleet
tiny peak
#

hmm... as I suspected, the USB glitch stuff is a Heisenbug. Turning on debugging appears to add enough delay that the glitch goes away.

tulip sleet
#

My last long bug investigation was also a Heisenberg 😀

tiny peak
#

supposedly tinyusb debug over RTT is possible. might try that.

#

supposedly RTT is really fast

full plume
#

Not exactly sure why, but looking at that made me slightly nostalgic for the old days where my "debug prints" went straight to text video memory, back when a "multiple monitors" meant you stuffed a CGA and a Hercules Mono card into the same case. Which I guess might be ever so tenuously relevant to debugging code on a FruitJam

tiny peak
#

From what I read of RTT, I think that's sorta how it works? Like, it just stuffs entries into some big circular buffer in RAM, where some hardware peripheral hooked up to the debug circuitry can get at them?

full plume
# tiny peak hmm... as I suspected, the USB glitch stuff is a Heisenbug. Turning on debugging...

that's why I just write code without any bugs in it, so I don't need a debugger. Of course I'm mostly kidding, but not all kidding. When I got my first computer, it took a while (another six months or so?) before I could save up enough to by any external storage - so whatever I wrote was gone as soon as the pwer went off. And if my code got stuck end an endless loop or poked something it shouldn't have and froze things, oh well... I think this is partly responsible for my tendency to write in a more defensive style which does a lot of internal "sanity checking" as things move along. Those habits have proven particularly useful for embedded programming - I do make mistakes, but the surrounding code usually catches and identifies things fairly well.

tiny peak
#

yeah... there are times and places where it really pays off to think pretty hard about what your code is gonna do before you turn it loose to do those things.

full plume
full plume
tiny peak
#

People also spend a lot of time thinking about such things in the realm of Ada / SPARK language

full plume
#

Well, it's not rocket science...

#

unless, of course, it's for rockets😋

tiny peak
#

and cars. I think some of that grew out of investigations in to stuck Toyota accelerators or something like that? Might be totally mis-remembering the details though.

#

But, yeah, generally for times and places where stuff actually needs to work

full plume
#

Personally, for anything beyond moderate complexity I'd just say don't try to write it in C

crimson ferry
#

wait, you mean my CircuitPython microcontroller hobby project isn't MISSION CRITICAL!?? 😉

full plume
#

C++ can be a much better environment for building high performance, high reliability code. Of course in can also lead to unmitigated disaster faster than you can say printf( "hello world" ); if you try and use all the options or constantly chase the shiny new things

full plume
tiny peak
#

If you've never experimented with trying to write some stuff in Ada / SPARK, it might blow your mind. Forces you to consider all sorts of edge cases and specify what behavior you intend.

#

Rust is sorta that way too, but it aims in a bit of a different direction.

#

Thing about C++ is it can be pretty much anything and everything. Some of those things being safe, and others very much not

#

Trouble with all of it is that ultimately you have to link against C libraries if you want to get stuff done in a reasonable amount of time.

full plume
#

Actually I thought twice before saying that. I've thought about placing (and most likely some time soon will) a VERY prominent warning section and some extremely blatant clauses in whatever "license" I end up with for my current project stating that this is NOT a "safe" system, and you are strictly FORBIDDEN from using it in ANY project which is channeling enough power or force (i.e. motors, etc.) to cause injury.

#

I'm probably being paranoid, but I know a bit about building high risk systems and I also know that my current project isn't exactly playing by the rules.

tiny peak
#

Good luck with figuring out how to handle that. Always tricky to decide how much time and effort to put in and when to call it good and ship the thing.

full plume
tiny peak
#

mmm... yeah, you never know what people will try.

full plume
#

But I really, really want to, just need to find some volunteers. Which is a bit challenging, considering that anyone who participates in discussions on most of the places I frequent (certainly anyone already lurking - much lest posting - in circuitpython channels) is already outside of the primary "non-programmer" target audience for my project. Still, I could always throw out some YouTube videos. (sadly, that's not a joke...)

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

It's not in the docs, because the "unknoown" errors are unexpected, and there are a lot of them. So they would be looked up in the source code. In this case, it is ports/espressif/esp-idf/components/bt/host/nimble/nimble/nimble/host/include/host/ble_hs.h.

I have no something like a beacon, but I have Mi Band 6 that advertise the generic heartbeat and battery sensor services. And there same thing happen when I try to connect to it from esp32-s3.

I have not same problem when connecti...

crimson ferry
#

We seem to have fewer sockets available in CP 10 (espressif 10.0.0-beta.3)? In CP 9, I could use 8 TCP sockets. in CP 10, only 4```py
import time, wifi, socketpool
pool = socketpool.SocketPool(wifi.radio)
socks = []
while True:
socks.append(pool.socket(pool.AF_INET, pool.SOCK_STREAM))
print(f"{len(socks)}") # 8 in CP 9; 4 in CP 10

crimson ferry
#

so I don't think you could have for example, an HTTPS client and an HTTPS server with a connected client (this would not be an unusual use case)

crimson ferry
#

CONFIG_LWIP_MAX_SOCKETS=8 is still 8. The limit of 4 is reached at socket creation time, presumably before the CONFIG_LWIP_MAX_ACTIVE_TCP=4 and CONFIG_LWIP_MAX_LISTENING_TCP=4 limits kick in. (Those haven't changed in 2 years either, but probably at least `_MAX_ACTIVE_TCP should?)

full plume
crimson ferry
#

yes, but many competing demands for esp-idf memory

full plume
crimson ferry
#

(I raised it to 8 from 4 in a PR years ago)

#

some esp-idf options have to be configured in at build time, like how many stations can connect to a wifi AP, and probably other wifi and ble things

full plume
#

looks like the main affected bit would be static uint8_t socket_fd_state[CONFIG_LWIP_MAX_SOCKETS]; and static socketpool_socket_obj_t *user_socket[CONFIG_LWIP_MAX_SOCKETS]; in socketpool/Sockets.c

crimson ferry
#

but the config constant hasn't changed, so I'm at a loss why only 4 STREAM sockets can be created now

full plume
#

that's in "our" ports/espressif/common-hal, not an ESP-IDF config

crimson ferry
#

right, something could have changed under the covers in esp-idf

crimson ferry
#

or some new default or config option we didn't tweak yet

#

I had to upgrade to CP 10 to fix that socket hard fault, but lost sockets in the process

full plume
crimson ferry
#

Espressif defaults are quite a bit higher... 10 for LWIP_MAX_SOCKETS and 16 for the other two params above (which don't use memory if not used)

full plume
#

I can poke around a bit - the httpServer listen loop needs to come from that list, as would each active Websocket (although you're only supposed to have one at a time). Shouldn't be too hard to throw enough (near) simultaneous requests at it to see where it breaks on my system.

crimson ferry
#

I think all it would take is 1 HTTPS client, then 1 HTTPS server which then tries to either open a websocket or accept a client connection

#

4 is painful, 8 is livable

full plume
#

I'm currently running a 10.0 beta-ish fork build for a Lolin S2 Mini. I can switch to 10.0.0-beta.3 (hopefully it won't break my code) - what board/build are you seeing these problems on?

crimson ferry
#

S3, but any espressif board should have the same behavior

full plume
#

10.0.0-beta.3?

crimson ferry
#

yes

#

(QT Py S3 N4R2, but I doubt flash config or PSRAM have anything to do with it)

full plume
#

OK, running with 10.0.0-beta.3 and it so far everything seems to be working (my fork provides support for __all__, so some from XYZ import *s might have gotten a little wonky with out it)

crimson ferry
#

nothing is jumping out at me from the esp-idf release notes

#

if you run my code above, do you get 4?

full plume
#

Need to hack togeher a load test

#

realizing it's not quite that simple... I was going to hit it with multiple concurrent REST requests from Postman and my "proxy" request base wrappers in a Jupyter notebook, but I think the current (non-async) adafruit_httpserver.Server will just "serialize" those

#

SO guess it's time to finally break the rules and see what happens when I try to open a second Websocket without closing the first one..

crimson ferry
#

or do an HTTP[S] request from within the server route

#

we should have taken this to a thread o_O

#

gotta step away for a while

full plume
#

Never too late for fancy threads, we can spin one up when you're ready

full plume
#

so.... multiple active Websocket connections is - at least for my current use case - working

full plume
#

we should have taken this to a thread o_

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 10.0.0-beta.3 on 2025-08-29; Adafruit PyPortal Titano with samd51j20

Code/REPL

>>> 
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== import board
=== import storage
=== import adafruit_sdcard
=== import os
=== import digitalio
=== import busio
=== spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
=== cs = digitalio.DigitalInOut(board.SD_CS)
=== sdcard = adafruit_sdcard.SDCard(spi, cs)
=...
manic glacierBOT
manic glacierBOT
#

Testing:
1)Run pre-commit run --all-files, Result:
ruff.....................................................................Passed
ruff-format..............................................................Passed
pyproject-fmt............................................................Passed

2)Hardware tests:

  • SD-card tested with 'adafruit_sdcard' based on this tutorial
  • Ethernet tested with 'adafruit_wiznet5k' based on this ...
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.8 on 2025-05-28; Adafruit QT Py ESP32-S3 4MB Flash 2MB PSRAM with ESP32S3
vs.
Adafruit CircuitPython 10.0.0-beta.3 on 2025-08-29; Adafruit QT Py ESP32-S3 4MB Flash 2MB PSRAM with ESP32S3

Code/REPL

import time
import wifi
import socketpool

time.sleep(3)  # wait for serial after reset
pool = socketpool.SocketPool(wifi.radio)
socks = []
while True:
    socks.append(pool.socket(pool.AF_INET, pool.S...
lone sandalBOT
crimson ferry
manic glacierBOT
#

OK, to restate this:
There is no way for the host to know that the SD card is "temporarily read-only" if CPy opens a file on the SD card for write. I think maybe we need these rules:

  • If, in boot.py, CircuitPython mounts the SD card as read-only, then the CPy automounter can present the card as read-write to the host computer. CPy cannot remount the card as read-write once it is presented to the host.
  • If, in boot.py, CircuitPython mounts the SD card as read-write, then th...
lone axle
#

I can do that tomorrow if you don't get to it, or can't get git to cooperate.

tulip sleet
lone axle
#

Ooh, nice. Thank you!

#

It may need to have conflicts resolved in this case. It outputs this error

crimson ferry
#

OK, thanks, I'll do a new PR and back out the changes (re-insert the deletions)

manic glacierBOT
#

-Fixes #10590

Detailed changes:

  • For cardputer_keyboard.c, allocate DemuxKeyMatrix it creates and the objects it holds (all the way down) on the port heap, because it lives past VM's.
  • To do the above, add support for non-VM heap for DemuxKeyMatrix and the keypad allocations it needs by passing an arg use_gc_allocator, as is done in lvfontio.
  • Add mp_obj_port_malloc(), mp_obj_port_malloc_var(), mp_obj_new_port_tuple(), all of which allocate on the port heap, not the...
thorny jay
# manic glacier

Thank you very much. The artifact works for me Adafruit CircuitPython 10.0.0-beta.3-3-g50922c9a74 on 2025-09-03, but something when wrong in the git action: Build CI / windows (not sure what it is, but it was in error and does not seems related to your change).

manic glacierBOT
manic glacierBOT
#

@b-blake I am confused as to what is working and not working. Please tell me whether these are right or wrong.

? The Metro RP2040 displays a drive for the SD card and shows its contents on your Windows 10 machine without anything in boot.py.
? The RP2040W with an SD card breakout wired up and the code above in boot.pyshows a drive but there is nothing in it. Or are you putting the mount code incode.py`?

manic glacierBOT
manic glacierBOT
#

@dhalbert, @tannewt

The issue is that 10.0.0 creates a secondary SD card instance when there is no native SD Card reader present.
If the user creates an SD Card instance, there are then two. One useable (user), the other useless (10.0.0).

On boards with a native SPI card reader it creates a functional SD Card instance whether there is an SD Card inserted or not.
Or if the user wants it or not.

  1. I am hoping that 10.0.0 will not create an SD Card on boards that do not have a native SD Ca...
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 10.0.0-beta.3 on 2025-08-29; Raspberry Pi Pico W with rp2040
Board ID:raspberry_pi_pico_w
UID:E6632C85930F4136
MAC:2C:CF:67:08:08:49

Code/REPL

import board
import busio
i2c1 = busio.I2C(board.GP15, board.GP14)

Behavior

Traceback (most recent call last):
  File "", line 1, in 
ValueError: GP15 in use

Description

If the code interrupted for any reason, be it a coding error, p...

#
  • Fixes #10606

Remove some lower-valued LWIP settings in sdkconfig.defaults on espressif. In particular, removed:

CONFIG_LWIP_MAX_ACTIVE_TCP=4
CONFIG_LWIP_MAX_LISTENING_TCP=4

These settings restricted the number of usable sockets. It looks like LWIP might have started paying more attention to these when it was updated in in ESP-IDF 5.4.1.

These were all removed:

CONFIG_LWIP_MAX_ACTIVE_TCP=4
CONFIG_LWIP_MAX_LISTENING_TCP=4
CONFIG_LWIP_TCP_SYNMAXRTX=6
CONFIG_LWIP_...
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

I have been trying to reproduce this on a Pico W with a very simple local webserver, running in Python, and an even simpler version of your HTTP test program in https://github.com/adafruit/circuitpython/issues/10455#issuecomment-3166290627, doing 10 requests a second. I have seen cases where the wifi module code starts raising EINPROGRESS errors, but mostly it is works fine.

However (and this is a big "however"), I am consistently seeing a crash into safe mode when I attempt to edit `cod...

#

There is no way for the host to know that the SD card is "temporarily read-only" if CPy opens a file on the SD card for write.

Correct. If the host enumeration happens while CP has a file open for writing, the host will see read-only until the mount is ejected.

CPy cannot remount the card as read-write once it is presented to the host.

CircuitPython doesn't really mount as r/o or r/w internally. I think the remount setting is only for USB. Instead it checks when trying to open a file f...

#

The issue is that 10.0.0 creates a secondary SD card instance when there is no native SD Card reader present.

This is not true. It does present a drive to the USB Host by having a LUN designated for SDCard. It doesn't talk to a missing card or create a sdcardio object.

If the user creates an SD Card instance, there are then two. One useable (user), the other useless (10.0.0).

No, there should only be one and it should be available at the LUN created earlier during USB enumeration. This...

manic glacierBOT
#

@tannewt,

When I plug my MagTag into a USP port on my Windows 10 PC I get two USB drives.
M: CIRCUITPY aka MagTag
S: When clicked "Please insert a disk into USB drive (S:)"

My MagTag does not have a USB/SD Card reader.
It is displaying "MagTag Daily Weather Forecast Display" which does not use an SD Card for data.

Thus my confusion. Why is drive S: created when there is no drive S: to access and it is asking for a disk to be inserted?

Is it a drive that is only accessible from within Cir...

manic glacierBOT
manic glacierBOT
#

@b-blake

I tested a MagTag, running CircuitPython 10.0.0-beta.3. I loaded the stock version of the "MagTag Daily Weather Forecast Display" from https://learn.adafruit.com/magtag-weather/project-code-2, after doing a storage.erase_filesystem(), and verified that the program was running.

I then plugged the MagTag into Ubuntu 24.04, a Windows 11 Pro 24H2 machine, and a Windows 10 Pro 22H2 machine. On all machines, I only saw the CIRCUITPY D: drive.

So I don't know where your S: drive is co...

manic glacierBOT
manic glacierBOT
jolly roost
#

Hello, we've created a circuitpython library (https://github.com/sensebox/CircuitPython_VL53LxCX) for VL53L5CX and VL53L8CX ToF sensors based on this: https://github.com/mp-extras/vl53l5cx We are able to bundle the library and also release it but these types of sensor need a firmware file which will be transfered to the sensor on startup. Is there any good way how we could integrate the firmware file to the CircuitPython Package release?

GitHub

CircuitPython driver for VL53L5CX and VL53L8CX ToF sensors - sensebox/CircuitPython_VL53LxCX

GitHub

MicroPython and CircuitPython support for ST VL53L5CX TOF sensor - mp-extras/vl53l5cx

spare jacinth
lone axle
# jolly roost Hello, we've created a circuitpython library (https://github.com/sensebox/Circui...

I believe it's possible to bundle .bin files with CircuitPython libraries already. I'm not sure if there is anything "special" needed beyond just including them in the repo though. There is an examplere here: https://github.com/adafruit/Adafruit_CircuitPython_PyCamera/tree/main/adafruit_pycamera where this is done. You could check the code and actions in that repo to see how the bundling work and if it requires anything additional.

spare jacinth
tulip sleet
lone axle
tulip sleet
#

great, will do it now

lone axle
#

thank you

spare jacinth
lone axle
#

I believe it may not have done that before and was only added when the PyCamera library was in the works.

manic glacierBOT
lone axle
#

(our bundling tools at least)

spare jacinth
spare jacinth
jolly roost
#

okay cool! Thanks for pointing to the PyCamera Library, I was already looking for other libraries who might have the same problem but didn't found it.

orchid basinBOT
lone axle
# jolly roost okay cool! Thanks for pointing to the PyCamera Library, I was already looking fo...

One handy trick to know for finding stuff in CircuitPython libraries is using git submodule foreach in the bundle repo https://github.com/adafruit/Adafruit_CircuitPython_Bundle All of the libraries are submodules so this allows you to use CLI tools like find, git grep etc to search all libraries at once. e.g. this command in the bundle will search for .bin files:

git submodule foreach "find . -name '*.bin'||true"

Though it does also spam "Entering ___" for each repo which makes the output harder to find without searching. So tacking on an extra grep to filter those out can be helpful too

git submodule foreach "find . -name '*.bin'||true" | grep -v Entering
#

On linux. Sorry, I'm unsure of other platform commands but something similar should be possible.

orchid basinBOT
manic glacierBOT
#

Tighten up gaps in usb.core.Device error handling:

  1. Instances where 0xff (not a valid enum value) was assigned to the static xfer_result_t _xfer_result; variable (an enum type) are converted to using XFER_RESULT_INVALID (a valid enum value). Both values were used to indicate the condition of waiting for a callback to finish. This change makes usage in usb.core.Device consistent with usage in the TinyUSB implementation.
  2. Callback result code checks are converted from partial cove...
lapis fjord
#

Hello, Working with a BMP581 on CircutPython9.2.8.
The adafruit_BMP5xx library doesnt seem to be in the 9.x library bundle.
So I assumed that I could pull it from github, and compile the .mpy (never done that, docs maybe a little crusty, but mpy-cross generated a .mpy:

(base) mperino@Aku:~/CircutPython/BMP5x/Adafruit_CircuitPython_BMP5xx$ mv /home/mperino/Downloads/mpy-cross-linux-amd64-9.2.8.static /home/mperino/bin/mpy-cross-9.2.8
(base) mperino@Aku:~/CircutPython/BMP5x/Adafruit_CircuitPython_BMP5xx$ chmod 755 /home/mperino/bin/mpy-cross-9.2.8
(base) mperino@Aku:~/CircutPython/BMP5x/Adafruit_CircuitPython_BMP5xx$ mpy-cross-9.2.8 ./adafruit_bmp5xx.py
(base) mperino@Aku:~/CircutPython/BMP5x/Adafruit_CircuitPython_BMP5xx$ ls
adafruit_bmp5xx.mpy adafruit_bmp5xx.py CODE_OF_CONDUCT.md docs examples LICENSE LICENSES optional_requirements.txt pyproject.toml README.rst README.rst.license requirements.txt ruff.toml

however when I copy over adafruit_bmp5xx.mpy and try an import (Adafruit CircuitPython 9.2.8 on 2025-05-28; Raspberry Pi Pico 2 W with rp2350a) :

from adafruit_bmp5xx import BMP5XX
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "./adafruit_bmp5xx.py", line 37, in <module>
ImportError: no module named 'adafruit_register'

lone axle
lapis fjord
#

I copied yours over, 4byte difference, added adafruit_register, and it's at least importing:

import adafruit_bmp5xx

lone axle
#

my best guess is maybe the difference is based on the version being filled in our not. But I am not sure, perhaps there are specific versions of mpy-cross used that differ slightly.

lone axle
lapis fjord
#

Also looks like there is a change which dropped the generic BMP5XX and is using the more specific and helpful BMP5XX_I2C
from adafruit_bmp5xx import BMP5XX_I2C (good)
from adafruit_bmp5xx import BMP5XX (depricated i asssume)

lone axle
lapis fjord
#

Greatly prefer the new class makes more sense. Thank you for the speedy support!

manic glacierBOT
#

@dhalbert,

I have a theory that the ESP32 is for some reason also enumerating the USB manager that is used to load CircuitPython.
I say this because COM48 enumerates during a normal run. COM40 enumerates during for a CP load.
Can two drives enumerate on one COM Port?

I do not get the phantom drive on my Fruit Jam with 10.beta-3. I do get a CPSAVES drive (read Only). I think of it as a scratch drive.

Running on: Windows 10 Pro, 22H2, 19045.6282, installed 5/28/2020.
Something in the his...

tulip sleet
lone axle
#

Ahhhh yeah that is way easier. I got honed in on submodule foreach using it with git grep. But now that you mention it I think that could work the same way with grep and without the submodule loop.

#

Thank you!

tulip sleet
#

i know you are using submodule foreach All The Time 🙂 to do patches or whatever. Makes sense you would continue the idiom

lone axle
#

@tulip sleet I'm going to push button to run the update bundles workflow manually. Having a new release will make it possible to get correct versions of the files screenshot picures used in the guides. I figure it will also be nice to know now if there is any reason it can't complete from it's new home.

full plume
manic glacierBOT
#

Just pushed another commit that sets unique errno values for each place in the usb.core.Device implementation that raises USBError or USBTimeoutError. The idea is to provide more visibility so CircuitPython code can understand what's gone wrong when TinyUSB complains about something.

Reviewers: The last commit deletes two USBError error strings (stalled pipe and no configuration set). Since everything now gets a unique errno code, it's still possible to distinguish those two USBError i...

#

My apologies, I'm not sure how to post the code, but here it is.

And a fuller console output:

CO2: 2126 ppm ===========================> code running happily
Temp: 29.9/28.7 C
Humidity: 59/56 %
CO2: 2143 ppm
Temp: 29.7/28.7 C
Humidity: 60/56 %
CO2: 2224 ppm
Temp: 29.6/28.7 C
Humidity: 60/56 %

Code stopped by auto-reload. Reloading soon. =======>commenting out the i2c1 line and the display/draw part
soft reboot

Auto-reload is on. Simply save files ov...
spare jacinth
manic glacierBOT
manic glacierBOT
#

Thus my confusion. Why is drive S: created when there is no drive S: to access and it is asking for a disk to be inserted?

CircuitPython pretends there is an SD card drive whenever sdcardio is compiled into CircuitPython. Think of this as a floppy drive without the floppy.

Is it a drive that is only accessible from within CircuitPython? How do I access it?

To use it, you can do what bablokb did.

I thin...

manic glacierBOT
#

Thank you for the PR!

Why do you need a native PIO_SPI object? It seems you are only using this from the Python driver. The PIOASM library has an example of implementing a busio-like UART via PIO all from Python here: https://github.com/adafruit/Adafruit_CircuitPython_PIOASM/blob/main/examples/pioasm_rxuart.py

Want to split out the board definitions from the wiznet module addition? I'm happy to take the new board defs as we sort out the PIO stuff.

wraith crow
#

I've been playing at getting CircuitPython working with all the peripherals of the Olimex RP2350pc but like the SolderParty RP2xxx Stamp Carrier XL the USB A ports/hub has been wired in parallel to the dedicated USB_DM/USB_DP RP2350 pins. I've mostly got a version of CircuitPython working that respects the CIRCUITPY_USB_DEVICE=0 parameter which allows the device to use the attached USB A ports for USB Host functions (keyboards, mice) at the expense of having to use something like an FTDI serial cable and something like Thonny to transfer files. While I would like to see boards like this supported on Circuitpython.org I know not having a CIRCUITPY drive has been a hard stop for boards in the past. Given that, I'm thinking if I make this firmware available on github for public use, my understanding was that Adafruit would prefer I didn't call it "CircuitPython". I was thinking of simply referring to it as something like RP2350pc Python but my question is, is there an obvious place in the core where the CircuitPython branding can be adjusted?

manic glacierBOT
#

I am able to reproduce this fairly easily with repeated HTTP fetches (doesn't have to be POST). I think this may be due to PR #10027, which switched to dynamic storage allocation in LWIP. I was able to get a stack backtrace after a failure that reported a tlsf assertion failure and I see that LWIP is doing storage allocate/free during an interrupt context. The port_malloc() and port_free() calls it uses are not protected in a critical section, so there may well be some overlapping stora...

manic glacierBOT
#

Last commit reduces the delay after a TinyUSB failure result. Previously, I used 50ms to have a big safety margin. But, that seems excessive. I tested unplug detection for many builds with delays between 0ms and 20ms using my pile of USB devices.

A 15ms delay worked fine with everything. Full Speed devices were marginal down to 13ms and failed at 12ms. Some Low Speed devices were okay down to 3ms, but the Adafruit generic SNES gamepad was marginal below 12ms. 15ms seems like enough.

manic glacierBOT
#

6. Fix missing error handling for usb.core.Device.idVendor and usb.core.Device.idProduct

I ended up loading these changes on a board I'm testing. Things mostly seemed to work for the narrow case I was testing but I did notice that the Adafruit_CircuitPython_USB_Host_Mouse library now fails when one of these fields fails to be retrieved. It's an simple fix to catch now that there's a specific error code but this will be a breaking change for at least some of the Fruit Jam apps as the...

manic glacierBOT
#

as these fields seem to error on retrieval relatively frequently.

Interesting. It's definitely been my experience that USBTimeoutError is very common for keyboards, mice, and wireless gamepads connected by USB-C or a USB wireless adapter. I will often see some USBError during initial connections, depending on the device, but I haven't seen much of it during normal usage unless I unplug. Was it a wireless mouse? I haven't tried much of that.

Did you happen to experiment with hotpluggin...

lone axle
#

All of the cron tasks seem to have run correctly from in the core repo blinkacomputer

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.8 on 2025-05-28; Raspberry Pi Pico W with rp2040
Board ID:raspberry_pi_pico_w
UID:E6632C85930F4136
MAC:2C:CF:67:08:08:49

Code/REPL

import time
import board
import busio
import wifi
import sys
import gc
import supervisor
import traceback
import adafruit_scd4x
import adafruit_requests
import adafruit_connection_manager
from os import getenv

i2c0 = busio.I2C(board.GP17, board.GP16)
scd4x = adafrui...
manic glacierBOT
lone axle
#

In 10.x it appears that os.uname().sysname for some devices changed. The Matrix Portal M4 is one I konw of for sure that changed from samd51 to samd51j19. Getting more specific about the chip type it looks like.

Is that change intentional and likely to stay? If so I found some libraries that use that mechanism that will need to get updated with the new version.

#

although I guess the library should account for it for some period of time even if it was untentional and going to change back since there are beta releases out with that value.

tulip sleet
fleet hollow
#

Does anyone know why most code using the TLV320DAC3100 sets the sample rate to 11030 rather than 11025? Is that a quirk of the dac? I've used 11025 in some projects and that seems to work fine.

manic glacierBOT
#

Did you happen to experiment with hotplugging with and without the changes?

I didn't but I can do a little more playing tonight. My suspicion has been that there's some soft reset occurring to the USB host device and then a timeout has to occur before the IDs become available, but that's entirely based on observation and the fact that putting the "find_mouse" call in a short retry loop has been used as a work around.

I gave these changes a go because I'm very deep into the weeds of a ...

lone axle
tulip sleet
#

maybe that 11.03 is just a rounded 11.025

fleet hollow
lone axle
#

I don't really know much about sample rates though, perhaps 11.03 is rounded? If 11025 is more of a standard that is probably what it should be.

fleet hollow
lone axle
#

yeah, looks like it is 11025

fleet hollow
#

I just wasn't sure if there was a strange quirk with that DAC that make it incapable of reproducing 11025, but my guess is that isn't the case.

#

I'm working on some other updates to the FruitJam library. I'll add that fix in there.

lone axle
#

as far as I am aware no. I just chose that value based on the properties I think.

#

thank you

tulip sleet
#

did you see 11030 anywhere else, in a guide example, etc.?

#

I only see it in that library in the bundle. looking in the fruit jam os...

#

nope not in fruit jam OS (there is a BASIC line number with that value 🙂 )

#

so maybe it's just that line

fleet hollow
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 10.0.0-beta.3 on 2025-08-29; Adafruit-Qualia-S3-RGB666 with ESP32S3
Board ID:adafruit_qualia_s3_rgb666

Code/REPL

# Test Qualia ESP32-S3 with RGB-666 4" Square Display
# Combination of CircuitPython internet test and RGB-666 4" square display setup

import os
import ipaddress
import ssl
import wifi
import socketpool
import adafruit_requests
import time
import supervisor
import json
import microcontro...
lone axle
#

I've just noticed that directories without python code in them seem to take precedent over python code files. i.e. I have:

CIRCUITPY/
  boot_animation/
    a_spritesheet.bmp
    ...
  boot_animation.py

When I do import boot_animation in the terminal it seems to be trying to import the folder and doesn't execute the code inside of boot_animation.py

In the short term I plan to change the name of the assets folder to work around this. But I'm also curious if it is somehow to possible to make import use the python file instead of the directory that doesn't contain code?

#

hmm, maybe there is something else wrong in my situation. Having trouble re-creating that now.

devout jolt
willow totem
manic glacierBOT
#

With these files in the root of CIRCUITPY

fake_lib/
  a_spritesheet.bmp
fake_lib.py

When you do in the REPL:

import fake_lib

It seems to be trying to import the directory. The contents of fake_lib.py are just print("Hello fake_lib.py") and that value never gets printed.

If you change the name of fake_lib/ to something else then run the same import it will execute the code inside of fake_lib.py

In CPython testing the same scenario results in the opposite behavior, th...

lone axle
willow totem
#

Ah maybe that was it, I must have had to clear that up for sen5x base driver or something

wraith crow
manic glacierBOT
tulip sleet
lone axle
#

under CPython it will execute the code in the .py file even if there is a folder by the same name with bitmap file in it (same conditions tested on CircuitPython)

#

Under 3.12 at least.

tulip sleet
#
(.py) halbert@cod:~$ mkdir foo
(.py) halbert@cod:~$ cat >foo.py
print("foo.py")
(.py) halbert@cod:~$ cat >foo/__init__.py
print("foo/__init__.py")
(.py) halbert@cod:~$ py
Python 3.12.3 (main, Aug 14 2025, 17:47:21) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
> import foo
foo/__init__.py
>>>
#

CPython looks for an __init__.py file and if present, will import the directory module

#

so MicroPython/CircuitPython probably don't bother to look for __init__.py

stuck elbow
#

though you can have it if you need code at the top level of the module

tulip sleet
#

i was just trying to figure out how to indicate that the dir was being used first

tiny peak
#

@wraith crow In your github comment earlier, you mentioned wanting to discuss USB host stuff here. Sounds good to me. Let's start a thread for it.

tulip sleet
lone axle
#

it may not be worth the overhead of additional logic to fix. I was surprised by the behavior at first and couldn't figure out why the script wasn't running. TBH I thought I had tested it this way before, but I guess I have not. In any case it turned out to only be the first rung of the ladder down the rabbit hole I started on 🙂

manic glacierBOT
lone axle
#

Now that I know it, I will try to avoid naming directories the same name as python files. I opened an issue so it's tracked somewhere but totally fine to close if it's not a priority to change the behavior.

manic glacierBOT
#
  • Fixes #10455

#10027 (added in 9.2.5) considerably improved network performance on Pi Pico by using dynamic storage allocation in LWIP. However, it turns out LWIP can do heap operations during interrupts. Thus the operations need to be guarded in critical sections. Otherwise there are storage-related crashes at random intervals, and I saw storage assertion violations in gdb when a crash happened.

Tested on a Pico W, with a simple test program that did an HTTP fetch from a local server...

slender iron
# wraith crow I've been playing at getting CircuitPython working with all the peripherals of t...

Not having CIRCUITPY isn't an issue anymore.

Your product supports at least one standard "Workflow" for serial and file access:

With a user accessible USB plug which appears as a CIRCUITPY drive when plugged in.
With file and serial access over Bluetooth Low Energy using the BLE Workflow.
With file access over WiFi using the WiFi Workflow with serial access over USB and/or WebSocket.

Boards that do not support the USB Workflow should be clearly marked.

wraith crow
#

Cool 😁

slender iron
#

We should probably call out the serial workflow their explicitly. I'd want it to work with code.circuitpython.org

wraith crow
slender iron
#

if you are using the CP repo then you are fine

#

a board def won't break it

manic glacierBOT
#

Thanks for looking into this. It is not simple stuff.

I'm mixed about these changes:

  • The error checking in getting PID and VID is good.
  • The magically fixes things delay is a fix I'd like to avoid. Instead, we can dig a bit deeper into why this is happening. Seems like there will be something tinyusb does during that delay that is important to do before we call more of its API. @hathach is back and can help with this.
  • I don't mind exposing TinyUSB error codes back to CP code but do...
manic glacierBOT
#
  • The magically fixes things delay is a fix I'd like to avoid. Instead, we can dig a bit deeper into why this is happening. Seems like there will be something tinyusb does during that delay that is important to do before we call more of its API. @ hathach is back and can help with this.

Okay, I can just remove the delay workaround. If somebody who actually understands how to troubleshoot weird low-level USB glitches wants to tackle a fix for the root cause, that would be fabulous.

*...

drifting token
#

I'm trying to get a espressif esp32-c3-lyra board working, and I've been stuck for a couple of days on getting the status led neopixel working. Is there anyone around who might be able to offer some advice?

manic glacierBOT
manic glacierBOT
#

This is a second attempt at

with a smaller set of changes to usb.core.Device error handling:

  1. Instances where 0xff (not a valid enum value) was assigned to the static xfer_result_t _xfer_result; variable (an enum type) are converted to using XFER_RESULT_INVALID (a valid enum value). Both values were used to indicate the condition of waiting for a callback to finish. This change makes usage in usb.core.Device consistent with u...
fiery pecan
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

I ran 10.0.0-beta.3 vs. PR artifacts on a mix of Pico W and Pico 2W, rapidly sending packets up to 1KB back and forth. The 10.0.0-beta.3 Pico W had an odd panic (below) after about an hour, but the PR artifacts have been running all night so I don't see any regressions.

Create TCP Client Socket
Connecting

*** PANIC ***

tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAI
[01:00:58.400] Disconnected
[01:00:59.410] Warning: Could not open tty device (No such file or directory)
[01:00...
lone axle
#

How does SPIDevice end up getting write(), readinto() functions that are callable from python code? They aren't listed in https://github.com/adafruit/circuitpython/blob/main/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c, but the example code calls them. I assume it is something to do with the enter function, but don't quite understand what it is doing to "tack on" those functions to make them callable. I see the python implementation has a similar thing going on: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice/blob/main/adafruit_bus_device/spi_device.py

jaunty juniper
#

(handling the locking and unlocking via the context manager)

lone axle
#

Ahhh. Thank you

crimson ferry
#

What's the simplest way to generate a lot of interrupts into the circuitpython core (raspberrypi)?

full plume
#

Unfortunately I'm not finding any simple API examples to actually do this - if you're running Linux/Raspbian on the Pi then the kernel tends to handle interrupts, and examples for direct hardware access without a linux kernel seem thin.

crimson ferry
#

I'm not wanting to change the core code

#

just have a lot of background interrupts happening behind the CircuitPython code

full plume
#

Even the arduino bits I've found mention that it's only "faking" it on Raspberry Pis

crimson ferry
#

I can set up various bus protocols or digital streams like PulseIn or countio, but hoping there was an easier way. Tried watchdog, but RAISE isn't implemented on raspberrypi

full plume
crimson ferry
#

Pico, sorry

#

raspberrypi port 😉

full plume
#

Ah, well that's different ....

crimson ferry
#

the port naming is confusing (Big RPis are broadcom port)

stuck elbow
#

any particular kind of interrupts?

crimson ferry
#

anything really, I just want to stress test some CircuitPython code by having interrupts happening in the background, was hoping for something with minimal setup

stuck elbow
#

I think pio can trigger interrupts

crimson ferry
#

that sounds like a half day research job 😉 I'll try some countio or something

stuck elbow
#

I think that uses pio on the raspberry pi

crimson ferry
#

some things. like keypad poll in the core, so that's no use

full plume
crimson ferry
#

yes

stuck elbow
#

create an spi peripheral and toggle the cs pin very fast?

crimson ferry
#

or maybe I can PulseOut to a PulseIn

full plume
#

it's plausible - maybe probable - that the wifi stack on a Pi Pico uses interrupts, so websocket torture tests might help

stuck elbow
#

thing is, if your interrupt-generating code is in Python, then it will be self-regulating, because a lot of interrupts will slow down python vm execution and result in generating fewer interrupts

crimson ferry
#

I'm actually looking for non-wifi non-socket interrupts to stress test wifi/socket code 🙂

stuck elbow
#

so you probably want to toggle that pin with another board

full plume
#

(well, a Pi Pico W anyhow...)

stuck elbow
#

there is also a way to generate a lot of usb interrupts, I think, but I'm fuzzy on the details

crimson ferry
#

I'm fuzzier

fiery pecan
full plume
stuck elbow
crimson ferry
#

thanks, I've got a few things to try now, and will verify before I get too far that the feature actually uses interrupts and not polling in the core

stuck elbow
#

with somethinng like wireshark

#

@crimson ferry by the way, the wifi module is connected over spi on the pico w, so any "wifi" interrupts would be either spi or pin change interrupts anyways

crimson ferry
#

on espressif I could use Monitor mode

full plume
stuck elbow
#

ah, sorry, I misunderstood

#

sure

crimson ferry
#

this arose because LWIP allocates within an isr, but it's protected now with a new pr

full plume
stuck elbow
#

there is a number of specialized malloc-like functions you can use in special cases

tiny peak
#

pulseio.PulseOut looks like it also does interrutpts, so maybe you could do a PulseOut to a counter

crimson ferry
#

I may have a board that can do DVI, but I haven't messed with that at all. I'm trying PulseOut now, no need for countio (maybe) since PulseOut is generating its own interrupts.

manic glacierBOT
#

@tannewt, @dhalbert

#1 I apologize for continuing this conversation. @dhalbert asked me a question and I answered it.

To use it, you can do https://github.com/adafruit/circuitpython/issues/10454#issuecomment-3068049424.
This gives me a third drive. It works just fine. The S: drive is still there.

I believe this is a Windows related bug that will not be resolved. Neither of you can replicate it, so you can't resolve it.

Bruce

manic glacierBOT
#

The PR seems like a rational fix, so maybe completely unrelated, but under atypically extreme duress (hammering on TCP socket, and hammering on interrupts ...assuming the code is doing what I think), a TCP client will get hardfaults somewhat regularly with PR artifacts on Pico W:

<details>
<summary>Client code (on a Pico W):</summary>

# Adafruit CircuitPython 10.0.0-beta.3 on 2025-08-29; Raspberry Pi Pico W with rp2040
# Adafruit CircuitPython 10.0.0-beta.3-8-g9e7a03cbc2 on 202...
manic glacierBOT
#

In shared-module/usb/core/Device.c, the error handling for _get_langid(), common_hal_usb_core_device_get_serial_number(), common_hal_usb_core_device_get_product(), and common_hal_usb_core_device_get_manufacturer() is suspicious.

  1. Tracing call chains, they all end in a tuh_control_xfer() with a _transfer_done_cb callback argument. Before those calls, nothing sets the _xfer_result global, so its initial value is undefined. That could cause _wait_for_callback() to end befo...
manic glacierBOT
#

Also, it turns out the string fetching functions I mentioned in the previous comment don't check if the device descriptor provides strings (i.e. do iProduct, iManufacturer, or iSerialNumber have non-zero string index values). Instead of checking the descriptor to see if a string exists, they just call into TinyUSB and rely on it to return a failure code if the string does not exist.

This approach is potentially troublesome because it masks the possibility of other USB errors. It would ...

manic glacierBOT
#

Just added a commit to fix missing error handling for product, manufacturer, and serial_number string getter properties. Details of missing error checks at:

I'm reasonably confident these changes should be enough to resolve issue #10553