#circuitpython-dev

1 messages · Page 90 of 1

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:

Client code (on a Pico W):

# 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 2025-09-05; Raspberry Pi Pico W...
manic glacierBOT
#

I didn't see any hard faults on beta.3 or PR artifacts until I added some PulseOut code. The beta.3 client hard faulted easier than the PR artifacts client. I didn't see hard faults with PulseOut on the PR artifacts until I turned up the number of pins / length of pulse sequences / timing range of pulses, and certainly didn't exhaustively test all of those variables... I was after replicating the original issue by introducing interrupts into the socket mix. I didn't know if this was realistic...

manic glacierBOT
#

We are about to rollout about 100 devices in schools in Africa. We don't even have electricity there. I don't want to roll out a beta-version of any kind. Although I could provide a sort of 9.2.9 or 9.2.8-fix version, deployment would be much easier with an official version. The local persons in charge for deployment could just follow the guideline to download the latest official stable version.

And I think this is what stable versions in software development are for: they receive importan...

orchid basinBOT
manic glacierBOT
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 10.0.0-beta.3-8-ga96f1123d9 on 2025-09-06; Pimoroni PGA2350 with rp2350b

Code/REPL

import board
import adafruit_pio_uart

adafruit_pio_uart.UART(board.GP32, board.GP33, 9600, 8, None, 1, 1, board.GP34, board.GP35)

Behavior

ValueError: program[6] waits on input outside of count

Description

Tried various combinations, then tried a modified [pin finder](https://gist.github.com/anecdat...

manic glacierBOT
#

With this version of Device.c I get this error starting Fruit Jam OS launcher and an unlabeled generic usb mouse, the "absolute newest" 10.x version doesn't have a problem starting up with this mouse (although I think it may not always see the mouse initially but once you start moving it everything seems to start working):

Note that you have to add the "use_mouse" parameter to the launcher.conf.json file to test mouse use in the launcher.

Traceback (most recent call last):
  File "c...
tulip sleet
manic glacierBOT
#

With this version of Device.c I get this error starting Fruit Jam OS launcher...

If I understand your description correctly, that sounds like what I would expect from CircuitPython code that is using the usb.core API without anticipating the possibility of USBError and USBTimeoutError. In my experience, it works best to:

  1. Have an outer loop that will retry usb.core.find(), usb.core.Device.set_configuration(), etc. when any of the code in either of the inner or outer loop get...
#

Also, I suppose it might be a good idea to include exception information int the documentation at:
https://docs.circuitpython.org/en/latest/shared-bindings/usb/core/index.html#usb.core.Device

The current docs mention that USBError and USBTimeoutError exist, but there's no indication of which methods and properties can raise them under which circumstances. Basically, most of the methods and properties touch the TinyUSB tuh_* API. That means they can get a failure result back from Tin...

manic glacierBOT
#

Has there been any consideration of back-porting the "updated" UF2 bootloader to work with (perhaps a new dot release of) CP 9? I realize this might be problematic unless you can have a single firmware / uf2 image build of CP9 work with both the old and new bootloaders, but if so (for UF2 capable controllers) it might make "field updates" much simpler even with CP9 (vs having to do a full install to get the new CP10 uf2 bootloader)

manic glacierBOT
manic glacierBOT
#

There may be a race condition in usb.core.find() where it's relying on TinyUSB's tuh_mount_cb() and tuh_umount_cb() callbacks to track device addresses. Those callbacks can get delayed by the mysterious thing that goes away if you wait for 20ms after getting a USBError.

Currently, _next_device() from shared-bindings/usb/core/__init__.c relies on common_hal_usb_core_device_construct() from shared-module/usb/core/Device.c to decide which addresses should be included in the `fin...

manic glacierBOT
#

By my reading of the code, it seems CircuitPython's usb.core.find() is usually racing with TinyUSB's asynchronous class driver configuration mechanism. Also, it seems that TinyUSB's class drivers may be operating in parallel with CircuitPython USB drivers?!?

  1. tuh_mount_cb() and tuh_umount_cb() have the wrong semantics for the way the usb.core.find() is using them. What find() actually needs is a way to check if the device has made it to the end of TinyUSB's [`ENUM_GET_FULL_CONFIG...
manic glacierBOT
lone sandalBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

@jbrelwof The updated TinyUF2 bootloader is only a thing for 4MB Espressif boards. It is compatible with 9.1.x and beyond.

Thanks, that's good to know. Do current "main head / latest" 9.x builds for Espressif boards use the new TinyUF2 bootloader? And if it the current release version doesn't already, will there be a future official 9.x release that does? Seems like that might be a bit of a hassle if the only thing it would change is closing this loophole for 4MB espressif boards. ...

manic glacierBOT
#

sadly, I'm still seeing:

Exception: [Errno 113] ECONNABORTED <class 'OSError'>

It ran for an hour with no errors. Then, errors started happening on every other request to the post. The GET to the same URL started erroring about 2 hours after startup. When errors started, it would fail every other request. Then, after about 16 hours, every

FWIW, I re-wrote this using the Arduino core in C/C++ and it didn't throw any errors.

#

The CircuitPython UF2 does not include TinyUF2. That is a separate installation. The explanation for what changed in the bootloader is here: https://learn.adafruit.com/adafruit-esp32-s2-feather/update-tinyuf2-bootloader-for-circuitpython-10-4mb-boards-only. We combined two partitions into one, so starting in 10.something we could add features to the build that would not have fit in the old smaller partition. In 9.1.0, we removed features that depended on there being two partitions (OTA update...

slender iron
#

I haven't had great sucess capturing traces externally. I was trying with imx more than rp2350. I was trying to use an orb trace to do it.

#

I had the best success with ETB on the SAMD21 where you can look back at what happened before a crash

#

I'm around now and will be off and on this week. First step is to get debug logging going via DEBUG=1 build and capturing the uart

lone axle
#

<@&356864093652516868> The CircuitPython meeting will occur here on Discord about 40 minutes from now at 2pm Eastern 11am Pacific. Notes and hug reports can bee added to the shared notes doc https://docs.google.com/document/d/10SvxnkxPP0HhgSv0_x4WXYV0ySvnUcm6KjmpRXEPlUQ/edit?usp=sharing. We look forward to hearing from everyong.

turbid radish
onyx hinge
#

Hi all, just listening in.

#

If I can have a few minutes in text chatwith some of y'all (dan/scott/maybe tim?) before you go, I have a question that I didn't feel rose to the level of needing to be in the weeds.

turbid radish
#

Thanks Tim

tulip sleet
#

sure

lone axle
#

Thanks everyone, have a great week

onyx hinge
#

basically -- I've decided that for my personal projects, I want to start moving off of github. I've selected codeberg as my new home for open source development.

#

The question is whether CircuitPython Community Bundle is interested in accepting projects whose home is not on github.

#

If no, I'll leave jepler_udecimal where it is. If provisionally yes, I am interested in being the guinea pig for this.

tulip sleet
#

if you can do submodules from there, I don't see anything wrong with that

onyx hinge
#

I think there's no problem at the technical level with git, but for instance if you need to report a problem against jepler_udecimal you'd need a codeberg account.

#

(or you can still @ me on an issue on github in the community bundle repo, I'll have a github account indefinitely and for adafruit work)

#

(and I guess it'd have to be the same for anyone who PRs the addition of their project to the community bundle)

lone axle
#

Agree'd having non-GitHub repos in the community bundle sounds fine to me. We'll want to make sure Circup / Adabot / Build tools don't have any problem with it, so having a willing guinea pig is good.

tulip sleet
#

that is a consideration for the library author about being able to get feedback easily. If it's easy to get a codeberg account, then seems fine

onyx hinge
#

oh yeah there may be problems at other levels of the tooling. guinea pigs good.

tulip sleet
#

make sure we use git and not gh, and don't use a github Python library, etc

solar whale
#

@lone axle Where can I find the new work that has been done on the SPI register bits? Just curious?

lone axle
#

The reports generator might assume github repos in some places, but I'm not sure if it actually grabs stats from the submodule repos in the community bundle, or just the community bundle itself.

onyx hinge
#

yeah lots of adabot stuff is using github API queries. those would not work against other forges.

lone axle
onyx hinge
#

If it turns out to be a whole thing I'm prepared to leave jepler_udecimal on github.

onyx hinge
#

anyway, that was my question, thanks for taking a moment to talk to me about it!

lone axle
#

Thanks for popping in!

#

Here is the notes document for next Monday’s CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Add your hug reports and status updates to the document before the meeting. If you are unable to attend but would still like to contribute, feel free to add your notes and we’ll read them off during the meeting. Hope to see you there! <@&356864093652516868> https://docs.google.com/document/d/1uoxUASzgEdYKXVSxoizL9sWmy7A4cxbn5Zr8vzxTOSI/edit?usp=sharing

full plume
# onyx hinge If it turns out to be a whole thing I'm prepared to leave jepler_udecimal on git...

Is this something where you'd specifically prefer to "not have it on github", or just that there's somewhere else you'd rather host the "root" repo and related workflow bits? If you want the main workflow for jepler_udecimal somewhere else but you're not opposed to having a it on github, would simply mirroring it on github be enough for this to "just work" even if some of the CP dev-ops tooling is github specific?

onyx hinge
#

@full plume at a minimum, I will be leaving "archived" copies of all my stuff on github indefinitely. jepler_udecimal doesn't see much development, so if there's much trouble moving it to codeberg while remaining in the bundle, I'll probably just leave it on github unarchived indefinitely instead.

fleet hollow
#

@onyx hinge Have you considered self-hosting a Gitea server?

onyx hinge
#

@fleet hollow yes I've considered that too (gitea or forgejo, which is a fork of gitea. codeberg uses gitea forgejo) and decided that for now anyway I didn't want to host my own service

#

in theory someone will be able to sign up on codeberg if they want to make a pull request or issue, while I would almost certainly not allow signups on a self-hosted forge instance

#

I think a goal of forgejo is to figure out "how to do federation, similar to mastodon" but I don't know how much progress is happening there. https://radicle.xyz/ is also interesting, taking a distributed network approach.

fiery pecan
# slender iron I haven't had great sucess capturing traces externally. I was trying with imx mo...

I tried it myself sometime after posting that. I first had to set up debugging, as explained in #circuitpython-dev message. Although I was initially having trouble reserving an unused buffer in SRAM, once I finally found a way to do that, the rest of the instructions from the linked repo were relatively easy to follow. In the end, I was able to get a list of memory addresses. At least from my understanding, the output was the most recent program counter values reached before interrupting the GDB continue command.

tiny peak
#

@slender iron I'm guessing you haven't had time to look at it yet, but I made a new PR for the USB stuff and I also found a plausible explanation for what's going on with that magic 20ms delay. The PR doesn't address that part as I'm not sure what the best approach would be. Seems like it might make sense to modify TinyUSB with an option to disable its class drivers and add a new tuh_something() function for checking when a device is fully enumerated (minus the class driver bit that currently happens).

#

Current situation is that CircuitPython's awareness of which device addresses TinyUSB considers to be valid relies on callbacks which are part of TinyUSB's asynchronous interface configuration and class driver binding mechanism (which is somewhat incompatible with how the PyUSB API works)

tulip sleet
#

If you think TinyUSB could use a new feature, then feel free to open an issue there.

tiny peak
#

That's basically what's happening now. The issue is that TinyUSB doesn't appear to have a notion of an enumerated device where the enumeration process ends with assigning an address and checking the descriptor info (to pacify devices that change their behavior based on what descriptor and string requests you make).

#

... rather, the enumeration ends with an asynchronous process (i.e. relies on tuh_task() being called many times by RUN_BACKGROUND_TASKS) of interface configuration and driver binding.

#

It's only at the end of the asynchronous driver binding, which can take some time, that CircuitPython gets notified of a device becoming available. I'm less clear about potential delays when a device is unplugged.

#

There are 2 problems:

  1. TinyUSB is binding drivers in some cases while the PyUSB API presents the abstraction that devices will appear in an unconfigured state (no longer true if TinyUSB has set a configuration and opened endpoints)
  2. The async stuff can be really laggy
#

So, if I haven't significantly misunderstood something, there's kind of an impedance mismatch between how CircuitPython is using TinyUSB and how TinyUSB was built to be used (automatic class driver binding)

#

To resolve this, it seems like there would need to be a moderately significant API and enumeration state machine change on the TinyUSB side, coordinated with a change on the CircuitPython side, maybe?

tulip sleet
#

if we were not trying to emulate PyUSB, do you think a better API could be developed on the CircuitPython side?

tiny peak
#

It might be a lot more efficient to just use TinyUSB's class drivers. In particular, for MIDI, I think it has some capability to convert MIDI events into a stream?

#

Not all relevant device types have class drivers though. For example, IIRC, there's no gamepad class driver

tulip sleet
#

The reason for PyUSB was just to have some "standard" API, and to maybe make user code compatible so it could be used through Blinka

slender iron
#

Pyusb does have a similar issue because of an os kernel

#

)at the dentist)

tulip sleet
#

as another example, we tried to emulate pyserial for usb_cdc.Serial, but it's not exactly the same, and pyserial itself has some idiosyncrasies, and trying to be completely compatible with it was not sensible.

#

This is much further away, it sounds like, but maybe it would be easier not to try to be so close, and put a layer for our own API on top of PyUSB for the Blinka case (if that is even worth it...)

tiny peak
#

Having worked with the PyUSB-like usb.core.* API a lot in the last year, I have kinda gotten the impression that its shaped in a rather awkward way for microcontrollers. If the fast endpoint polling happened in C-land somewhere, then events popped up in Python-land through a buffered stream API, I expect the CPU load could be a lot lower.

#

As a counter-point, there's such a wide variety of USB devices that it's really, really nice to be able to write device drivers in userspace rather than kernelspace (hence PyUSB)

#

On the balance, my personal inclination would be to see how far it's possible to go by smoothing out rough edges with the current PyUSB-like API.

tulip sleet
#

i haven't used usb.core at all myself, except to look at it, so I can't say very much useful. But it's obviously worth thinking about this some more.

#

we can think about a better API in the long run. maybe add some polling calls if that would help

tiny peak
#

FWIW, I'd be inclined to just polish up the current usb.core stuff and see how things look once that's done

#

A key test would be whether it's possible to write MIDI synth stuff that doesn't drop notes using the current API

tiny peak
manic glacierBOT
#

The current implementation of usb.core.Device.detach_kernel_driver() looks like this:

void common_hal_usb_core_device_detach_kernel_driver(usb_core_device_obj_t *self, mp_int_t interface) {
    #if CIRCUITPY_USB_KEYBOARD_WORKFLOW
    usb_keyboard_detach(self->device_address, interface);
    #endif
}

So, it's only aware of the possibility of the CircuitPython core having claimed keyboards.

For better compatibility with desktop PyUSB, the detach implementation could be extended...

manic glacierBOT
#

To bring this back into sharper focus on error handling... I'm concerned about the automatic TinyUSB class driver binding stuff because it's redundant (drivers are active but CircuitPython doesn't use them), it's asynchronous (relies on RUN_BACKGROUND_TASKS), and the usb.core.find() implementation currently depends on class driver callbacks (tuh_mount_cb() and tuh_umount_cb()).

The current find() implementation sometimes fails to find devices or finds devices that give USBError...

slender iron
orchid basinBOT
tiny peak
# slender iron May just be a bug. We're the only users of detach. I wanted to make universal ho...

By my reading of the code, I doesn't look like TinyUSB actually provides any way to unbind a driver. So, to get detach working, that would need to change. Might be a lot simpler to just have a TinyUSB config option to totally turn off all the class driver stuff though. For that to work, there would also need to be a way to check if the enumeration process was complete (in the absence of class driver mount/umount callbacks)

#

Implementing those changes would probably be fairly straightforward. My main hesitation would be how to test it (upstream supports a whole lot of hardware), and how the necessary API changes might interact with all the other stuff that uses TinyUSB other than just CircuitPython.

manic glacierBOT
#

Thinking about the TinyUSB enumeration state machine some more, and considering what RetiredWizard mentioned on Discord over the weekend about additional control transfer in progress mutex logic... It seems plausible the TinyUSB enumeration state machine might not be adequately keeping track of when a control transfer is in progress. The enumeration process makes a bunch of async control transfers, and it also has some provisions for debouncing as a solid physical connection is established at...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

As I read more of the code, it seems like CircuitPython actually uses the Hub and HID class drivers to implement the supervisor's HID keyboard input feature. But, as far as I can tell:

  1. No other class drivers are enabled
  2. The usb_keyboard_detach() function is a bit of a misnomer because it actually controls the TinyUSB HID driver. So, it's not limited to just keyboards

If I read the code correctly, common_hal_usb_core_device_detach_kernel_driver() should actually be working just fin...

tiny peak
# tulip sleet we can think about a better API in the long run. maybe add some polling calls if...

Tonight I've been looking into how the supervisor uses TinyUSB's HID class driver for keyboard input (which I wasn't aware of until just recently). From what I'm seeing, it seems plausible that the existing tuh_hid_report_received_cb() callback function in supervisor/shared/usb/host_keyboard.c might be pretty easy to modify for also reading mouse and gamepad input. Something on the order of just maintaining a cursor (x,y) coordinate and gamepad report FIFO as globals in the supervisor, then letting whatever new usb_hid_something API provide access to those.

#

Not sure if it would be a good idea to do that, but it's possible that might work for an input device API that was a whole lot less complex than building drivers on top of usb.core.Device. Seems like both mechanisms could coexist just fine and people could choose what they want to use by calling usb.core.Device.detach_kernel_driver(), or not.

#

No clue what the implications of that approach would be for Blinka

#

The main possible benefit would be getting to use TinyUSB HID driver's support for HID gamepads. I'm not sure how that would compare to using a CircuitPython gamepad library built on top of the usb.core API. It's possible the TinyUSB class driver approach might allow for much lower CPU use and a correspondingly higher frame rate for games.

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 10.0.0-beta.3 on 2025-08-29; Pimoroni Pico Plus 2 W with rp2350b
vs.
Adafruit CircuitPython 10.0.0-beta.3 on 2025-08-29; Adafruit Feather M4 Express with samd51j19

Code/REPL

import time ; time.sleep(3)  # wait for serial after reset
import sys
import board
import busio

def write(size, ch):
    print(f'writing {size} bytes...', end=" ")
    written = u1.write(f'{size * ch}')
    time.sleep(1)
    pr...
manic glacierBOT
#

I wouldn't mind having it in the core but I'd want to to be faithful to the CPython API and behavior.

Otherwise, a community library would be good.

TL;DR;

We can have a "faithful" implementation of importlib.reload(...) , but there's not much else in importlib we could plausibly replicate. So is only reload() enough to justify adding it to the core vs a library?

importlib.reload()

I hav...

manic glacierBOT
#

I wouldn't mind having it in the core but I'd want to to be faithful to the CPython API and behavior.

Otherwise, a community library would be good.

how faithful is it compared to CPython's importlib.reload(...)?

My current implementation is available at https://github.com/Lumensalis/LumensalisCPLib/blob/main/lib/LumensalisCP/pyCp/importlib.py.
I've done quite a bit of "reload magic" over the years, and I'm comfortable stating that this mimics CPython reload semantics rather well....

#

If there is a subset implementation that can be done, even if it's only a small part of the CPython library, if that part is useful, then it could be a library. If that subset implementation can be done in Python, then that's even easier.

The implementation is a subset, but is also in pure python - no firmware tweaks required (although some might make it even better). The "open questions" from my perspective (and the reason for the extended commentary) are:

  • where should a PR go ...
slender iron
#

I'd follow what you can do in Python on Linux.

manic glacierBOT
manic glacierBOT
#

See https://docs.espressif.com/projects/esp-adf/en/latest/design-guide/dev-boards/user-guide-esp32-c3-lyra.html
This commit adds support for audio out and the status LED.

The audio out on this board is in PDM over the I2S encoder hardware.

It's not 100% clear to me why the default neopixel_write implementation
doesn't work, but it seems that deleting the RMT channel triggers some
sort of glitch signal that clears the WS2812C LED.

Tested CircuitPython web interface over wifi, seria...

#

3. I've been operating under the understanding that adding new error strings is to be avoided if at all possible.

Error strings are better than error numbers because they are human readable and therefore human actionable. I only want to avoid similar error messages that could be combined.

I'd only use error numbers to match a CPython API. Otherwise Exception subclasses can be used to make new error machine actionable as well.

#

The PDMOUT change alters what audiobusio.I2SOut does, so it precludes also using regular I2SOut maybe on some other pins. would be more inclined to make PDM-out be a run-time choice as an optional argument for I2SOut

Would audiopwmio work with the onboard circuitry? Could you try it?

Admittedly I'm a bit out of my depth with the hardware here, but I did try using audiopwmio initially. It can drive the speaker pins on this board but the sound isn't right, it's tinny and sc...

manic glacierBOT
#

Could you split this into two PR's: one for the board specifically, but without the PDM out, and then one for I2S PDM out? Then we can discuss the PDM stuff.

I didn't even know Espressif had I2S PDM output. I looked at some other chips and I don't see anyone else doing that, but it sounds like it's quite a bit nicer than PWM out, and maybe we could recommend it for simple audio output on Espressif, since DAC's are not present on many of their chips, and when they are, they're not great.

manic glacierBOT
#

Do you mean you drove the on-board speaker through the LPF, and it sounded bad? The carrier frequency might be too low, I guess.

The hardware stuff is beyond me, but this board has an class D amp, and I presume an LPF in front? All I know was that the audio signal was on GPIO3, and I tried to use that with audiopwmio. Sound came out, but it didn't sound right.

Will do with 2 PRs on main.

#

This was mostly resolved by the merging of

Only remaining problem is that you need to use a try/except block to catch USBError and wait for about 15-20ms after getting a USBError. That will allow TinyUSB's tuh_task() background task runner to clear some mysterious fault condition that will otherwise delay the tuh_mount_cb() and tuh_umount_cb() callbacks and cause find() to continuously produce more exceptions.

#

I am testing this with the tip of main right now. I am seeing ECONNRESETs as you were, about 30-50% of the time. As an experiment, I am running the server on my Linux machine, with the very similar code below. Interestingly , in that case I see EBADF a lot, not ECONNRESET, at least 75% of the time. I've only had one hard crash so far, but was unable to get a stack trace.

I'll also try the more pervasive critical section code I mentioned above in https://github.com/adafruit/circuitpyt...

manic glacierBOT
tiny peak
#

@slender iron Thanks for the USB PR merge! It's exciting to have hotplugging working more reliably.

manic glacierBOT
#

TinyUSB apparently relies on frequent calls to tud_task() and tuh_task() to clock its state machine and task queuing mechanisms. The reproducer code above might prevent RUN_BACKGROUND_TASKS from running often enough for TinyUSB's internal state to stay in sync with what's happening on the USB bus.

A simple experiment to verify this would be to sprinkle some RUN_BACKGROUND_TASKS calls around the usb.core implementation and see if anything improves.

#

I see checks like that in the reads, but not in the writes on any of the three ports

atmel-samd specifically has a code comment:

non-blocking and will return immediately after setting up the write

but atmel-samd is the odd one that allows you to keep writing after the buffer is full with hardware flow control pins defined (new bytes shifted in, old bytes shifted out)

#

I regularly see EBADF too, but it recovers and continues. Server shouldn't matter, except that delay that allows read to complete before the connection is reset could be platform-dependent?

BTW, I reloaded 10.0.0-beta.3-8-g9e7a03cbc2 on 2025-09-05 (PR artifact) again yesterday afternoon on both clients, and made a safemode file to log the hard faults. One has 21 entries, the other has 45, so 1-2 per hour -ish. I just wanted a baseline rate for any further testing.

manic glacierBOT
#

Seems RUN_BACKGROUND_TASKS probably doesn't schedule tud_task() and tuh_task() often enough. If I call tud_task() and tuh_task() directly, it doesn't crash:

diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c
index c07ffda114..3c04321bf2 100644
--- a/shared-module/usb/core/Device.c
+++ b/shared-module/usb/core/Device.c
@@ -9,6 +9,7 @@
 
 #include "tusb_config.h"
 
+#include "lib/tinyusb/src/tusb.h"
 #include "lib/tinyusb/src/host/hcd.h"
 #include "...
#

I tested again with the https://github.com/adafruit/circuitpython/issues/10618#issuecomment-3264114116 version, but as a debug build (so I could get a stack trace, running against the Pico 2 W server. After about an hour I got an assertion failure (with context):


onnecting
Sent 2443 bytes
Received 1460 bytes bytearray(b'378F6203BCB62124B302C1ABCED96BBC8DABC3FB5A435D75DF818CCBAAB8F4F80BD858D3CB60BE5D5C9EB8BFBDC907F8F0A64494F5A99C0B091129B6B26775EE30AC3FB67BBE88BAA057A2342FEC57D1CF2745BF2B...
slender iron
tiny peak
#

I think I've got a workable fix for the issue where polling usb.core.Device.read() too fast can make the board crash

#

Dan has some related concerns about whether my fix is masking a deeper issue in TinyUSB. Might be. Dunno.

#

But, seems like pretty good odds that a bunch of stuff will start working more reliably if we just call tud_task() and tuh_task() at the beginning of each usb.core public property or method to make sure the TinyUSB task queues are all caught up.

#

For whatever reason, relying on the 1024 Hz timer schedule of RUN_BACKGROUND_TASKS seems to be insufficient

manic glacierBOT
#

See https://docs.espressif.com/projects/esp-adf/en/latest/design-guide/dev-boards/user-guide-esp32-c3-lyra.html This commit adds support for the status LED.

It's not 100% clear to me why the default neopixel_write implementation doesn't work, but it seems that deleting the RMT channel triggers some sort of glitch signal that clears the WS2812C LED.

Tested on this board:

  • console/REPL over USB/UART (connection works but is not stable)
  • web interface and editor over wifi
  • audiomp3 p...
manic glacierBOT
wraith crow
#

In supervisor/shared/usb/tusb_config.h is this correct?

// Always use PIO to do host on RP2.
#if !CIRCUITPY_MAX3421E
#define CFG_TUH_RPI_PIO_USB 1
#else
#define CFG_TUH_RPI_PIO_USB 1
#endif

It seems strange to do the same thing on both branches, I would have thought that MAX3421E implemented a host stack that wasn't PIO based but I guess it's possible that on the RP2xxx chips it is?

manic glacierBOT
#

Does file IO for the CIRCUITPY drive depend on background tasks? Is it possible that too much polling could be backing up some queue for tasks related to the FAT filesystem on CIRCUITPY?

I'm puzzled by what I'm seeing with a Fruit Jam rev C and macOS 15.6.1 on an M1 mac mini:

  • Sometimes I can cat or touch a file on /Volumes/CIRCUITPY with no trouble while my reproducer above is banging on Device.read()
  • Sometimes when I do seemingly the same thing, the command line command will blo...
tiny peak
manic glacierBOT
#

This attempts to fix a problem where a Fruit Jam board crashes if you access the CIRCUITPY drive while code.py is rapidly polling a gamepad using usb.core.Device.read(). For details on the problem see

This fix is only marginally effective. It's still kinda crashy, but marginally less so than without the changes. I'm posting this here so people can poke at the code or try the CI build if they want.

manic glacierBOT
manic glacierBOT
#

Mostly there.

I have Pimoroni PGA2350 firmware (very generic, all pins except 49 is PSRAM CS) on a Pimoroni Pico Lipo 2XL W. Can't test 43 and 49 due to special use on the physical board.

I can init 6 PIO UARTs normally (2 bidirectional PIOs per state machine). Everything is fine up to pin 39. It seems like if I use any pins above that in a PIO UART, at least I have to reset or I get RuntimeError: All state machines in use, and if I use more than 1 or 2 pins in the 44-47 range, I can ...

manic glacierBOT
#

It seems the RuntimeError: All state machines in use occurs when too many of the PIO UARTs are from pins >= GP32.

This works, without a reset:

adafruit_pio_uart.UART(tx=board.GP0, rx=board.GP1,cts=board.GP2, rts=board.GP3)
adafruit_pio_uart.UART(tx=board.GP4, rx=board.GP5, cts=board.GP6, rts=board.GP7)
adafruit_pio_uart.UART(tx=board.GP8, rx=board.GP9, cts=board.GP10, rts=board.GP11)
adafruit_pio_uart.UART(tx=board.GP12, rx=board.GP13, cts=board.GP14, rts=board.GP15)
adafru...
manic glacierBOT
manic glacierBOT
#

Interesting, exception on the 3rd UART:

adafruit_pio_uart.UART(tx=board.GP31, rx=board.GP44)
adafruit_pio_uart.UART(tx=board.GP36, rx=board.GP37)
adafruit_pio_uart.UART(tx=board.GP32, rx=board.GP33)  # RuntimeError: All state machines in use
# 
adafruit_pio_uart.UART(tx=board.GP8, rx=board.GP9)
adafruit_pio_uart.UART(tx=board.GP4, rx=board.GP5)
adafruit_pio_uart.UART(tx=board.GP0, rx=board.GP1)
drifting token
#

Hi folks. I got an Espressif esp32-c3-lyra-v2.0 dev board recently and am trying to get CircuitPython set up. This board has no DAC, but it does have a pin connected to a Class D amp that is connected to speaker pins. The Espressif sample code in the esp-adf uses the I2S hardware in a PDM mode to use only the data pin to drive the amp, and it sounds half decent.

The quickest way to a prototype was to#ifdefthis board into the audiobusio code and use the PDM mode, but @tulip sleet correctly pointed out that this prevents the use of I2S on this board. It would be better to somehow pass a param into I2SOut() to specify PDM mode.

I'm entirely unfamiliar with how these APIs are designed, need recommendations on the appropriate way to approach an API change:

  1. Add a keyword arg to I2SOut() for PDM mode specifically for this board. I'm not sure but I think I need to update the API across all the ports to allow for this.
  2. Allow passing in None for the bit_clock, word_select and main_clock pins, and implcitly go into PDM mode on ESP32 hardware when only the data pin is provided. It does look like I need to handle this error checking in the shared-bindings, but otherwise shouldn't have to touch any other ports.
  3. Implement this as audiopwmio instead. It looks like audiopwmio does not exist on the Espressif port, so I'd have to implement it from scratch.
manic glacierBOT
tulip sleet
#

PDM is better than PWM for audio, is my limited understanding. It's easier to implement the filtering. So I think implementing actual audiopwmio is not worth it.

#

your alternatives above:

  1. Yes, an optional keyword arg, and then an additional arg to the common_hal constructor on all ports, which most would just ignore.
    It would also be possible to have different signatures forthe constructor across the ports, based on pre-processing flags, but we haven't done that before, and I'd be reluctant to start.
  2. This kind of implicit mode changing is obscure, and there might be other reasons to omit those values, conceivably.
  3. as I mentioned, probably not worth it
#

if you made a draft PR that just included the common-hal changes, one of us could do the API side, or guide you through it. The API addition is not actually that hard. So add an extra arg to the constructor, and temporarily make it always turn PDM mode on. Then you could test it.

slender iron
#

I think it'd be ok to implement audiopwmio using PDM on ESP.

#

It's two techniques to fake an analog voltage on a single pin

#

In contrast to mod:audioio, the pin(s) specified are digital pins, and are driven with a device-dependent PWM signal.

tulip sleet
#

i was thinking that they end up doing the same thing, albeit with a different-shaped waveform, but the filtering required is different. it could be renamed to audiopulseio.PulseAudioOut to be more general, but maybe that's being pedantic,

drifting token
#

@tulip sleet thanks. Adding a flag to I2SOut() certainly seems the simplest for me.
audiopwmout is easy to use, and a lot of samples use it, so I think there is an argument to go that route from the API perspective. From a high level it's a pin that drives an amp/speaker?
I'm not familiar with the internals, does audiopwmout handle all all the DAC config internally and hide that from the user?

tulip sleet
#

for chips with true DACs, there is audioio, which controls a DAC to produce true audio output, no filtering needed.

manic glacierBOT
#
vernal sage
#

I am (foolishly) trying to build an image for a ESP32C61. I managed to get a reproducable circuitpython-firmware.bin after updating esp-idf and few esp api changes. What is a reasonable size for the bin with no wifi/ble? I have an espressif dev board showing up today so I'll try it regardless and try to work backwords to get at least wifi working

manic glacierBOT
#

To make something like this work for import, we'd need to support some way of recursively descending into zip files to get at the .py/.mpy files inside. For example, given

/lib/foo/__init__.py
/lib/foo/bar/__init__.py
/lib/foo/baz.zip
               \ __init__.py
               \dragons.py

and

from foo.baz import dragons

The import mechanics would need to, after failing to find /lib/foo/baz.py or /lib/foo/baz/..., add a step to check for /lib/fo...

slender iron
#

it needs latest esp idf

vernal sage
#

I'm quite please with how similar our branches are for the amount of cpp/c I touch. Mostly the same besides the make file and updating GPIO_PIN_MUX_REG refs since it seems to not be implemented or deprecrated with the C61. I'll probably switch to your branch and cherry pick the board specific bits tonight and see how much farther I can get with flashing

full plume
#

CircuitPython and C++?

manic glacierBOT
#

Here's some code I wrote to do more or less what you're talking about, if I understand you correctly:
https://github.com/samblenny/fruit-jam-two-gamepad-demo/blob/v0.1.1/bundle_builder.py#L86-L122

That code is part of the bundle builder script I use to extract libraries from the official bundle and create project bundle zip file for Playground guides.

I suppose maybe you'd need something in C rather than Python. But, FWIW, I use that code and it works well for me.

manic glacierBOT
#

That seems to totally fix the problem? I just tried a test build with this change:

diff --git a/ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.h
index 08c3271552..207babe13e 100644
--- a/ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.h
+++ b/ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.h
@@ -40,7 +40,7 @@
 #define DEFAULT_SD_CARD_DETECT (&pin_GPIO33)
 #define DEFAULT_SD_CARD_INSERTED true
...
manic glacierBOT
#

For the read destination buffer, it's just getting allocated wherever CircuitPython decides to put it when the reproducer's buf = bytearray(max_packet) line gets run.

Poking around the TinyUSB source code a bit, it seems like the CFG_TUSB_MEM_SECTION and CFG_TUSB_MEM_ALIGN macros may have something to do with restricting what DMA does. Not obvious to me if that's relevant to this issue or maybe aimed at a different thing with alignment.

TinyUSB's tinyusb/src/class/msc/msc_host.h fil...

#

Hmm... the tuh_msc_* stuff may be irrelevant. It doesn't seem like CircuitPython uses that section of the TinyUSB API.

I looked at the fixes in those two PR's but I've no clue how to go about applying similar changes to DMA that might be happening in the TinyUSB implementation. That stuff is a bit over my head. I'll step aside an leave this to other folks. I can test potential fixes though.

manic glacierBOT
#

This may be a clue. This works:

    adafruit_pio_uart.UART(board.GP34, board.GP35)
    adafruit_pio_uart.UART(board.GP36, board.GP37)
    adafruit_pio_uart.UART(board.GP38, board.GP39)
    adafruit_pio_uart.UART(board.GP40, board.GP41)  # 40,41 not exposed on 2XL
    adafruit_pio_uart.UART(board.GP42, board.GP43)  # 43 VBAT SENSE on 2XL
    adafruit_pio_uart.UART(board.GP44, board.GP45)

I recall getting a ValueError: Cannot use GPIO0..15 together with GPIO32..47 exception...

manic glacierBOT
manic glacierBOT
onyx hinge
#

@tulip sleet @lone axle I think trying to move udecimal to a different git forge is probably going to end up creating problems / showing limitations with adabot that would be time consuming to properly address.

That being the case, wdyt about transferring the udecimal git repo into the circuitpython organization on github? It's used in (just) two projects on Learn, fwiw, one of which was even by somebody besides me.

#

@tulip sleet can you add me back to circuitpythonistas at your convenience?

lone axle
onyx hinge
onyx hinge
#

OK I can just archive the wrong one. this is fine 🙂

manic glacierBOT
#

I re-titled this issue to focus just on the control-c blocking, and may open separate issues on other differences in UART behavior across ports (with and without hardware flow control). For each, to decide if it's OK, a bug, or a doc issue:

  • multi-stage receive buffers and buffering behavior (e.g., shift vs. ignore new bytes)
  • .in_waiting behavior [especially in light of differences above]
  • .written behavior
  • hardware flow control blocking writes vs. non-blocking or timeout
vernal sage
#

I managed to get a "working" firmware.bin last night for esp32c61 after getting around this error assertion "flash_mmap_malloc_internal_cb != NULL && flash_mmap_free_internal_cb != NULL" failed: file "spi_flash_mmap.c", line 195, function: spi_flash_mmap. If I remember correctly that was deprecated so I'm not sure where it's even pulling that in from. I've nuked esp-idf and made sure it's circuitpython-v5.5.1, rm'd ~/.espressif. I hit this error last night and got around it but I can't seem to remember how now. Any other artifacts I am missing?

#
commit f4fddd2d05b44d1d606b546b596d17de0a73e9eb (HEAD, origin/circuitpython-v5.5.1)```
slender iron
#

try running it again

#

I just hit the same exact bug 🙂

vernal sage
#

Try running what part again? Yeah I just tried checking out circuitpython-v5.5.1 directly and did the install.sh again

slender iron
#

and the build didn't complete?

#

how did you get past the mmap error?

vernal sage
#

Oh the build completes and it flashes, once I reset the board I hit that assertion

slender iron
#

kk, that's what I'm seeing too

#

on c6

vernal sage
#

Last night I had it past that and it made it through the bootloader and was calling app and then I started to hit other things

slender iron
#

I'm hitting that assertion from within CP

lone axle
#

@solar whale sorry it took me a few days to circle back. I had some weird stuff from a prior attempt at a combined driver that I wanted to cleanup before sharing.

Here is my working branch for register_spi: https://github.com/FoamyGuy/Adafruit_CircuitPython_Register_SPI/tree/updates_and_things. The main changes I made so far were adding functionality to set the command bit in the MSB of address byte, and changing it to only write a single byte when it is sending the address/RW command. With those changes I'm able to successfully use a bmp580 via SPI.

I have not addressed the polarity of the RW command bit yet, we'll need a mechanism for that since some devices use opposite.

solar whale
lone axle
#

an argument passed to the constructor for polarity would be nice. But the Bit/Bits classes usage as descriptors, and the goal of a combined driver that can work for either I2C or SPI without having to duplicate all of the descriptor definitions make it tricky. I'm not sure if constructor argument will end up being possible.

solar whale
#

As I recall, the main issue I had was just how to modify the existing code to use it. Can you please post an example of how you use it for the bmp580.

solar whale
lone axle
solar whale
#

Thanks -- I have to shake off a few cobwebs and delve back into it. I needed a good project!

lone axle
manic glacierBOT
#

On the smallest boards, we use terse error messages to save space. Usually this is fine, but the module not found error is confusing, because on casual glance it can make it appear that a module being imported is missing, instead of some subsequent import being missing. Use the regular more verbose message instead, which names the missing module.

I've seen several users be confused by this and resort to asking a support question. This happened most recently in discord.

Example and tes...

vernal sage
#

@slender iron I managed to fix my checkout and at least am not crashing immediately on the mmap assertion, any pointers where to look next for this?

slender iron
#

How'd you fix it? What does it do?

vernal sage
slender iron
#

¯_(ツ)_/¯

#

Watchdog timer resets are tricky

vernal sage
#
make fetch-port-submodules
cd esp-idf
git checkout origin/circuitpython-v5.5
g reset --hard
# new shell
. ./esp-idf/export.sh```
#

I think something was lingering in the esp-idf component submodules

manic glacierBOT
slender iron
#

Baby is waking up but... why do we have our own version of memcpy?

slender iron
vernal sage
#

I'll give it look. Dropping the spiflash is interesting since right now I am failing esp_flash_api.c:rom_spiflash_api_funcs->start(chip); but I think I may have some bad pin defs for the spi psram

full plume
#

going by git-blame comments, it looks related to optimizations - specifically related to word vs byte copies. If it's aligned on a 32 bit boundary, it will copy 32 bit words first, then one 16 bit and/or one byte for the remainder. Wouldn't be surprised if the standard glibc version does even more complicated stuff (beyond just dealing with 64 bit words), so there could be plausible justification for having "our own version". That said, seems like it should be primarily a MicroPython level change. You'd think it would be simple to have GitHub pull up a pretty diff between a source file and it's "ancestor" in another repo (like micropython/micropython), but nooooo.... or maybe it's just me missing something obvious. But an old school side-by-side MK1-eyeball compare shows the main difference being extra conditional compilation directives in CP to skip the optimization unless CIRCUITPY_FULL_BUILD is true - save space for tiny boards?

fiery pecan
fiery pecan
# fiery pecan That's the most recent `git blame`, but it goes back much further: https://githu...

Additionally, according to https://github.com/micropython/micropython/issues/337, there was a migration to a "HAL". Around the time the aforementioned file was created, there existed an (almost) identical copy of that file in stm/string0.c, without the keyword "hal" in the path. I'd assume it was literally copied from that. The oldest git blame of that file is here: https://github.com/dhylands/micropython/blob/ed65605edc5c1376947a34723b9c750400b5a028/stm/string0.c#L4

GitHub

MicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems - micropython/micropython

GitHub

The Micro Python project. Contribute to dhylands/micropython development by creating an account on GitHub.

wraith crow
#

I think I have the firmware fully working for the Olimex RP2350pc, the only problem is that in addition to the Circuit Python changes, it took commenting out three lines of code in tinyusb->rp2040_usb.c. I suspect that means I need to open an issue with hathach/tinyusb but does that mean I need to write some sort of non-circuitpython standalone reproducer?

tulip sleet
wraith crow
#

Ok thanks. I suspect It’s not as simple as deleting the lines, but I think there’s a pending PR that holds promise. Unfortunately, when I try applying it I still have issues. I think I’ll try explaining my situation on that PR first though

lone axle
#

There wasn't any bootloader update required for Metro RP2350 between beta.2 and beta.3 was there? I have a metro that I just upgraded via UF2 and afterwards it comes up with only CPSAVES. no CIRCUITPY

full plume
upper radish
#

Included has been a labor of, let's call it love, for the past few weeks; this proof-of-concept was developed with help from Claude Code and has grown out from another CircuitPython-related project. This fork https://github.com/johnnohj/web-editor of the CircuitPython.org web-editor includes a web assembly build of CircuitPython under a new 'Virtual' workflow option, giving users access to a CircuitPython interpreter inside the browser. Focus has been on implementing a functional REPL experience. References to other features serve as suggestions for future integration. Instructions included to spin up a local dev server on localhost:3000 - I hope this effort provides at least a novel curiosity for those interested to try. blinka_cooking

full plume
upper radish
slender iron
#

@lone axle do you have time to chat about the i2c/spi unification?

wraith crow
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 10.0.0-beta.3 on 2025-08-29; Adafruit Feather RP2040 with rp2040

Code/REPL

import board
import time
import neopixel
import digitalio

import alarm

import adafruit_debouncer

from adafruit_led_animation.color import RED, GREEN, BLUE, PURPLE, BLACK, GOLD


class Main:

    def __init__(self):
        ########################
        # set up key

        self.keypin = digitalio.DigitalInOut(board.A1)...
vernal sage
#

How do you enable coredumps for espressif? More specifically how do add the espcoredump component? It seems like anything I add in the Makefile and it just gets pruned

manic glacierBOT
slender iron
vernal sage
#

So far I've come to the conclusion that it is hanging in the xPortStartScheduler esprv_int_set_threshold call. Just skipping that for giggles and I end blow past the yield but some progress

slender iron
#

what version of my branch are you based on?

vernal sage
#

I pulled the two commits last night after you squashed

slender iron
#

hrm ok

#

that's the latest I have

vernal sage
#

I am partly chocking it up to the c61 still being alpha in 5.5 given logs like this
W (1060) clk: esp_perip_clk_init() has not been implemented yet

This is where things are at though: https://github.com/dbd/circuitpython/commits/dbd-esp32c61/ Mostly c61 specific besides these two

6ad2bc082c [ports/espressif/digitalio] update GPIO_HAL_GET_HW reference for IDFv5.5
63e04bfa3d [ports/espressif] stop relying on GPIO_PIN_MUX_REG for IDFv5.5
#

All this effort for just 2MB of PSRAM

I (764) esp_psram: Speed: 80MHz
I (1286) esp_psram: Adding pool of 2048K of PSRAM memory to heap allocator
manic glacierBOT
#

@anecdata I have been testing with variants of your client and server programs. I can reproduce with a server that's running on Linux as opposed to a server running on Pico 2 W or ESP32-S3. The ESP32-S3 server seems identical in behavior to the Pico 2 W server.

One unusual thing about the client is that it asks to send the whole payload, but only tries to .send() once. It will send a max of 1460 bytes at a time. It will also receive partial packets, but doesn't attempt to drain the socket ...

manic glacierBOT
#

I think in theory, server shouldn't matter, but the exceptions we're seeing (ECONNRESET and EBADF) may indicate something is not quite right - maybe about the server closing the connection? That time.sleep() shouldn't be necessary after the server closes the connection, but even in 9.2.4, there are a lot more exceptions at the client without it.

The 1460 is per frame? But deep down, I assumed TCP handles splitting, recombining, sequencing, error-checking, etc. The client closes after...

manic glacierBOT
#

I think there may be some race condition going on about the socket transitioning to disconnected.

The .close() in the server is supposed to wait until all the data is sent, but that means delivered to the client computer, not necessarily read by the client program (I think). Maybe the problem is that the socket state is checked after it is closed and is detected as a reset.

1460 is the maximum data size in a single packet, right.


I think there are two problems here. One is a critica...

manic glacierBOT
manic glacierBOT
#
  • Fixes #10618

  • Make all port_* storage operations use critical sections, not just those for LWIP.
  • Fix a bug in espressif that was raising the wrong error code on a connect() failure. Discovered in passing.

This is a draft for now because there still seem to be occasional crashes on CYW43, and I want to understand why a connect failure is ECONNRESET instead of ECONNREFUSED, as it is on Linux.

@anecdata FYI

manic glacierBOT
vernal sage
#

@slender iron Success!

0;🐍REPL | 5.0.0-beta.0-4145-g24b25d4d23-dirty
Adafruit CircuitPython 5.0.0-beta.0-4145-g24b25d4d23-dirty on 2025-09-13; ESP32-C61-DevKitC-1-N8R2 with ESP32C61
>>> import gc
>>> print(f"Mem free: {gc.mem_free()/1024/1024:.2f} MB")
Mem free: 1.98 MB
manic glacierBOT
#

I'm not sure how to account for the hard faults I saw earlier with "picow-guard-all-port-storage" Adafruit CircuitPython 10.0.0-beta.3-3-geaca0bb751-dirty on 2025-09-07; Raspberry Pi Pico W with rp2040. I haven't seen any in 2 hours on 2 Picos - one without PulseOut talking to a Pico2 server, the other with PulseOut talking to a macOS server. I didn't think I'd changed the code materially, just minor timing tweaks.

Have you seen a hard fault with "picow-guard-all-port-storage"? Sounds like...

#

Have you seen a hard fault with "picow-guard-all-port-storage"? Sounds like you had. I'll let this run longer, then revert to the posted client code for an overnight run.

I thought I did, but very rarely. I also saw the assert(), but only two three times out of dozens of other runs, and you have to make a DEBUG=1 build on Pico-W for the asserts to be checked. I have not seen any hard faults when running the same code on an ESP32-S3 client.

manic glacierBOT
#

I've been running the client code on 10.0.0-beta.3-3-geaca0bb751-dirty, as posted in the original comment except buffer size 1024. The only tweak I've made to the servers is in the finally: to vary the delay with time.sleep(0.1 + random.random() / 10) (to avoid potentially getting synchronized into some exception state). I haven't seen any hard faults, and very few exceptions. There may still be something lurking, like the close happening prematurely, but I'm not seeing any reason not t...

manic glacierBOT
manic glacierBOT
tulip sleet
#

@crimson ferry it is hard to tell the 4MB and 8MB QT Py S3's apart -- it's only the chip labeling

#

esptool.py chip_id may help:

$ esptool.py --port /dev/ttyACM0 chip_id
 esptool.py --port /dev/ttyACM0 chip_id
esptool.py v4.8.1
Serial port /dev/ttyACM0
Connecting...
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.1)
Features: WiFi, BLE, Embedded Flash 4MB (XMC), Embedded PSRAM 2MB (AP_3v3)
crimson ferry
#

I never bought any No PSRAM, it's definitely a 4/2 S3 that was working, but maybe part of flash is bad. But I have it working on a reverse TFT S3 now.

crimson ferry
#

sorry, I was wrong, apparently did buy a no-PSRAM o_O

tulip sleet
#

The no-psram board was introduced first, I believe. It has a noticeably lower SKU number

manic glacierBOT
#

Between 10.0.0-alpha.4 and alpha.5, this code.py started crashing on SAMD51, specifically PyPortal:

import board
import sdcardio
import storage
import time

spi = board.SPI()
cs = board.SD_CS

print("mounting sd card...")
sdcard = sdcardio.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
print("sd card mounted")

while True:
    print("sleep 1")
    time.sleep(1)

It prints sleep 1 once and then hangs.

I'm testing on other ports as well. On an RP2040 Metro i...

manic glacierBOT
manic glacierBOT
vernal sage
#

@slender iron was wifi working on your c6 from your branch?

vernal sage
#

Ah got it working updating the ordering and setting the storage type

slender iron
vernal sage
#

Oh sorry thought you said you had a prompt on one before. I'll split out my changes for esp-idf stuff and the c61 bits so you can cherry-pick just the one if you need it

#

At this point I think it is just bt, pcnt, rmt and twai_ll. I atleast have bt buildable, it got weird since the kconfig just points to source the esp32c6 but I think I did that in sane manner, but that was hanging or core dump. I don't recall which. The rest I haven't dug into since I was prioritizing wifi.

manic glacierBOT
slender iron
manic glacierBOT
vernal sage
#

Still need to test the PinAlarm changes but digitalio seems to be working along with the reset_all_pins

manic glacierBOT
tulip sleet
#

@lone axle hi - I'm working on https://github.com/adafruit/circuitpython/issues/10461, but I can't seem to get any sound out of the Fruit Jam whatsoever, whether with speakers or headphones. I've tried a couple of wavefiles. Here is a simple test audio player that does not seem to be working:

from audiocore import WaveFile
import adafruit_tlv320
import time
import board
import busio
import audiobusio

i2c = board.I2C()
dac = adafruit_tlv320.TLV320DAC3100(i2c)
dac.headphone_output = True
dac.speaker_output = True
dac.configure_clocks(sample_rate=16000, bit_depth=16)

audio = audiobusio.I2SOut(board.I2S_BCLK, board.I2S_MCLK, board.I2S_DIN)
wave_file = open("/mak16.wav", "rb")
wave = WaveFile(wave_file)

while True:
    print("play")
    audio.play(wave)
    while audio.playing:
        pass
    time.sleep(1)

Is there something you can see I'm doing wrong? Tested with mono 8 bit and 16 bit 16 kHz wav files.

lone axle
tulip sleet
#

can i have both devices hooked up?

tiny peak
#

maybe unrelated to your problem, but audio quality will be much worse on the headphone output if you don't do dac.speaker_output = False before dac.headphone_output = True. Sounds a lot better if you pick one or the other.

tulip sleet
#
dac.dac_volume=-20.0
dac.headphone_volume=-52.7
dac.speaker_volume=-20.1
lone axle
#

I have only ever done one or the other. I'm not sure if both will go at the same time.

tulip sleet
#

set dac.headphone_output = False, no help. I am using some Apple earbuds that have a mic too. Maybe I should try TRS instead of TRRS

#

the example is just cribbed from the issue

tiny peak
#

you could try increasing the headphone volume with dac.headphone_volume += 10 or maybe += 20. Maybe start with the earbuds not in your ears

tulip sleet
#

is dac_volume = -20 OK?

tiny peak
#

somewhere on github there's a sample app I wrote that uses a synthio test tone with serial console commands to let you interactively tweak all the volume settings

tulip sleet
#

or should I increase that too? IIf I understand right, there are two gain stages

wraith crow
#

I don't know how the interaction with headphone_volume and speaker_volume work but I'm generally running with dac_volume higher than that

tiny peak
#

I recommend using headphone_volume and speaker_volume as gain controls to adjust for differences in sensitivity between audio output devices (which vary in impedance and loudness). Then, once balanced, you can use dac_volume as the regular volume adjustment control for your user facing UI.

#

If you look at the FruitJamOS repo where it does volume adjustment stuff, that will give you an idea of a good target range for dac_volume. Tim knows more about that.

lone axle
#

There appears to be something else going on I think

#

I'm not getting any sound attempting to play wave files either now when doing it direct with TLV library as shown in the code above. Playing them through the Fruit Jam library is working though.

tiny peak
#

Is this right (from example code above:

audio = audiobusio.I2SOut(board.I2S_BCLK, board.I2S_MCLK, board.I2S_DIN)
#

looking at my volume adjuster sample app, I did this:

audio = I2SOut(bit_clock=I2S_BCLK, word_select=I2S_WS, data=I2S_DIN)
tulip sleet
#

makes sense to me, the issue is from a while ago and maybe Tim was using different pins due to a pin swap

tiny peak
#

my memory is fuzzy, but was it the MCLK and WS pins that got switched around rev C?

lone axle
tulip sleet
#

I have the product one with the wrong IR resistor

#

you must have been testing with an early one. OK, I think that's it

tiny peak
lone axle
#

yeah, init should be like this:

audiobusio.I2SOut(board.I2S_BCLK, board.I2S_WS, board.I2S_DIN)
tulip sleet
#

works now!

#

thanks everybody!

lone axle
#

I do think I was using the one with swapped pins when I made the issue.

tulip sleet
#

the speaker is ridiculously quiet even with dac.speaker_output = True

#

I made the gain 0 instead of -20

tiny peak
#

that's odd. Are you using the Fruit Jam kit speaker, or something else?

tulip sleet
#

yes, fruit jam speaker

#

I'll run your test program

tiny peak
#

you might also try Tim's FruitJamOS stuff to see what you think of its default volume range

#

The driver is set up to be pretty quiet to avoid accidental hardware damage

#

In most use cases it will probably be necessary to provide UI controls for increasing the volume, and perhaps to restore a saved volume

#

for a while people were blowing up their speakers

tulip sleet
#

i was in the loop for the code review but didn't actually try it 🙂

wraith crow
#

just me blowing up speakers I think 😁

lone axle
#

I am thinking of bumping the default volume a little higher still. At the same time as swapping to use floats 0.0 - 1.0 for volume in fruit jam library. I tested before with synthio but have found the waves included in the boot animation and some of the projects still come out on pretty low.

tiny peak
#

at one point tannewt zapped the DAC on one of his prototype boards too, IIRC. Seems like he mentioned that on one of his last Deep Dive shows.

manic glacierBOT
#

The reason for this is that the TLV320DAC3100 and the ESP32-C6 shared a reset line, board.PERIPH_RESET (aka board.ESP_RESET) on the Fruit Jam. To set up the C6 requires pulling its reset line low, which will reset the state of the TLV320.

The TLV320 does not need to be hard-reset in general. You can reset it over I2C with a RESET command, and there's nothing in the library that deals with the reset pin.

I will add a warning to the Fruit Jam guide to init the ESP32-C6 first, and that any...

manic glacierBOT
manic glacierBOT
#

Hi folks, thanks for reviewing this with perfect timing. I've been asking myself this as well. I ended up needing a 2nd esp32-c3-lyra board and it arrived today, and I don't have this problem on the 2nd board, so it seems to me that the first board I was testing on has a broken hardware pixel that I worked around.

I'm pretty confident the pixel on the first board is bad since there's some additional glitches under slightly more intense usage - there's clearly something a bit off with the...

manic glacierBOT
#

I was testing this on my modified tinyUSB build and ran into a memory error when trying to run Fruitris so I tried on the stock Fruit Jam and got the same error:

/apps/Fruitris/code.py output:
Traceback (most recent call last):
  File "/apps/Fruitris/code.py", line 37, in <module>
  File "adafruit_fruitjam/peripherals.py", line 113, in request_display_config
MemoryError: memory allocation failed, allocating 307200 bytes

manic glacierBOT
#

...ran into a memory error when trying to run Fruitris...

Thinking about it, that makes sense. My sample code doesn't use any large buffers, and it calls release_displays(). For RAM intensive code, if enough buffers get allocated to fill up internal SRAM, or to significantly fragment it, then all the various DMA-fix dynamic allocations could end up fighting for a scarce or non-existent SRAM heap space.

Perhaps, instead of dynamically allocating SRAM buffers, `shared-module/usb/core/...

manic glacierBOT
#
  • Fixes #10487

  • In raspberrypi rotaryio.IncrementalEncoder, make object be marked as deinited if constructor fails.
  • In all rotaryio.IncrementalEncoder implementations, implement and use common_hal_rotaryio_incrementalencoder_mark_deinit() consistently and same for rp2pio.StateMachine.

Note that in some previous implementations, both IncrementalEncoder pins were NULL'd out on deinit. This was not really necessary, because the deinit test just checks that one of the pi...

thorny jay
# tulip sleet I made the gain 0 instead of -20

I played with the FruitJamOS, and I could not figure out where the sound was supposed to get out of...
I connected the speaker, and expected to hear something, but not really (using the boot animation, and using the music game).
Then I connected/added a headset, and there I could hear a little bit. (it was not clear to me if I had to disconnect the (official) speaker.
Also, it was not clear exactly where to glue the speaker, or let's say in what direction... there is a mark on the PCB, but that place is full of component. I did not see clear instruction on the learn guide (but I did not search much).
PS1: I installed everything one or two weeks ago maybe, so I might not have the latest version.
PS2: I have two FruitJam, but I only tested one, I could test one with the speaker and the other one without the speaker.
PS3: I don't hear very well, but people around me had the same issue.

tidal meteor
tulip sleet
#

The current volume settings are quite low and will be tweaked.

tulip sleet
tulip sleet
manic glacierBOT
#

The idea of audio effect/mixer chaining was theorized in one of the first audio effects PRs, https://github.com/adafruit/circuitpython/pull/9640#issuecomment-2389776124, but never actually implemented.

The updates in this PR are relatively simple. Instead of returning None within play(...) methods of audio objects which allow both input and output (effects and mixer), it instead returns a reference to itself.

With this minor update, rather than building audio chains the old way:

...

wraith crow
lone axle
#

I've made a note on my list to update that page with the audio controls.

#

I'm going to update the fruit jam lib to use 0.0 - 1.0 range first so the docs can reference that from the beginning.

#

I will expand the guide more generally to mention the default behavior of audio and how to change it.

wraith crow
#

Until foamyguy’s updates, For speaker {“audio”:{“output”:”speaker”}} 😁

wraith crow
thorny jay
# wraith crow I would also recommend updating the firmware, libraries and fruit jam os frequen...

Fully understand that.

I wanted to start a list of "imperfection" from an "end-user point of view".

  • Sound was issue number one.
  • Switching to terminal display between FruitJamOS and "FruitJamApplication" is also "uggly" and I would prefer the terminal to be hidden, and just a black screen.
  • Maybe some lack of common behaviour between application (like how do I get out of a game/application)
  • Maybe common setting (like sound level) but I have seen issue or stream that let me to believe that this is worked on.

I am not sure the best "channel" to share "opinion" about the "look and feel" of the resulting CP+FruitJamOS+Application combo.

manic glacierBOT
lone axle
# thorny jay Fully understand that. I wanted to start a list of "imperfection" from an "end-...

An issue on the Fruit Jam OS repo is probably the best place to start a discussion: https://github.com/adafruit/Fruit-Jam-OS/issues

Switching between terminal and display is not something that the Fruit Jam OS layer has control over I don't think. CircuitPython itself automatically shows the terminal when it starts up. The "launching apps" mechanisms involves restarting circuitpython so it will show the terminal when that happens unless behavior in the core is changed I think. In any case I'd want a change like that to be optional if possible because I find the switching kind of charming in a way even if it's jarring by modern UX standards.

As for common behaviors: ctrl+c should be able to exit out of any app/game. Then can go back to the launcher with ctrl+d. Other games/apps do provide other mechanisms as well like pressing q at the end of the game will exit a few of the ones I made but it is up to individual apps to provide any behavior beyond the ctrl+c / ctrl+d that is built-in to CircuitPython.

manic glacierBOT
manic glacierBOT
vernal sage
#

Didn't realize that was going to post here and made the comment so it wouldn't get lost in discord. Apologies if comments on drafts are discouraged

manic glacierBOT
orchid basinBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

@RetiredWizard I wasn't able to reproduce your error with Fruitris. Were you doing anything special?

My setup:

  • Fruit Jam rev D board
  • CircuitPython UF2 file from this PR's CI build
  • Fruit Jam Fruitris 1.0.0-alpha.5 project bundle zip file
  • EVGA XR1 lite HDMI capture card
  • Adafruit generic SNES gamepad or 8BitDo SN30 Pro gamepad (both work fine for me)

I did have to make a couple attempts to get all t...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

This is a revision to @tannewt's earlier PR that used dynamic allocation in the SRAM heap:

This is intended to fix https://github.com/adafruit/circuitpython/issues/10562

Changes relative to tannewt's PR:

  1. Use a fixed size static global buffer
  2. Remove exceptions about allocation failures
  3. Implement several length checks to avoid possible buffer overflows. When a requested length is too long, it will be silently truncated to...
#

I tested a local build of this code with my reproducer code from https://github.com/adafruit/circuitpython/issues/10562 and with Fruit Jam Fruitris 1.0.0-alpha.5. Both worked fine.

I did not try installing Fruit Jam OS, so I haven't actually seen the problem that RetiredWizard reported. I'm not sure if this code will fix that. But, since I removed the dynamic allocation stuff, it seems possible.

tiny peak
#

CI maintainer folks, I got a build error on this PR which seems to have been caused by a http 403 from attempting to fetch a Ubuntu 24.04 image from Azure. The error only happened for one build. Looks like something weird is going on.

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

Also, it might work fine to set the default buffer size to something much lower, like 128 or perhaps 64. The supervisor uses TinyUSB's HID class driver in a way which probably (maybe? not sure) does not depend on anything in shared-module/usb/core/Device.c for fetching configuration descriptors.

I'm not sure what other code might depend on being able to read large configuration descriptors in one control transfer call. I think it would probably work fine to write code that made a series of...

lone axle
#

it may have been an issue with the server hosting the file at the time the request was made.

plain oasis
#

While creating a PR for the MMA8451 library i noticed that the ruff formatter when run locally fails to start because rule E999 is available anymore but selected by default. Is there any specific configuration required to run ruff locally?
Makes it a bit problematic to check if it meets the rules before pushing.

manic glacierBOT
#

Apparently having a launcher.conf.json file with:

{
    "use_mouse": "True",
}

Fruitris doesn't utilize that property at the moment, but my guess is that the initialization of that device within Fruit Jam OS before loading the application might have been the cause.

is the difference, ~however it didn't look like the keyboard plugged into the usb port of the fruit jam was working properly even when the program loaded with no launcher.conf.json file. The arr...

lone axle
# plain oasis While creating a PR for the MMA8451 library i noticed that the ruff formatter wh...

What version of ruff are you using, and how do you launch it? We typically use pre-commit to run ruff and the other checks, and it seems to be working okay inside that repo:

~/Adafruit_CircuitPython_MMA8451$ pre-commit run -a
check yaml..................Passed
fix end of files............Passed
trim trailing whitespace....Passed
ruff-format.................Passed
ruff........................Passed
reuse.......................Passed
plain oasis
lone axle
#

I'm not opposed to updating to a newer version of ruff, but that will require a much wider change in the cookiecutter and all the rest of the library repos, since we use the same configuration in all of them. It would be good to get rid of deprecated configs ultimately.

plain oasis
#

Good to know. Just noticed that while checking the PR after the first verification failed. Then for a local check removing E999 or using an older version is probably enough.

btw. regarding the open PR i am open to feedback if a different approach is preferred to ensure a proper delay after the MMA8451 reset. A simple 1ms delay is in theory enough but as the startup time is not really specified in the datasheet a dynamic retry loop may be more reliable.

lone axle
#

I think the latest version is good, I reviewed the PR, thanks for working on that.

manic glacierBOT
#

@todbot You use synthio a lot, and I do not. Would you have any comment? Thanks!

Looks neat! I remember advocating for something similar with digitalio long time ago.

I didn't realize mixer.play(playable, voice=num) existed. Is that equivalent to mixer.voice[num].play(playable)?

My only concern (as w/ everything in the core modules now) is that the added feature will push out other modules on ports that are at the limit.

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

Thanks for submitting a pull request to CircuitPython! Remove these instructions before submitting.

See https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github for detailed instructions.

  • Consider whether to submit this PR against main or against (if it exists) the branch for the current stable release or an upcoming minor release. The branch will be named i.j.x, for example, 9.2.x. Bug fixes and minor enhancements can be submitted against the stable release b...
#

I'm not sure I want to do so far as a static allocation. Silently failing if a request is longer than the buffer isn't good and allocating more than you need seems subpar too. One thing we could do is share the temporary buffer amongst all devices. Right now it is per-device.

Allocating the large framebuffers late after startup will also be risky. It's much better to do the largest allocation first and keep it.

slender iron
#

@vernal sage want to PR your changes into my branch?

#

actually I can just pull in the commits

manic glacierBOT
#

Trying some variations using Adafruit CircuitPython 10.0.0-beta.3 on 2025-08-29; Adafruit Feather M4 Express with samd51j19 on two Feather M4s...

The controller's 8 pre-loaded bytes should get rotated from controller to target, and the target's 8 pre-loaded bytes should get rotated back to the controller. Instead, it looks like the controller reads back some of what it wrote, and the target gets gibberish. The controller initiates a transaction every second. The target is only doing a ...

manic glacierBOT
#

...Silently failing if a request is longer than the buffer isn't good and allocating more than you need seems subpar too...

Some things to weigh here as you consider how to move forward with this:

  1. What counts as "failure"? The TinyUSB transfer calls are designed to return their actual length of transferred data which may be less than the requested length. This is a pretty normal way for C IO functions to behave. The PyUSB API is also designed to be consistent with this by returning t...
slender iron
#

@gilded cradle I'm using code-beta.cp.org with an ESP32-C6 via the internal usb to serial converter. On connect I'm seeing the device reset. Is the editor doing this or my OS?

vernal sage
#

I did a bit more testing from from branch, I think the C61 is done at this point since it is missing RMT/PCNT/TWAI. I flashed a TinyC6 and the default neopixel test was running from. I tried to flash the MetroS3 but that likely needs a partition update as well the lib changes you mentioned your PR

slender iron
#

kk

#

I'm starting with C6 testing and will do the others this week

#

Thanks for the help!

#

just pushed my branch with your changes plus the string0 change

vernal sage
#

I foolishly didn't check the C61 block diagram before starting this whole thing so I'll probably have the C5 branch up tomorrow. All I want from a board is matter/thread and some PSRAM. Hopefully that is just the boilerplate stuff though given the TinyC6 worked fine

manic glacierBOT
orchid basinBOT
#

Bumps rexml from 3.4.1 to 3.4.2.

Release notes
Sourced from rexml's releases.

REXML 3.4.2 - 2025-08-26
Improvement

Improved performance.

GH-244
GH-245
GH-246
GH-249
GH-256
Patch by NAITOH Jun

Raise appropriate exception when failing to match start tag in DOCTYPE

GH-247
Patch by NAITOH Jun

Deprecate accepting array as an element in XPath.match, first and each

GH-252
Patch by tomoya ishida

Don't call needless encoding_updated

GH-259
Patch by Sut...

manic glacierBOT
manic glacierBOT
#

On a Metro ESP32-S3, there is no automount after a hard reset, because there are no `DEFAULT_SD_*``. (The card detect pin on the SD card socket is not wired up.)

I did simulate a default SD card by wiring to an SD breakout and add DEFAULT_SD_* values for those pins. It did not work, and caused USB disconnection as on PyPortal.

When manually mounting the SD card with the on-board socket in code.py, the card does show up as a drive in Linux, but the board reliably does an auto-reload res...

wraith crow
#

@lone axle I just noticed in the recent learning guide PRs, you left it so that volume_override_danger set both the volume and the new safe limit. In your deep dive you had mentioned that you thought they should be separate. Did you change your mind? If not, and you don't have time, I can throw a quick PR in tonight to set them as you had defined in the deep dive.

lone axle
wraith crow
#

okay, I'll submit a PR later tonight that does both...

lone axle
#

Thank you!

gilded cradle
#

@slender iron I'll have to take a look

slender iron
#

kk

#

its an esp32c6 that I'm trying

gilded cradle
#

I should have one somewhere

#

ah, found it

slender iron
#

I'm monitoring the esp_log via uart to see that the device restarts due to the serial to jtag triggering it

#

could be a linux thing

#

or maybe some restart trigger leaking over from a shared serial library?

gilded cradle
#

@slender iron I don't think it's resetting. Does the reset cause it to disconnect?

slender iron
#

no, but it does the startup blinks again

#

it doesn't fully connect afterwards anyway. I was just starting to debug it

#

does it work for you?

gilded cradle
#

Yeah, it seems to work fine for me on mac.

#

I was able to connect, open code.py, edit it, save it, and run it.

manic glacierBOT
#
  1. As long as the buffer is big enough, getting a shorter than requested actual length should be a rare thing.

This won't be under the program's control if we silently allocate a shorter buffer internally. I agree that the argument should be checked but it should be a sign of the device's response length, not an intermediate limitation.

2. I would expect this could easily lead to fragmentation of the SRAM heap.

My code doesn't allocate until a transfer with a PSRAM buffer is don...

#

Thank you for the new board definition. It looks like you didn't update your submodules and then added them all to your commit. Please explicitly add files to your commits to avoid this mistake.

To fix this, I think you can 1) checkout the submodules from the parent branch 2) switch to your PR branch 3) git add all of the different modules and then git commit --amend to integrate them back into this PR's last commit. You'll need to push with --force-with-lease to replace this current...

#

Do we know what is causing the buffer allocation in Fruitris and why it occurs before the new framebuffer is allocated?

Taking a quick skim through the adafruit/Fruit-Jam-OS repo, I didn't see any sign of calls to gc.collect(), and it's obviously pretty graphics intensive and the launcher uses some USB host stuff. My guess is that that stuff leads to a fragmented SRAM heap by the time the launched program gets loaded? Maybe?

slender iron
manic glacierBOT
#

Part of what I was thinking with the static buffer approach is that it would buy folks some extra breathing room by making heap fragmentation less likely. That way they wouldn't have to think as much about managing memory allocation when writing Python code. OTOH, you could definitely make an argument that people should consider memory management more in their Python code by calling gc.collect() and allocating large buffers early.

willow totem
#

How do I see the partition size circuitpython creates on the fruit-jam? I want to consider matching the app / user-fs ratio for the WipperSnapper installer. Tried using picotool partition info but didn't show anything / recognise the setup (CPY v10).
I've gone with 8mb/8mb for "reasons" (adafruit_fruitjam.menu.flash.16777216_8388608), but this is the choice list: https://github.com/earlephilhower/arduino-pico/blob/master/boards.txt so was wondering if there was a better option.

crimson ferry
crimson ferry
#

(and .h in board folder, where the saves partition is defined… but where does it go? 🤷‍♂️)

willow totem
crimson ferry
#

I wish all boards had a saves partition, even if it was small… Some place to put things more complex than bytes in flash by code.py

willow totem
#

yeah it's a good one. I also like the idea of accessing log files that way, read-only to the user

#

not sure the longevity of flash and logging but ignoring that...

lone sandalBOT
manic glacierBOT
#

gc.collect() isn't involved here. It manages the VM Python heap.

The framebuffer error is caused by the "outer" heap fragmentation which separately manages the internal SRAM and the external PSRAM. The internal SRAM is only used for buffers that are used by DMA (like the framebuffer) and buffers that need to be accessed when PSRAM access is disabled (like the USB buffers.)

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.0 on 2024-10-28; M5Stack Dial with ESP32S3

Code/REPL

import board, os
from digitalio import DigitalInOut, Pull

import usb_hid, time # , neopixel
import time, busio, rotaryio, terminalio, displayio

import adafruit_focaltouch

KEYCODE_ON_RINGBUTTON = KEYCODE_ON_MULTITOUCH = KEYCODE_ON_TOUCH= [1,2,3] # Faked for Github
TOUCH_DEBOUNCE=.0005
textColour=0xfe8a2c

print(os.uname().machine)

# create ...
manic glacierBOT
slender iron
tulip sleet
#

@slender iron re the automount bugs: i have not yet found the cause of the disconnects on atmel-samd. forcing tud_task() calls every msec doesn't solve the problem. There are differences in supervisor/port.c and usb.c between ports that work and those that don't. I added a task-ready check but it didn't help.

The 70-second auto-restart on Linux also happens on RPi Linux, so it's generic. I have a USB trace that shows some activity from the host at that time, tickling the SD drive, it appears.

We talked at the Wednesday meeting about maybe turning the automount stuff off for 10.0.0. Our we could have it on only for Fruit Jam and other boards where the automount can be done before, but that doesn't solve the 70-second restart on Linux. Happy to talk about this if you have time.

tulip sleet
#

there is a fix in code that is not in beta-code, I thnk, that Tim made a day or two ago and I approved

slender iron
#

I can chat if you want

#

I was using latest from main

manic glacierBOT
#

Will do that now and then push it here.

If I understand correctly, you're proposing to do a heap allocation and deallocation of the full size buffer for every Device.read(). That might be okay. But, could you hold off on merging that until we have the chance to test how much additional latency it adds?

I'm concerned that MIDI polling in particular is already apparently too slow such that it drops notes.

#

If I understand correctly, you're proposing to do a heap allocation and deallocation of the full size buffer for every Device.read(). That might be okay. But, could you hold off on merging that until we have the chance to test how much additional latency it adds?

Yup, just pushed. Please give it a test. I only made sure it compiles for Fruit Jam.

I'm concerned that MIDI polling in particular is already apparently too slow such that it drops notes.

I suspect MIDI needs a separat...

manic glacierBOT
manic glacierBOT
#

I tested the build for the latest changes and it works fine with my MIDI synth and gamepad stuff. The amount of stuck notes on the MIDI synth didn't seem any better or worse than before these changes. If RetiredWizard tries this and it works okay with Fruit Jam OS + Fruitris, then as far as I'm concerned, this is good to go. I have some reservations about _abort_transfer(), but it's probably fine. Whatever. Fixing the crash is more important.

#

I suspect MIDI needs a separate higher level API that is implemented using TinyUSB's MIDI support for buffering. What is the way to do it in CPython on Linux?

Not sure. Aside from PyGame's pygame.midi I haven't run across much in the way of MIDI coding using Python on full size computers. It's more common to see stuff using C/C++ or one of the special purpose music programming languages (Pd, Max, Faust, Supercollider, ChucK, Sonic PI, etc). ...

manic glacierBOT
manic glacierBOT
#

I was able to shrink down my example code

import board, os
from digitalio import DigitalInOut, Pull
import usb_hid, time 
import time, busio, rotaryio, terminalio, displayio
import adafruit_focaltouch

print(os.uname().machine)

# create the switch, add a pullup, start it with not being pressed
button = DigitalInOut(board.KNOB_BUTTON)
button.switch_to_input(pull=Pull.UP)
button_state = False

def get_touches(debug_str=""):
    touch_touched = None
    try:
        if 'touches' in dir(tou...
manic glacierBOT
#

I have what I think is a V1.0 MSStack Dial. I loaded both 10.0.0 beta.2 and beta.3 on the board (.bin, since there is no named TInyUF2 version).

I was unable to cause a crash. Your simpler program runs, printing a lot of stuff on the display. I click the button and touch the screen, and nothing bad happens. Was there something specific you did?

The difference between V1.0 and V1.1 seems to be STAMP S3 vs STAMP S3A. But there don't appear to be spec differences that would cause a problem.

G...

lone sandalBOT
manic glacierBOT
#

Summary of testing

PyPortal (SAMD51): mount SD manually card in code.py, and then print a count once per second

  • After only one or two seconds, the program stalls. CIRCUITPY never appears. Eventually the program starts up again, as visible on the display, and there are one or more reconnects/disconnects on USB serial.
    • A USB trace shows that there is occasional USB MSC activity (SCSI status commands) for tens of seconds. Eventually there is some fatal error in Linux USB subsys...
manic glacierBOT
#

Sorry to comment on something so old and seemingly unfixed / unresolved.

But is it possible to get _bleio back for esp32 boards with psram, but tell it to not use the psram?

I was hoping to talk to a BLE temp sensor and tried using adafruit_ble to no avail since it relies on _bleio and it has been indefinitely disabled for ESP32. @dhalbert said in May 2023 that "ESP32-S3 boards have limited native _bleio support turned on." But I guess that was later changed in december the same year?
...

manic glacierBOT
#

CircuitPython version and board name

CircuitPython 10.0.0-beta.3, MagTag 2025 edition

Code/REPL

from adafruit_magtag.magtag import MagTag
from os import getenv
import gc

url = getenv("PWD_URL")
print("Getting data from URL "+url)
magtag = MagTag(
  url=url,
  json_path=[[], [], ["ssid"], ["passphrase"], ['timestamp'], ['qrcode']]
)

def update(magtag):
  try:
    result = magtag.fetch(auto_refresh=False)
    print("Retrieved data: "+str(result))
    magtag....
#

@dhalbert : I can reproduce this when the Magtag is disconnected from the computer. I just posted the console log for illustration.

I am testing a much simpler version below. The board is currently disconnected from the computer. Will post an update in a few hours when I have tested it more.

from adafruit_magtag.magtag import MagTag
from os import getenv

url = getenv("PWD_URL")
print("Getting data from URL "+url)
magtag = MagTag(
  url=url,
  json_path=[['timestamp']]
)

title_font = g...
#

ESP32 boards for both 9.2.9 and 10.0.0-beta.3 have native _bleio enabled. This has been true for a while now. Is there something not working? Which board are you using?

Ah, ok, that's weird. I am running:

Adafruit CircuitPython 9.2.9 on 2025-09-07; Adafruit Feather ESP32S3 4MB Flash 2MB PSRAM with ESP32S3
Board ID:adafruit_feather_esp32s3_4mbflash_2mbpsram
UID:8B8F268D0BC5

Mine does NOT seem to have _bleio. Even when i look using the REPL >>> help('modules'). I was trying to us...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

From https://forums.adafruit.com/viewtopic.php?t=220287:

I can't initialize two PWMOut on two pins that use the same slice (for example, GP2 and GP3). But if I try, depending on which pin I initialize first, and what parameters I give to the second initializer, I get three different error messages, two of which are misleading. This makes PWM conflicts difficult to debug.

Adafruit CircuitPython 9.2.8 on 2025-05-28; Raspberry Pi Pico with rp2040
>>> import pwmio
>>> import boa...
manic glacierBOT
#

Here is a minimum reproducible example that fails to update after a few hours when the Magtag is plugged into a USB power supply, not a computer. Also, note that I have two Magtags and I can reproduce this failure on both boards, which suggests this is a software issue, not a hardware issue.

from adafruit_magtag.magtag import MagTag
import terminalio
import random

sleepTime = random.randint(1,30)

magtag = MagTag()

magtag.add_text(
    text_font=terminalio.FONT,
    text_position=(20,2...
#

This seems to generate safe mode pretty quickly. I get one or two [Errno 5] Input/output error beforehand.

import board
import adafruit_focaltouch

def get_touches():
    try:
        touch_touched=touch.touches
    except OSError as e:
        print(str(e))
    except RuntimeError as e:
        print(f"RuntimeError", str(e))
    return touch_touched

touch = adafruit_focaltouch.Adafruit_FocalTouch(board.I2C(), debug=False)

while True:
    get_touches()
manic glacierBOT
#

OK, so not even a fetch is involved. When you say "a few hours", is that time actually consistent?

I don't know. It takes too long to babysit.

Could you try 9.2.9 as well? Thanks. It would be useful to know if this is a regression.

Unfortunately no, according to the instructions for installing CircuitPython:

WARNING: The updated Adafruit MagTag 2025 Edition will not work with CircuitPython 9.2.x or earlier. Make sure you in...

manic glacierBOT
tiny peak
#

The CircuitPython meeting is today, right?

lone axle
tulip sleet
vernal sage
#

@slender iron did you ever get a C5 to repl?

#

Of course as soon as I ask, openocd wants to play nice. Back to gdb it is

slender iron
#

C5 and C61 are just a bonus

lone axle
#
lone axle
#

Thanks for hosting Dan! have a great week everyone.

tulip sleet
tulip sleet
#

Here is the notes document for the Monday October 6, 2025 CircuitPython (Bi-)Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Add your hug reports and status updates to the document before the meeting. If you are unable to attend but would still like to contribute, feel free to add your notes and we’ll read them off during the meeting. Hope to see you there! <@&356864093652516868>
https://docs.google.com/document/d/1Tbs6tWOH9oaIUS1076qzb8weuu53jphB2x7t-8VxvgQ/edit?usp=sharing

crimson ferry
#

os.uname() is getting deprecated(?), but sys.implementation has private methods. What is the canonical way to programmatically get the port, chip ype, etc.?

manic glacierBOT
#

When you say "a few hours", is that time actually consistent?

I modified the test so that it is deterministic. See below. I confirmed the number of iterations is not consistent: I got a failure of 61 and 16 trials, on the same MagTag. If you want to start with a fresh count each time, you need to run the two commented lines via REPL.

from adafruit_magtag.magtag import MagTag
import terminalio
import microcontroller

## INIT NVM via REPL
# i = 0
# microcontroller.nvm[0:8] = i.to_bytes(...
crimson ferry
#

thanks, we don't really have port available directly, but I can infer it... I'll lean toward sys.platform and sys.implementation

#

is RP2040 different enough from RP2350 to have sys.platform be the chip and not the port (as opposed to Espressif)?

tulip sleet
#

if we had platform, it might be more helpful, but very little room for it on small SAMD21 builds

#

I don't know where MicroPython is going with this. That comment about deprecating uname is pretty old

#

os.uname() is Linux only on CPython

crimson ferry
#

I think for now I just need to distinguish ports (probably sticking to S3 and RP2350 in those ports)... some data interfaces behave differently by port... so I can do conditionals on port. If I absolutely have to, I can vary by chip.

tiny peak
#

Question for folks interested in making games: Has anybody put any thought into the problem of doing 2D or 3D graphics on Adafruit boards at a higher frame rate than what's currently possible with CircuitPython displayio? I expect that would be possible in Arduino, but doing game logic in C is less pleasant than a higher level language. I've also been considering things like Love2D on Raspberry Pi, the TinyGL software rendering library, etc.

#

Broader context for my question is, I've got an idea for a game I'd like to build using 3d wireframe graphics, or perhaps simple 3d shaded graphics. I'm wondering if I could somehow coax CircuitPython into giving me a tolerable frame rate on a Fruit Jam board, maybe by adding some new performance-oriented graphics API to the core. OTOH, it might make more sense to build on a different software stack, like maybe Lua and TinyGL on top of Arduino or Pico-SDK.

tiny peak
#

Or phrasing my question a bit differently: Would it be totally ridiculous to even consider attempting to add a limited OpenGL-like (TinyGL) software rendering API to CircuitPython?

#

Or from a third angle: What do core devs think of the potential long term maintenance impact for adding more game-framework-like features to CircuitPython vs. an approach of porting (or creating) a Lua-scriptable game framework to run on top of existing Arduino libraries (or Pico-SDK)?

fiery pecan
blissful pollen
#

At the same time directly blitting a Gif from OnDiskGif was able to get decent rates. So it is possible.

wraith crow
#

It doesn't appear that the adafruit_fruitjam library in the bundle circup uses has been updated with the most recent PR (5 days ago)....

fiery pecan
# tiny peak oh wow! very interesting.

However, the device it runs on doesn't exactly fall under the category of "Adafruit boards" that you initially asked for. Although it was sold on Adafruit's website at one point in the past, it's technically manufactured by Pimoroni.

tiny peak
# fiery pecan However, the device it runs on doesn't exactly fall under the category of "Adafr...

eh, close enough. The code is very interesting. Looks like they use geometry exported from Blender and feed that into a custom rendering engine that keeps one core busy. Then the c++ game logic runs on the other core. So, that at least validates the idea that software rendering of mildly complicated geometry ought to be doable. I'd expect that though. The bigger question would be how to package a rendering API such that you could do game logic in a scripting language that wasn't terrible for beginners to use.

tulip sleet
#

@tiny peak Scott might have more to say. displayio was inspired by the display architecture of memory-limited game systems, with tiles and sprites.

We have talked about doing lvgl. I'm not sure how good that is for gaming.

tiny peak
#

I don't think lvgl would really help much as it seems heavily oriented towards making 2D GUI stuff for touchscreens (lots of IO widgets for making forms and control panels)

#

For making stuff like platformer games, or perhaps the kind of 3D you'd need for a lo-fi flight simulator or racing game, it would be useful to have a library that's oriented towards a game rendering loop. Like, the loop would target 60 or maybe 30 fps, and each time through it would check inputs, update all the world state, then render a new frame from scratch.

tiny peak
#

For 3D stuff, it would also be helpful to have code to help with things like culling, shading triangles, animating the camera, and such.

#

It would also be really nice to have something that could sync the animation loop with the PicoDVI vertical refresh.

#

I'm not sure if it would be practical to modify CircuitPython to be compatible with that style of animation loop.

lone sandalBOT
lone axle
full plume
stuck elbow
full plume
#

IMHO getting non-trivial 3D graphics in CircuitPython would be a major uphill battle which might not be feasible to run on most current CircuitPython boards. Python support for 3D graphics has been a side quest of mine for a long time - I went so far as building a python wrapper for OpenGL at one point. It's been a few years since I went searching for a decent solution - most of my use cases involve highly interactive visualization of very large data sets. I've yet to find something that does that well with Python bindings.

stuck elbow
full plume
#

Python support for 3D rendering has gotten better though - I've played with Panda3D a bit and it seems promising for gaming. However, getting it running well on a CircuitPython controller could be challenging.

#

Most Python "3D" systems are wrappers around C/C++ libraries. AFAIK there's not a trivial way to port CPython-API based wrappers to build as Micro/CircuitPython extensions. It's also likely that those wrappers (and the underlying C/C++ 3D engines) use some form of RAII based on CPython reference counting, which is not going to play well with Micro/CircuitPython's GC memory model.

#

FWIW there is cheat/hack that indirectly lets you have a UI with 3D from an embedded controller - which I haven't technically done with CircuitPython but I'm certain it could work well. You run the UI in a browser page, with REST/WebSockets keeping all the "moving parts" in sync but all the display and rendering done on the client. I've done this with Next.JS apps using three.js, where the entire UI is deployed as static javascript (+html,css,...) served from a micro SD card on an ESP32.

#

So it's not on a directly connected display (like the dvi out on a FruitJam), but it is "self contained" (i.e. you don't need anything installed outside your controller - just something with a decent browser which can connect over WiFi). It even works with my Android phone.

fiery pecan
frail swallow
#

using an xiao 2040 and can't see to get it in read/write so I can write a config. boot.py is correct to my knowledge.
I tried an nvm route but also had issues and couldn't get it working.

[Errno 30] Read-only filesystem

import storage, usb_cdc
import board, digitalio

btn = digitalio.DigitalInOut(board.D2)
btn.switch_to_input(pull=digitalio.Pull.UP)
storage.remount("/", readonly=False)

if btn.value:
storage.disable_usb_drive()
else:
storage.enable_usb_drive()

usb_cdc.enable(console=True, data=True)

crimson ferry
#

nvm should work no matter what... can you post the code and exception?

#

@frail swallow is the intention for this boot.py to allow writing to the CIRCUITPY drive from code.py?

frail swallow
#

yes, I just need a place to store/update a config, allowing code.py to create/update the config

frail swallow
#

Let me set back up nvm and see

crimson ferry
#

is there an exception in your boot_out.py?

slender iron
#

@tiny peak I'm open to adding another module to support 3d rendering

#

likely that'd need to be based on some 3d engine for microcontrollers

#

and ideally the api would match something from CPython

#

I don't know of any microcontrollers with 3d accelerators. most are for 2d

#

phone class SoCs will have 3d GPUs but they are much more closed ecosystems

fleet hollow
#

@slender iron @tiny peak I'd love to see _stage.render expanded to support framebufferio.FramebufferDisplay. From there python-ugame/circuitpython-stage could be updated to support the Fruit Jam and other boards with picodvi. 3D acceleration would be cool, but getting 2D graphics to render faster is of higher priority imo in order to enable more detailed action games (platformers, etc).

vernal sage
#

@slender iron esp32c5 branch is up if you want to poke, definitely some stability issues that I need to sort out but it does boot to repl fine after an initial reset. Seens like there are some issues with SPI at >40m when tuning

GitHub

CircuitPython - a Python implementation for teaching coding with microcontrollers - Commits · dbd/circuitpython

tiny peak
#

Thanks to all the folks who gave feedback on the graphics stuff. Sounds like there's general interest in adding better support for a faster way to do game graphics. I didn't know stage was a thing, so I'm definitely gonna need to look into that a bit.

stuck elbow
tiny peak
#

It sounds like there are at least two different levels of capability that people are interested in. First would be just faster 2D graphics, perhaps achievable by modifying the stage module so it can be used with more boards. Second would be some kind of 3D capability using a software renderer (perhaps TinyGL).

stuck elbow
#

it could be possible to do 2d graphics with a framebuffer instead of computing the pixels on the fly like displayio does, it would use more memory, but would be faster for some kinds of graphics

tiny peak
#

I'm particularly interested in lofi 3D capability suitable for building stuff with visual complexity on the order of old school MS Flight Simulator.

stuck elbow
#

real 3d or 2.5d a la wolfenstein?

#

or a la mode7 of snes

tiny peak
#

Not sure. I'm not knowledgable enough about the implementation details of such things. I just know I'd like to make a flight simulator.

stuck elbow
#

and you could rotate it too

tiny peak
#

oh, that looks very Outrun

stuck elbow
#

there are some arcade flight simulators that used this

tiny peak
#

I'm thinking FPV racing course kinda thing

stuck elbow
#

lotus esprint ;-)

#

but it's all flat

#

you can have other airplanes and vehicles, and maybe trees or buildings as sprites, but no things like skyscapers or mountains

#

here's a hang glider simulator for snes using mode 7

tiny peak
#

oh... cool

stuck elbow
#

note how they curved the horizon of the death star

tiny peak
#

hmm... interesting. One thing about old game console video modes, if I understand the history correctly, is that a lot of that stuff used hardware acceleration. So, on a board without such accelerator chips, I'm not sure there would be much benefit over just using a software renderer in the style of TinyGL or Pico3D.

#

I've been thinking in the direction of: What if Love2d, but with OpenGL 1.1-ish level graphics implemented with a software renderer, and maybe in Python?

stuck elbow
#

it's much cheaper to display a single rotated and scaled texture, than to render hundreds of textured triangles with occlusion

tiny peak
#

interesting. In any case, I'd like to figure out something that would let me do 3D graphics that look like old Bruce Artwick games.

tiny peak
#

maybe a generation or two ahead of that if possible, but yeah. terrain and obstacles with either wireframe or shaded triangle stuff. possibly textures, but I care less about those.

stuck elbow
#

so those were done with a framebuffer and a Breshenham line drawing algorithm, and some basic projection math, later maybe some occlusion stuff

#

it was done purely in software on early pcs, amigas, atari st, etc.

tiny peak
#

I've toyed with the idea of trying to implement something from scratch according to the principles described in Artwick's "Applied Concepts in Microcomputer Graphics" book.

#

Trouble with that approach is it would be pretty unfamiliar to folks who are used to modern stuff. That's why I've also been wondering if I could maybe port a scaled down version of Love2D to Fruit Jam if I used a software renderer. Might be easier for folks to understand. Dunno.

stuck elbow
#

there is lua for the pico

tiny peak
stuck elbow
#

yes

tiny peak
#

oh, sorry, crossed posts there

#

yeah. that is interesting

stuck elbow
#

you can easily do love2d-level stuff with displayio already, you just need a python library that would implement the familiar functions

tiny peak
#

yeah. To me, for 2D stuff at least, it seems like the first choice path ought to be adding a module to CircuitPython, or modifying an existing module. The trick would be to come up with an API and implementation that works for action games where the whole frame gets re-rendered at a reasonably high frame rate.

stuck elbow
tiny peak
#

displayio is slow

#

particularly if you are also doing USB gamepad or keyboard input

stuck elbow
#

displayio is not slow, the displays you are using are slow

#

you have to push all those pixels over a single wire

#

a rewrite won't help with that

tiny peak
#

I think we're in danger of wandering off topic for this channel. I don't want to hassle the other folks in this channel with arguments. I'm gonna peace out for now. Maybe we can discuss more later.

stuck elbow
#

this channel is for circuitpython development, so it's on topic here, we can create a thread if you worry about others

slender iron
#

my thinking for displayio is to have a second implementation of it based on LVGL for higher end (aka not RAM limited) MCUs. LVGL already has a way to accelerate 2d stuff with MCU accelerators and we could expand that as desired

#

displayio performance as it is scales with the number of pixels that need to change. a pico 8 celeste style game with limited motion should be plenty fast. a scroller like mario will be tougher because each pixel needs to change. I always aspired to using the scroll ability of SPI display but it is often in the wrong direction

slender iron
vernal sage
#

Whats a reasonable amount of time for a board to start? I'm sure there is a range but 14 seconds does seem kind of rough. I suppose this could in #help-with-circuitpython but this is more an issue with changing from flash storage to ram so wifi/bluetooth are initialized at boot every cold cycle

code.py output:
0;🐍10.0.0.114 | BLE:Off | code.py | 5.0.0-beta.0-4141-g0613f28042-dirty
 ==========  TIME  ==========
22:23:38 - 23/9/2025
==========  DONE  ==========

0;🐍10.0.0.114 | BLE:Off | Done | 5.0.0-beta.0-4141-g0613f28042-dirty
Code done running.

Press any key to enter the REPL. Use CTRL-D to reload.

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
0;🐍10.0.0.114 | BLE:Off | code.py | 5.0.0-beta.0-4141-g0613f28042-dirty
 ==========  TIME  ==========
22:23:52 - 23/9/2025
==========  DONE  ==========
#

Also that reliability with the C5 was just bt trying to read nvs before it was initialized, so it would core dump, warm cycle before flash was reset and then would start up into safe mode. Switching to no NVS storage seems to have things working pretty well

slender iron
#

14 seconds with wifi starting isn't super crazy to me. It does at least one scan to find the channel to connect to

#

it should be two seconds or so without wifi

#

one second for safe mode blinks and one for bluetooth blinks

vernal sage
#

Ah okay, those blinks seem to line up with what I'm seeing

tiny peak
tiny peak
#

From a quick look at the LVGL and ARM Developer docs, I'm wondering if Adafruit sells any boards besides possibly the Metro M7 and Teensy 4.x that would have the right instruction set features to benefit from LVGL's 2D acceleration stuff.

tulip sleet
tiny peak
#

as far as I can tell, M33 doesn't do the Helium vector instruction stuff

#

it's not clear to me if M33 has any lesser instruction set features that can be used by LVGL for acceleration

#

At first glance, my impression is that the stuff mentioned on the LVGL 2D acceleration docs page doesn't seem like it would apply to the RP2350. Might be wrong about that though. IDK.

tulip sleet
tiny peak
# slender iron likely that'd need to be based on some 3d engine for microcontrollers

From reading what people have to say here, on reddit, HN, and so on, I get the impression that not a lot of people do 3D stuff in desktop python, and it's quite rare on small microcontrollers. Like, 3d game engine for microcontrollers may not be a thing. (obligatory mentions: yes PyGame, Panda3d, Ursina, Pico3D do exist, but they don't seem very popular).

#

My point is that it doesn't seem like there is an existing game engine or framework for Python that people consider to be in the same league as other choices like Love2D, Defold, Pico-8, Godot, Unity or Unreal, etc. From what I read about PyGame, its API apparently lacks important features that are needed for many types of 2D games.

stuck elbow
#

I wrote a bunch of games, both in love2d and in pygame, and I never noticed pygame missing anything

#

but it's a library not a framework

tiny peak
#

one of the specific complaints I saw about pygame was that if you wanted to do a scroller with camera tracking, you had to implement all the coordinate translations on your own.

#

and people also mentioned they thought the API was generally pretty low level so you ended up having to build a lot of stuff on your own (things people missed having from engines that included more stuff by default)

#

haven't tried it myself, so I don't have much context to weigh those claims

#

The overall impression I got was, if we want to find good APIs to emulate -- stuff that lots of people like for building games of different styles -- it might be worth looking at how some of the popular Lua-based frameworks and engines work.

#

My tentative plan for the moment is to try some tutorials and experiments with Love2D, PyGame, and maybe some other stuff, then revisit all this later when I have more experience.

stuck elbow
#

then again, plain love2d doesn't have much implemented either, I remember I had to do my own sprites, which pygame already had

#

my impression is that most of the lua and javascript game frameworks are based on this idea that you get a clean canvas, and draw all the game graphics on it from scratch every frame, which really doesn't work that well with non-accelerated platforms

#

displayio was based on the gameboy, nes, snes etc. platforms, where you have a number of tile grids and sprites, and where you only update the parts that have changed from the last frame

full plume
#

my impression is that most of the lua

manic glacierBOT
#

Thanks for more research on the NeoPixel.

The creation ID used here is not in https://github.com/creationid/creators/blob/main/creations/espressif.md#0x00c3_xxxx---c3-dev-boards . Could you open an PR there? Also I would say use a creation ID that is consecutive with other C3 boards.

I tried to copy the model based on
0x0032_A000 ESP32-LyraT
Since this board seems to be the esp32-c3 equivalent of that one (though other than supporting audio, they are pretty different).

slender iron
manic glacierBOT
#

This PR is a proof of concept, but need some discussion on how to handle this "properly".

The esp32-c3-lyra board has no DAC, but the i2s data pin is connected directly to an audio amplifier.
Using the audiobusio library, I was able to play music on this board, but it sounded terrible.

Comparing the i2s implementation in CircuitPython vs the working sample in the esp-adf dev kit, it turns out that the dev kit isn't using true i2s, but the i2s hardware has a PDM output mode. This p...

orchid basinBOT
manic glacierBOT
fleet hollow
stuck elbow
fleet hollow
stuck elbow
stuck elbow
#

you would have to pretty much rewrite it for anything else

full plume
#

@slender iron just a heads up - not quite PR ready yet but that's the plan.... I've added some extra tracking inside gc.c / gc.h and calls to get at the extra info in modgc.c. It keeps a running total of how much is allocated at any given time, so you can call gc.mem_alloc_live() and get the result effectively instantly (especially compared to gc.mem_alloc(). I also added gc.mem_quick_free_live() and gc.mem_quick_used_live() (apologies for lazy naming - that will be fixed) which "walk the heap" like gc.mem_free() / gc.mem_alloc() but run around 300% faster. Source is at https://github.com/jbrelwof/circuitpython/tree/gc_extensions if you're curious.

#

My use case is a fairly complex profiling harness which tracks elapsed time and GC allocation. Since there can be dozens of before/after samples per single "main loop" iteration, the overhead for gc.mem_alloc() rendered the system nearly unusable when doing a "full depth" profile with memory tracking enabled. Using gc.mem_alloc_live() drops the overhead to around 20% compared to profiling completely disabled - whereas the overhead was more like 95%+ with gc.mem_alloc().

manic glacierBOT
#

Build Request

I'm working on a project that requires LoRa, and the Seeed Studio Xiao ESP32-S3 with the SX1262 Hat fits my use case perfectly.

Unfortunately, there isn't a specific firmware build/port for it, only the same board but with the Sense/Camera hat, and I don't know enough about the build process of CircuitPython to make a new port for this particular board+hat combo.

**Would someone with experience updati...

slender iron
#

memorymonitor is an example

tulip sleet
#

@slender iron I am going down a rathole of automount issues. in main.c we have this code, which is about 6 years old:

static void stop_mp(void) {
    #if MICROPY_VFS
    mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table);

    // Unmount all heap allocated vfs mounts.
    while (gc_nbytes(vfs) > 0) {
        vfs = vfs->next;
    }
    MP_STATE_VM(vfs_mount_table) = vfs;
    // The last vfs is CIRCUITPY and the root directory.
    while (vfs->next != NULL) {
        vfs = vfs->next;
    }
    MP_STATE_VM(vfs_cur) = vfs;
    #endif
#

it looks like it is assuming that there are no non-gc-able vfs mounts between gc-able vfs mounts in the linked list. I think that assumption could be incorrect, what with CPSAVES and automounting. Maybe it still works by accident.

#

also I see a a number of places callling gc_nbytes() to see if something is gc-able, but we now have bool gc_ptr_on_heap(), which is more efficient, and should work just fine, I think.

#

this is not urgent. I can talk to you tomorrow about this, just giving advance warning

#

there is also a catch-22 on auto-reload if you write to a code.py-mounted filesystem. When you write to that filesystem, it will trigger an autoreload, stopping the VM, and the filesystem will get unmounted, because it is gc-able. So writes to user-mounted filesystems should not trigger auto-reload ever.

#

(I started writing a lun_is_automounted() routine and then stumbled into the rathole above.

manic glacierBOT
#

Builds for 3rd-party boards are usually done by the manufacturer or a community member, so it depends on their priorities. I tend to agree with you that a basic build for the Pro would be useful, and perhaps even handle all of the hats in Python libraries.

Also note that the SX1262, afaik, is not yet supported in CircuitPython. If it was, it could be used with the https://github.com/adafruit/Adafruit_CircuitPython_RFM9x or https://github.com/adafruit/Adafruit_CircuitPython_RFM libraries. La...

manic glacierBOT
#

Builds for 3rd-party boards are usually done by the manufacturer or a community member, so it depends on their priorities. I tend to agree with you that a basic build for the Pro would be useful, and perhaps even handle all of the hats in Python libraries.

My main ask is directed to the community members. It's kind of a shot in the dark, but I needed some help so I'm aiming for a kind soul out there. 🙏

Also note that the SX1262, afaik, is not yet supported in CircuitPython.

That's fin...

manic glacierBOT
#

Is 8MB vs. 16 MB flash the only difference between the vanilla Xiao ESP32-S3 to the Xiao ESP32-S3 Plus? It would be relatively easy given one to do the other. I'm sure you can get community help along the way. You probably want to start with the learn guide for building CircuitPython. Then probably use the Sense as a base, and strip away the camera (and any other differences). It may also help to review the [PR](https://github.com/adafruit/...

manic glacierBOT
manic glacierBOT
#

Keep the issue open, you may find a kindred spirit who also wants the base board or the Plus.

The way I read the schematic, the LoRa pins on the B2B connector are duplicates of the main header pins. LoRa uses GPIO 1-5 and also the SPI pins GPIO 7-9, leaving 3 GPIO pins unused on the main headers. All of these [pins](https://github.com/adafruit/circuitpython/blob/main/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins...

#

Keep the issue open, you may find a kindred spirit who also wants the R8 (flash only), N8R8, or the N8R16 base board(s).

The way I read the schematic, the LoRa pins on the B2B connector are duplicates of the main header pins. LoRa uses GPIO 1-5 and also the SPI pins GPIO 7-9, leaving 3 GPIO pins unused on the main headers. All of these [pins](https://github.com/adafruit/circuitpython/blob/main/ports/espressif/board...

manic glacierBOT
#

I would if I could. It's in a private repo, and it's got a lot of layers.

The hard part is that the module I have for the SX1262 I got from someone else on GitHub, and it requires passing in the pins, not the SPI interface. I'm not sure why that is, but maybe I can refactor it to take a new parameter for an SPI class instead of each individual pin.

manic glacierBOT
manic glacierBOT
#

I don't know which Xiao board you actually have in hand, but there are two QT Py ESP32-S3:

• 8 MB flash, no PSRAM (this would match the Xiao with 8 MB flash, no PSRAM - Or, * MB flash and 8 MB PSRAM but the PSRAM wouldn't get used)

• 4 MB Flash + 2 MB PSRAM (I don't think this could be used with any of the Xiao)

Other alternatives are boards that match the flash and RAM config of the board you have, and have the pins you need exposed. Some possibilities are:
https://circuitpython.org/boar...

manic glacierBOT
#

Another alternative that comes to mind is the audiopwmio API, which is a "natural" place for beginners to go, since it's used in a bunch of examples. The API would look the same, except that the name is wrong by one letter. Perhaps adding a flag or PWM vs PDM, or an audiopwmio.PDMAudioOut API.

This is my preferred approach. The docs already note that the platform gets to decide the frequency of the PWM pulses so we can make it a little less specific to encompass PDM.

lone axle
#

I still have to do the I2C implementation and some more cleanup and testing. But open to get feedback when you have time to look.

manic glacierBOT
#

Another alternative that comes to mind is the audiopwmio API, which is a "natural" place for beginners to go, since it's used in a bunch of examples. The API would look the same, except that the name is wrong by one letter. Perhaps adding a flag or PWM vs PDM, or an audiopwmio.PDMAudioOut API.

This is my preferred approach. The docs already note that the platform gets to decide the frequency of the PWM pulses so we can make it a little less specific to encompass PDM.

So have...

manic glacierBOT
manic glacierBOT
#
  • Fixes #10632.
  • Does not deal with #10510, which touches some of the same code, but I'll put that in a separate PR after some further consultation.

SD card USB presentation

  • Add new .h-only compile option CIRCUITPY_SDCARD_USB, which will enable/disable presenting SD card as a USB MSC LUN.
  • Enable on all ports except atmel-samd due to some bug that causes USB disconnection. I tested most of the other ports, and they don't have this problem. I'll open a separate issue ...
tulip sleet
manic glacierBOT
#

So have some sort of #ifdef or variable in board.c to define that PWMAudioOut uses PDM on this board?

Nope, just implement audiopwmio for Espressif using PDM for everyone.

Also I'm just ramping up on this. I couldn't find an audiopwmio in common-hal, should I be looking to implement this in ports/espressif/common-hal/pwmio?

Yup! Add ports/espressif/common-hal/audiopwmio with the implementation and enable it by setting CIRCUITPY_AUDIOPWMIO=1. I'd suggest using starting w...

manic glacierBOT
manic glacierBOT
#

I have this kind of problems in various projects. Since I often use external circuitry to shut down instead of using alarm.exit_and_deep_sleep_until_alarms(), it is important to wait for the update to finish.

I usually loop on display.busy, but it turns out that there are displays where you cannot trust the busy-pin.

Fixing this in the alarm-module wont help in my use-case. I would prefer to have an option that makes display.refresh() synchronous.

vernal sage
#

What was the reason neopixel_write uses rmt instead of ledc for espressif? Seems like ledc has the wider class of support so you could use it on the C61 and C2

devout jolt
manic glacierBOT
#

@tannewt thanks for the input. I'm not likely going to get to this next week, so it'll be a little while.
I'm not sure if there's any chance anyone else will take a look at this... if so you might want to leave this PR open as a reference. However, since the actual fix will look pretty different in terms of the affected files, you can close this and I'll submit another PR when I get around to this.

full plume
# slender iron `memorymonitor` is an example

Yeah, fixing the names and moving it the API wrapper to a separate module are part of getting it "PR ready". But it will still require changes in gc.h and gc.c, although those are all wrapped in #if CIRCUITPY_GC_TRACK_LIVE... so you can choose whether or not to add the tracking logic at compile/build time.

tulip sleet
#

@slender iron it turns out an ordinary file open() from CircuitPython don't use filesystem_lock() or blockdev_lock() at all. The open just checks filesystem_is_writable_by_python() ., which checks MP_BLOCKDEV_FLAG_USB_WRITABLE, which is only set/cleared by filesystem_set_writable_by_usb().

#

So the USB MSC side may do blockdev_lock(), but the CIrcuitPython side pays no attention to that. The filesystem_lock() and blockdev_lock() are used in the common workflow routines.

slender iron
slender iron
tulip sleet
#

i have somebody coming over briefly in the next 15-30 minutes, so short or could be after that.

slender iron
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

Hi, we need an allocated PID for this, ideally from WeAct itself (if it has a VID), or from https://github.com/raspberrypi/usb-pid. Failing that, it would be from https://pid.codes/ . USB_PID = 000F is the PID for the Pico 2. See https://learn.adafruit.com/how-to-add-a-new-board-to-circuitpython/customizing-the-board-files#usb-vid-and-pid-3137314, including the pointer to the FAQ for this.

manic glacierBOT
manic glacierBOT
#

The 0x000F PID is for the UF2 bootloader, but is not for when the board is running CircuitPython. You can't find the proper PID unless the manufacturer or someone else has registered a PID already. See https://learn.adafruit.com/how-to-add-a-new-board-to-circuitpython/frequently-asked-questions#faq-3130481.

I don't think WeAct has its own VID (vendor ID). They could ask Raspberry Pi for a PID (product ID) by going to https://github.com/raspberrypi/usb-pid. Or you or they could ask for on...

manic glacierBOT
manic glacierBOT
copper crescent
#

I assume the "org" side is what needs the fix (renaming the images/md etc)?

lone axle
orchid basinBOT
manic glacierBOT
manic glacierBOT
#
  • Fixes #10510

  • Ensure that a filesystem visible via USB is read-only to the host if it is read-write to CircuitPython and vice-versa.
  • Type-check storage.mount(filesystem=, ...) argument to ensure it is a VfsFat object.
    • Currently it only checks that it implements mount. But elsewhere in the code there are assumptions it is an fs_user_mount_t, which is a `VfsFat.
    • If/when we provide other filesystem types (as MicroPython does), we will relax this. I left the old val...
tulip sleet
#

@slender iron I have release notes for 10.0.0 rc.0, so I think I will just go ahead.

manic glacierBOT
#
[adafruit/circuitpython] New tag created: 10.0.0-rc.0
orchid basinBOT
orchid basinBOT
tulip sleet
full plume
slender iron
#

@tulip sleet I'm tempted to have you do 10.0 today. I'm out 10/8-10/15 so doing it now gives me time to help fix bugs. Otherwise we'd wait two weeks

tulip sleet
slender iron
#

I'm out Friday during the day as well

tulip sleet
#

so tonight if we don't hear anything bad. I want to xref the OPEN INSTALLER guide in the Factory Reset pages, but that should be quick

#

we are not going to get a bunch of rc.0 testers -- those people have already been testing all the betas, and the recent changes are simple or isolated.

slender iron
#

yup, agreed

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

Sorry for the late reply, and thank you for the feedback.
The reason I implemented a native PIO_SPI is as follows:

  1. Performance and Overhead
    While it’s possible to drive PIO purely from Python, the WIZnet chips require very frequent register accesses. In practice, the Python interpreter overhead accumulates and can noticeably reduce throughput and responsiveness. The native implementation removes this overhead and ensures more stable operation.

  2. High-Speed Transfer
    Communication ...

manic glacierBOT
manic glacierBOT
#

I've added a new board: M5Stack DinMeter

The compiled firmware was tested in the context of an ongoing project of mine and appears fully functional.

Explicitly tested hardware-features that work:

  • Display
  • Rotary & Button
  • Bluetooth LE
  • Grove Ports A & B (albeit only GPIO functionality was tested)
    I didn't test WIFI, Grove I2C and power-management - but as those aren't board specific features, I expect for them to work just as well.
#

As a side note: I didn't know whether a new board is considered as something that should be targeted for the current release-branch (10.0.0 as of just yesterday) or onto the main branch. Maybe this could be added as an additional guidance to https://learn.adafruit.com/how-to-add-a-new-board-to-circuitpython/submit-a-pull-request

I've added an alert to that page about branches and a note on the getting setup page. Right now main is essentially 10.0.x so this is to the best branch. We ...

manic glacierBOT
#
  1. In practice, the Python interpreter overhead accumulates and can noticeably reduce throughput and responsiveness. The native implementation removes this overhead and ensures more stable operation.

Did you try the Python-only version first? I'm worried this is a lot of specific code for us to maintain. Having it in a library of yours using rp2pio directly means you can maintain it easier.

manic glacierBOT
#

CircuitPython version and board name

main branch

Code/REPL

No code

Behavior

(circuitpython) outside/circuitpython - (main) > gmake -C mpy-cross

gmake: Entering directory '/Users/bwhitman/outside/circuitpython/mpy-cross'
- Verbosity options: any combination of "steps commands rules", as `make V=...` or env var BUILD_VERBOSE
In file included from ../py/emitnx64.c:16:
../py/emitnative.c:2423:5: error: variable length array folded to constant arra...
manic glacierBOT
#

14.3.rel1

outside/circuitpython - (main) > which arm-none-eabi-gcc
/Users/bwhitman/Downloads/arm-gnu-toolchain-14.3.rel1-darwin-arm64-arm-none-eabi/bin/arm-none-eabi-gcc
outside/circuitpython - (main) > gmake -C mpy-cross     
gmake: Entering directory '/Users/bwhitman/outside/circuitpython/mpy-cross'
- Verbosity options: any combination of "steps commands rules", as `make V=...` or env var BUILD_VERBOSE
In file included from ../py/emitnx64.c:16:
../py/emitnative.c:2423:5: error: varia...
autumn jasper
#

hey guys. I noticed that with CircuitPython it is not possible to use the usb host functionality with the Raspberry Pi Pico's built in micro usb port. This seems to be possible otherwise: https://github.com/rppicomidi/midi2usbhost

I'd like to maybe add this functionality to CP. Any idea where I should start looking?

tulip sleet
# autumn jasper hey guys. I noticed that with CircuitPython it is not possible to use the usb ho...

We use the PIO USB Host if we want host capability. Otherwise you lose a lot of ease of use in the development cycle. For instance, the REPL would need to be done over serial, CIRCUITPY would not be expose,d etc. Do you have a particular use case in mind that would want to use the built-in host capability rather than something like https://www.adafruit.com/product/5723 ?

#

The RP2350 fixes all the known errata for native USB host on RP2040.

autumn jasper
#

I'll look into PIO USB Host.

tulip sleet
#

CircuitPython 10 (and earlier) has usb_host support on Pico 2 (and Pico)

autumn jasper
#

Where you would use something like an OTG cable and power the Pico externally

#

Like the github repo I linked earlier

tulip sleet
#

that's right, that usb_host support is PIO. We have a lot of USB breakouts. Do you want micro-B or would you prefer a USB-A

autumn jasper
#

Ok. Actually I needed to use the built in micro usb because I soldered a design of mine to a protoboard with a JST connector hooked up to VBUS so I could power the Pico 2 externally and then use an OTG cable

#

so to use a USB A port for usb host functionality I would have to desolder some of that ahaha

#

I'll probably solder a newer version accounting for that

tulip sleet
#

well ... you could do hours of software dev or alter the design 🙂

autumn jasper
#

I just assumed that CircuitPython would be able to achieve what that github repo did

autumn jasper
#

so... to clarify: with PIO usb host I could potentially use 2 GPIO pins for Data + and Data -?

tulip sleet
#

you have to use 2 PIO pins for data +/-

#

two consecutive pins are required

autumn jasper
#

thanks for the help! I'll probably just add another JST connector for Data + and Data - and cook up my own USB A port

manic glacierBOT
tiny peak
#

re the RP2040 USB host stuff using the Pico's microUSB port instead of PIO... IIRC, somebody around here (can't remember who... perhaps RetiredWizard?) was recently looking at how to do something similar to add support for the Olimex RP2350pc. If I'm not totally misremembering, I think that board has its USB A jacks wired up to use the onboard USB peripheral instead of PIO. There may be some github issue and pull request discussion about it. My impression from what I remember of the discussion was that it wasn't an easy thing to get working with CircuitPython? Might be wrong about that.

wraith crow
# tiny peak re the RP2040 USB host stuff using the Pico's microUSB port instead of PIO... II...

@tiny peak @autumn jasper I was working on getting the microUSB working with the native tinyUSB stack. I have a CircuitPython PR ready that was needed to allow non-PIO USB Host to work when USB device was disabled but I also ran into an issue in tinyUSB that was resulting in a safe mode crash. I was able to work around the safe mode crash by commenting out a section of the tinyUSB code. I added the information to an open tinyUSB PR but I believe the fix I had could create problems when USB Host was used for something other than a keyboard or mouse. I think it may have simply ignored some data if it was received out of order or before earlier packets were processed (I didn't get deep enough to really understand what tinyUSB was doing and I don't know the USB protocol). I'll probably go ahead and submit the CircuitPython PR just so folks can look it over but I'm not sure it's going to make sense unless someone capable of digging into the tinyUSB problem has the time and inclination to do so.

manic glacierBOT
#

This PR adds the ability to use both CIRCUITPY_USB_DEVICE=0 and CIRCUITPY_USB_HOST=1 on raspberrypi rp23xx boards to indicate that the native usb pins DP/DM should be configured in HOST mode using the TinyUSB stack.

TinyUSB does not properly handle non-pio RP2350 host mode though so this PR doesn't currently enable the desired functionality. There is an un-merged TinyUSB PR (https://github.com/hathach/tinyusb/pull/2474) which may be applicable to the problem but doesn't solve the problem ...

autumn jasper
#

And after altering the board files for the Pico 2? Or is that not needed here?

autumn jasper
#

the flag "CIRCUITPY_USB_HOST=1" should be added, correct?

wraith crow
# autumn jasper the flag "CIRCUITPY_USB_HOST=1" should be added, correct?

Yes and CIRCUITPY_USB_DEVICE=0 and CIRCUITPY_USB_VIDEO=0, you'll also need to add CIRCUITPY_CREATOR_ID and CIRCUITPY_CREATION_ID, for testing you can just use the USB_VID/USB_PID for those values but eventually you would need to create proper values.

I don't think the tinyUSB stack will handle USB_MIDI but you can give it a try. Also, with this build attempting mouse input the way it's currently being done with many short timeout calls is causing a tinyUSB panic. Keyboard input seems to work fine. I do have a hack to Device.c that basically turns off the timeout on usb reads and avoids the panic, however then mouse reads become blocking.

#

Overnight, it occurred to me that keyboard input must be checking if any USB input is ready before attempting to read the USB data and if I could modify the timeout function on the generic USB read to do the same thing before starting a USB xfer then tinyUSB would not have to attempt and abort so many transfers which would probably avoid the panics I'm seeing on mouse reads. When I get going this morning, I'll dig in that direction 😁 that was a dead end....

wraith crow
#

Using this technique you won't get a CIRCUITPY drive or be able to use the native USB port (microUSB) as a REPL terminal. To interact with the device, you'll need to define UART pins and connect a terminal or USB FTDI cable. board.c should construct your host port in board_init and CIRCUITPY_CONSOLE_UART_RX/TX sets up the console

manic glacierBOT
crystal fractal
#

Trying to build CP on macOS 15.7 on Intel, getting the following error, looking for advice:

$ gmake -C mpy-cross
gmake: Entering directory '/[redacted]/circuitpython/mpy-cross'
- Verbosity options: any combination of "steps commands rules", as `make V=...` or env var BUILD_VERBOSE
GEN build/genhdr/mpversion.h
QSTR updated
GEN build/genhdr/qstrdefs.generated.h
Module registrations updated
GEN build/genhdr/moduledefs.h
Root pointer registrations updated
GEN build/genhdr/root_pointers.h
In file included from ../py/emitnx64.c:16:
../py/emitnative.c:2423:5: error: variable length array folded to constant array as an extension [-Werror,-Wgnu-folding-constant]
 2423 |     MP_STATIC_ASSERT(MP_OBJ_STOP_ITERATION == 0);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../py/misc.h:57:51: note: expanded from macro 'MP_STATIC_ASSERT'
   57 | #define MP_STATIC_ASSERT(cond) ((void)sizeof(char[1 - 2 * !(cond)]))
      |                                                   ^~~~~~~~~~~~~~~
1 error generated.
-e See https://learn.adafruit.com/building-circuitpython; Adafruit Discord #circuitpython-dev
gmake: *** [../py/mkrules.mk:104: build/py/emitnx64.o] Error 1
gmake: Leaving directory '/[redacted]/circuitpython/mpy-cross'
$ git rev-parse --short HEAD           
a54ddb329b
$ gmake --version
GNU Make 4.4.1
Built for x86_64-apple-darwin24.0.0
manic glacierBOT
manic glacierBOT
lone axle
#

<@&356864093652516868> Reminder: The (Bi) Weekly meeting is scheduled to occur here on discord today at 2pm US Eastern / 11am US Pacific, just under 90 minutes from now. As always, notes and hug reports can be added to the shared doc https://docs.google.com/document/d/1Tbs6tWOH9oaIUS1076qzb8weuu53jphB2x7t-8VxvgQ/edit?usp=sharing and we look forward to hearing from everyone who can attend.

lone axle
#

<@&356864093652516868> Bi-Weekly meeting is getting started now.

manic glacierBOT
lone axle
#

Have a great week everyone 👋

tulip sleet
#

Thanks for hosting!

manic glacierBOT
lone axle
#

Here is the notes document for next Monday’s CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord. Add your hug reports and status updates to the document before the meeting. If you are unable to attend but would still like to contribute, feel free to add your notes and we’ll read them off during the meeting. Hope to see you there! <@&356864093652516868> https://docs.google.com/document/d/1LMG6qyV-DP5TUlEeVBjLp1mIY5y-KvM_xqybEOMvSCI/edit?usp=sharing

slender iron
#

@tulip sleet just updated my 5.5.1 branch and S3 is working for me. esp32 and c3 also worked the last time I tested. c6 it boot looping

#

gonna try and jam out an epaper driver for liz before I leave

slender iron
#

not sure exactly but I removed some debug prints I'd left in

#

from debugging the c6

#

they weren't committed so it makes sense that it worked for thach

manic glacierBOT
#

CircuitPython version and board name

### Description

I’m building a **custom nRF52840 board** (`BOARD=sensera2`) and want to **disable SPIM3** and reclaim the **8 KB** reserved “SPIM3_RAM” back into **APP_RAM**. I created a **board-local linker script** without `SPIM3_RAM` and pointed my board to it, but the final build **still shows** `SPIM3_RAM: 8 KB` and **APP_RAM stays at 192 KB**.

It looks like the build system may still be using the **template**/generated linker instead...
manic glacierBOT
#

cmake is not used for ports/nordic, so the board.cmake file is not going to do anything. Are you thinking of MicroPython or the zephyr port?

See references to SPIM#_BUFFER_RAM_SIZE in https://github.com/adafruit/circuitpython/blob/64b32f6e385361592025a1cd7be40121e556992f/ports/nordic/mpconfigport.h#L21-L38. It isn't conditionalized there, but you could conditionalize it. It feeds into boards/common.template.ld. You will also need to set #define NRFX_SPIM3_ENABLED 0 somewhere.

manic glacierBOT
#

@eightycc Thank you for your work on this!
I have a Pico Plus 2 purchased from before the release of the Pico Plus 2W. I've been watching this thread for a while hoping for support for the RM2 module over spice. I would love to see support for at least the pico plus 2 since it was practically made for it. I would be happy to volunteer to help if there is anything I could do to help this happen.
It works fine in Micropython, but I just enjoy using Circuitpython for most of my projects. I atte...