#circuitpython-dev

1 messages Β· Page 82 of 1

manic glacierBOT
#

Trying to make a custom build with the custom build action, I get a failure, with the following error:

Run make -j4 $FLAGS BOARD="$BOARD" DEBUG=$DEBUG TRANSLATION="$TRANSLATION"
  make -j4 $FLAGS BOARD="$BOARD" DEBUG=$DEBUG TRANSLATION="$TRANSLATION"
  shell: /usr/bin/bash -e {0}
  env:
    pythonLocation: /opt/hostedtoolcache/Python/3.13.2/x64
    PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.13.2/x64/lib/pkgconfig
    Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.13.2/x64
    Python2_...
brazen hatch
#

Yea the MAKE flag has 0% chance of working with ansi escapes and bytes.

#

I did spend half a day now to try making it work

#

Took 30 minutes to make custom header to include the code

#

Downside to my "encode it into what looks like malware" approach, is that it takes exorbitantly long for 350k characters to load into the stack, causing a cpu watchdog reset.

#

I think I should pivot to frozen module generation

#

I'll just design it so code.py is just import setup and the host application crafts a frozen module containing all the decompression and setup code.

#

Or an alternative would be to just have default code.py test if the setup module is available.

#

This would allow people to just include a frozen module named "setup" and be done with the build configuration, simplifying automation as well.

#

This would allow us to have ci like:
- Take this image file url.
- Extract into frozen/setup
- Enable setup for board
- Build

#

Actually this whole thing makes images pointless, just a zip

manic glacierBOT
#

Tinkering with it some more this morning, I'm not sure what input_pixel.tile_x and input_pixel.tile_y represent, they are perhaps influenced by scale. I tried passing in tile_width and tile_height and dividing but that led to the wrong tile_location result, printing out the values I realized they don't seem to be matching up with pixels how I thought when I wrote the above, they are larger than I they would be if they were what I understood them to be.

passing in tile_location is...

#

The custom build action is currently broken, see #10117
This is how you start it (to do in you fork) - but currently results in an error.

<img width="332" alt="Capture d’écran 2025-03-06 aΜ€ 12 55 29" src="https://github.com/user-attachments/assets/02ff608b-4fd1-4fd2-999a-555f177ba92c" />
<img width="348" alt="Capture d’écran 2025-03-06 aΜ€ 12 58 49" src="https://github.com/user-attachments/assets/5a3a40e2-0e50-4cc0-aa29-5eee11fe2281" />

If you understand github actions, you can try ...

manic glacierBOT
#

The latest commit contains a bunch of the requested changes, as well as fixing the functionality for more colors, it turned out that was not behaving correctly before.

This is the updated test script i've been using the test the color functionality:

import time
from displayio import Palette
from tilepalettemapper import TilePaletteMapper
import board
import terminalio
import displayio
import rainbowio


time.sleep(1)
p = Palette(258)
p[0] = 0x000000
p[1] = 0xffffff
for ...
slender iron
#

I think bootloader would be better since it doesn't require CP to start. It is nice that is universal though. Seems similar to circup

#

@lone axle any luck with the metro and absolute latest?

brazen hatch
#

If there is no vendor flashed setup code, nothing happens.
If there is, it'll take over, doing whatever it wants.

#

The thing I'm writing will check if .setup_complete exists and only run if not, checking usb mounting state and rebooting if needed.

slender iron
#

it will be constrained by flash

#

if you freeze the whole default file system

brazen hatch
#

zlib

#

Already did it with my whole project

#

no complains on esp

#

Besides, it's useful for more than just packing a whole fs.
You can use it as I said to stuff a download script.

slender iron
#

I don't want a default boot.py but vendors can do what they want on their boards

lone axle
# slender iron <@382939733107408897> any luck with the metro and absolute latest?

Keyboard input to REPL is working now (wasn't for me before). Still no luck with the generic PS3 or the cheap SNES controller using this script that I wrote for the rp2040 originally https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Feather_RP2040_USB_Host/CircuitPython_GamePad_ReadData/code.py

I do think the PS3 controller may be getting further than it did before. It has a blinking red light that seems to indicate an error state. On the old firmwares that just kept blinking forever, on the new one, if I boot the metro up with that PS3 controller plugged in it does settle in to it's normally functioning state of not blinking.

#

Both my current games use keyboard input though, so this gets me unblocked to run those on the metro. πŸŽ‰

slender iron
#

thach is going to do more debugging I think.

manic glacierBOT
lone axle
#

@slender iron for the 360x200 display size of PicoDVI what are the supported color depths? 8 and 16 bits same as 320x240? I'm going to update the docs to list that new mode and update to note that it's the default instead of 320x240.

manic glacierBOT
#

Here is the part to add back:

    - name: Board to port
      id: board-to-port
      run: |
        PORT=$(find ports/*/boards/ -type d -name ${{ inputs.board }} | sed 's/^ports\///g;s/\/boards.*//g')
        if [ -z $PORT ]; then (exit 1); else echo >> $GITHUB_OUTPUT "port=$PORT"; fi
      shell: bash

I would only use this for the build action. The rest doesn't need it. Also note that I removed this because it won't work for the zephyr port because it nests boards under an additio...

slender iron
#

On RP2350, output resolution is either 640x480 or 720x400. Monochrome framebuffers (color_depth=1 or 2) must be full resolution. 4-bit color must also be full resolution. 8-bit color can be quarter, half or full resolution. 16-bit color and 32-bit color must be quarter or half resolution due to internal RAM limitations.

jaunty juniper
#

@slender iron speaking of zephyr, is seems like build_board_info.py also errors due to the paths, it will have to be special cased there too.

❯ RELEASE_TAG=9.2.4 DEBUG=1 python build_board_info.py
Traceback (most recent call last):
  File "tools/build_board_info.py", line 287, in <module>
    generate_download_info()
  File "tools/build_board_info.py", line 256, in generate_download_info
    board_info = board_mapping[board_id]
                 ~~~~~~~~~~~~~^^^^^^^^^^
KeyError: 'nordic'

the code does this:

        board_path = os.path.join("../ports", port, "boards")
        for board_path in os.scandir(board_path):
lone axle
#

perfect, that's got all of the details, the environment docs can link over to there

manic glacierBOT
slender iron
#

(How did this not break 9.2.4's release?)

jaunty juniper
#

seems 9.2.4 was a few days before the zephyr PR was actually merged

manic glacierBOT
slender iron
manic glacierBOT
#

Description

I'm trying to use a USB keyboard with the Feather RP2040 with USB Type A in CircuitPython (version 9.2.4). However, when I plug in my keyboards, the Feather crashes and disconnects from the PC after about 15 seconds.

I tested using Adafruit’s USB Host device info example, and the behavior is consistent. **A wired USB mouse works fine and is detected correctly, but ...

slender iron
tulip sleet
#

@slender iron thanks. on a different topic, have you ever seen c6 or c3 builds where a build doesn't even come up? the bootloader just generates tons of "Invalid header: 0xffffff...". I am building NINA-FW just fine but it won't come up at all. Does CONFIG_BOOTLOADER_OFFSET_IN_FLASH value make any differene. Arduino IDE is fine and so is CircuitPython. I know the .bin is being loaded; I downloaded it and it's exactly what I expect.

#

partition table is not unusual

manic glacierBOT
#

I was able to reproduce this on the USB host feather wing but not on the RP2040 feather with a usb host breakout cable plugged in. The breakout cable's power pin was connected to the USB power pin on the feather header.

I suspect a power issue because the crash doesn't result in a safe mode. The device disappears and doesn't come back. I mean to check my Linux dmesg output but have run out of time. I'd also check the USB activity with an analyzer to see if anything happens before the c...

slender iron
#

did you try a full erase beforehand?

tulip sleet
#

I have turned on logging there, as an initial step. yep, did an erase

slender iron
#

want me to try and fix the issue neradoc found that may break the next release?

tulip sleet
#

for sure, my thing i think I will figure out eventually

slender iron
#

yup, I'd print the address it is reading

tulip sleet
#

i turned on verbose logging but it said the bootloader was too big πŸ™‚

slender iron
#

you could just add the print you need then

#

if logging is on at least

tulip sleet
#

thanks, I will do that:

ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x7 (TG0_WDT_HPSYS),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x400294a6
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
...
slender iron
#

that looks like the rom bootloader

#

not the second stage one

#

I bet you are flashing the second stage bootloader to the wrong place

tulip sleet
#

right, I thought maybe the second stage was either not getting called at all or was failing really early

#

its offset is 0x1000 instead of 0x000, compared with an arduino blink program. ESP32 uses 0x1000. I have not found good documentation on how this offset is communicated to the first stage bootloader

tulip sleet
#

ho ho, thanks!!

#

i googled that to no avail

#

that must be it

slender iron
#

yup. I think its the second stage that looks at the partition table

willow totem
tulip sleet
#

my issue is errors in the sdkconfig due to incomplete menuconfig-ing

#

my fault

willow totem
#

The dreaded menuconfig

#

On another note who here is aware of what the situation with the library bundles ruff rules is?
We don't seem to have sane defaults, although I have no idea or opinion on this really, just noticing that I've had to add F821 Undefined Name to detect what feels like a basic error.
Justin suggested bring to discord and in-the-weeds, but I wondered about scoping out the situation in advance (and kind of thought might get lost in discord).

tulip sleet
# willow totem On another note who here is aware of what the situation with the library bundles...

I don't know where the rules set came from. I think we could start over on that. micropython has been using ruff for a while, and we could look at theirs. I don't think there are a lot of people in the weekly meeting who have experience with this. We may well have a bad set of defaults. I'd go back to the initial commits and see if we can figure out where they came from. But I'd find out how to generate a sane set and then go from there. It's certainly not sacred.

slender iron
#

The kconfig files themselves can be helpful too

willow totem
tulip sleet
#

i have been reading those too. I think i just forgot to do idf.py set-target

willow totem
tulip sleet
#

I'm sure it was tweaked to fix our style but I don't know what the starting point was. @lone axle may remember where it came from first

lone axle
#

I don't know all of the specifics, some of them may not apply the same, or it may still be nice to add others if they can be helpful. Beyond trying to match what we had I dont recall much other discussion around it.

willow totem
lone axle
#

I'm not sure about that.

willow totem
#

Cool, no worries. Makes my sweeping changes less of a concern 😁

lone axle
#

I do believe we started ruff in libraries before micropython started using. Matching them now that they've begun too does seem like a reasonable approach to me. Definitely worth some discussion in the weeds.

tulip sleet
#

do we have to do an all-library set of PR's each time we change the rules?

willow totem
#

That also concerns me yeah, but adabot can probably do it in one foul swoop

tulip sleet
#

I am not sure MicroPython is a good starting point -- they are very casual about some things we care about

willow totem
#

good to know

tulip sleet
#

can we point to a default set of rules and have modifications for each library?

lone axle
#

Hmm, it would be nice to centralize it somehow, but still be tweakable for each library.

#

Its probably possible somehow, but I'm not sure the best way to do it.

#

fetch ruff.toml from some central repo, and then merge it with a local one in the working repo?

tulip sleet
#

Definitely, which we have done for other common things. I can't remember what is common right now.

willow totem
tulip sleet
#

I thought it was stuff in circuitpython-build-tools? It's something that gets fetched in the CI, or maybe in pre-commit? pre-commit might get in the way

jaunty juniper
#

can it be defined in .pre-commit-config.yaml ?

lone axle
#

github actions are centralized like that. But they allow us to "point" to the central place within their own config file syntax. I'm not sure whether ruff has a similar ability to point to another place.

willow totem
lone axle
#

AFAIK each repo's pre-commit is independent and doesn't have a central location that updates it.

tulip sleet
#

--config <CONFIG_OPTION> Either a path to a TOML configuration file (pyproject.tomlorruff.toml), or a TOML <KEY> =
<VALUE>pair (such as you might find in aruff.tomlconfiguration file) overriding a specific configuration option. Overrides of individual settings using this option always take precedence over all configuration files, including configuration files that were also specified using--config

lone axle
#

cookiecutter is a central location they get created from, but nothing automatic keeps pre-commit in sync AFAIK.

tulip sleet
#

but could there be a pre-commit action that fetches the default settings from somewhere and then merges them with local? It doesn't look there can be a cascade of .toml files, though

lone axle
#

if it will let us specify two config files that would make it fairly easy

willow totem
#

cascading works, just a bit below config discovery it talks about extend for pyproject.toml or ruff.toml to parent folder as example

#

Maybe only two levels, but ci action has level one and project level two

#

cookie cutter just sets up action and pyproject/ruff.toml with empty ruff section

tulip sleet
#

Unlike ESLint, Ruff does not merge settings across configuration files; instead, the "closest" configuration file is used, and any parent configuration files are ignored. In lieu of this implicit cascade, Ruff supports an extend field, which allows you to inherit the settings from another config file, like so:

willow totem
#

yeah inherit from another. Needs testing, but sounds like a solution

tulip sleet
#

looking at the same page as you πŸ™‚

jaunty juniper
#

note that it has to work when running pre-commit run from a local cloned repo, not just in a CI environment, otherwise it's gonna be a world of bad surprises with every PR

tulip sleet
#

so the q is does pre-commit have any mechanisms for fetching files? Maybe you can specify a custom action that will do that.

willow totem
#

So the ci calls precommit, which uses the libraries local yaml as config. All libraries will need an initial tweak to that yaml, and the ruff/pyproject.toml, and the actions should be ok.
Maybe a cookiecutter update as it were.
The yaml contains the --fix option for ruff so we can add the --config there, alternatively we ask the projects config to extend from a central one, so if its offline the project config still works but not as well

tulip sleet
#

I think the pre-commit person hates that kind of thing, because it introduces a dynamic dependency in a repo

manic glacierBOT
willow totem
#

I can't help but admit I don't run pre-commit, so that needs to work locally first I guess

tulip sleet
#

it is Good Thing

#

saves a lot of CI round trips

willow totem
#

it's a good thing to run for sure, it just hates 66% of my computers

tulip sleet
#

macOS? sorry

willow totem
#

windows, probably broken python setups from yesteryear. I should try installing it again on the refreshed one

manic glacierBOT
#

Alias boards get double the versions, because they are already in board_mapping.
So you don't need the inner loop on alias:

    for board_id, board_info in board_mapping.items():
        if board_id not in current_info:
            changes["new_boards"].append(board_id)
            current_info[board_id] = {"downloads": 0, "versions": []}
        new_version = {
            "stable": new_stable,
            "version": new_tag,
            "languages": languages,
           ...
short tendon
#

@lone axle have time to release MiniMQTT today? Want to see if I got ALL the secrets

short tendon
#

Thanks!

#

And secrets are gone from library code! And aio keys are all updated to ADAFRUIT_AIO_USERNAME and ADAFRUIT_AIO_KEY

#

There are 176 files in the learn guide that from secrets import secrets or import secrets

#

Not sure how you would like to tackle those. I can update all the code, but not sure about the learn guides themselves...

lone axle
#

@short tendon Thanks for all of the effort that you've put into it! For learn guide code you can submit a PR. If you have time and are so inclined you can search for the learn guide associated with the code as you change it and see if there are any instances outside of the main embeded code file that contain references to secrets.py, if so add a link to the relevant pages to a comment in the PR like: https://github.com/adafruit/Adafruit_Learning_System_Guides/pull/2755#issuecomment-2026325982

If you don't have the time, or would rather not search through the learn guide pages you can just submit the PR with code changes and someone else will go through them.

willow totem
#

Not this week probably, but I can smash some out, or do the matching guide pages

willow totem
#

nevermind that pre-commit additional_dependencies talk, it tried to pip install my test file 🀦 Easier to use some python fetch script instead, but yuk

short tendon
#

And it looks like there aren't any linting rules in the repo?

lone axle
short tendon
#

Sounds good

lone axle
#

The linting is far less strict, but I do think there is some

#

although I'm not sure if the actions enforce it

short tendon
#

I can add some basic linting and not commit it to make sure I at least have imports and declared vars

manic glacierBOT
short tendon
#

What about 1 PR vs many?

lone axle
# short tendon What about 1 PR vs many?

for big sweeps like this in the learn repo I find it easiest to work through them as one big one, or perhaps a few PRs split into chunks if you pick up / put down the work on it.

#

both as reviewer and contributor personally.

short tendon
#

Sounds good. I'll see what I can do in a sitting and figure it out from there. In the end breaking it up won't be hard after the fact

#

Final question (and not sure if we need multiple opinions). In the examples I did:

from os import getenv

As it seemed most common (from a quick search) and Dan didn't have any issues in initial reviews.

Are we good using that in all the updates?

short tendon
#

Also @lone axle do you want any help with the ruff migration?

lone axle
# short tendon Also <@382939733107408897> do you want any help with the ruff migration?

I wouldn't turn down help. I basically just do the switchover for any libraries that I am working in for other reasons if I am not in a hurry. I would say though my preference is to keep them all on the same version of ruff, I noticed the versions was bumped on miniMQTT.

Keeping them the same accross libraries is ideal in my mind so that the rules for all libraries are the same, and because the adabot patching tool is less effective when the files it's patching contain differences. So if we want to update them all at once with a patch for instance having a smattering of different versions in different libraries makes that more difficult.

short tendon
#

Yeah, that's why I was asking. Cause if we get them all done, then we can globally make changes.

#

Do you know roughly what percentage of libraries have been updated?

lone axle
#

I do not really. my guess is that there are "a few dozen" or so completed, but it is definitely just a guess.

#

you did the first handful, and I've done a few chunks with other changes. I think a few others have been swapped in PRs by other community members.

short tendon
#

Gotcha. So still most need to be done. After I finish with the learn guide, I can start going after this. How many PRs in a pass feels good to you? For secrets I was doing 4-6

lone axle
#

That sounds fine to me, but I'm good with whatever rate you want to go at really. I will try to stay caught up on reviews, if I lag behind and you feel like slowing down you can, though I also don't see it as terrible if they stack to some degree as long as it's not getting out of hand.

#

If any do lag, and require changes I can commit them instead of having you circle back if you've moved on.

short tendon
#

Sounds good. I'm not a fan of PRs hanging out too long (mostly because of conflicts from other merges), so will keep an eye on open ones, and if it seems like it's a lot will check in with you.

willow totem
willow totem
short tendon
#

😦

#

@lone axle what do you think we should do here where it just looks for the existence to raise (since the MagTag library would have grabbed them from secrets, now does from settings)

try:
    from secrets import secrets
except ImportError:
    print(
        """WiFi settings are kept in secrets.py, please add them there!
the secrets dictionary must contain 'ssid' and 'password' at a minimum"""
    )
    raise
#

Do we check that getenv("ssid") is not None and raise?

lone axle
short tendon
#

so:

if getenv("ssid") is None:
    raise Exception(
        "WiFi settings are kept in settings.toml, please add them there."
        "the settings file must contain 'CIRCUITPY_WIFI_SSID' and "
        "'CIRCUITPY_WIFI_PASSWORD' at a minimum"
    )
short tendon
short tendon
lone axle
short tendon
#

Bad copy/paste edit of the original. Fixed

lone axle
short tendon
#

so, there's two types. The ones that import secrets, just to raise an error (the ones using portalbase) and the ones that actually use secrets. I can easily add that exception for all of them and it will be similar

short tendon
#

@willow totem and @lone axle if there are aio keys, we don't specifically error, but should we?

# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml
# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.)
ssid = getenv("CIRCUITPY_WIFI_SSID")
password = getenv("CIRCUITPY_WIFI_PASSWORD")
aio_username = getenv("ADAFRUIT_AIO_USERNAME")
aio_key = getenv("ADAFRUIT_AIO_KEY")

if ssid is None:
    raise Exception(
        "WiFi settings are kept in settings.toml, please add them there."
        "the settings file must contain 'CIRCUITPY_WIFI_SSID' and "
        "'CIRCUITPY_WIFI_PASSWORD' at a minimum"
    )
if aio_username  is None:
    raise Exception(
        "Adafruit IO settings are kept in settings.toml, please add them there."
        "the settings file must contain 'ADAFRUIT_AIO_USERNAME' and "
        "'ADAFRUIT_AIO_KEY'"
    )

or

# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml
# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.)
ssid = getenv("CIRCUITPY_WIFI_SSID")
password = getenv("CIRCUITPY_WIFI_PASSWORD")
aio_username = getenv("ADAFRUIT_AIO_USERNAME")
aio_key = getenv("ADAFRUIT_AIO_KEY")

if None in [ssid, aio_username]:
    raise Exception(
        "WiFi and Adafruit IO settings are kept in settings.toml,"
        "please add them there. the settings file must contain "
        "'CIRCUITPY_WIFI_SSID', 'CIRCUITPY_WIFI_PASSWORD', "
        "'ADAFRUIT_AIO_USERNAME' and 'ADAFRUIT_AIO_KEY' at a minimum"
    )
lone axle
#

yeah πŸ™‚

#

tbh with it refactored that way I would go ahead and toss in password and aio_key too

short tendon
#

although password could be blank, yes?

#

but I can

lone axle
#

A network can have no password, but I'm not sure if None vs "" would make a difference

short tendon
#

I'll test getenv and see what it does. one sec

lone axle
#

though I have never tested on a network without a password. I assume it works okay, but there could be issues I'm not sure. I never considered it, hopefully it's not really being done 😬

#

most networks without a password tend to be public hot spots that have some other login or accept mechanism that would block our code I think.

short tendon
#

that totally works. So we could tell people to set it to:

CIRCUITPY_WIFI_PASSWORD=""
#

This look good?


# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml
# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.)
ssid = getenv("CIRCUITPY_WIFI_SSID")
password = getenv("CIRCUITPY_WIFI_PASSWORD")
aio_username = getenv("ADAFRUIT_AIO_USERNAME")
aio_key = getenv("ADAFRUIT_AIO_KEY")

if None in [ssid, password, aio_username, aio_key]:
    raise KeyError(
        "WiFi and Adafruit IO settings are kept in settings.toml, "
        "please add them there. The settings file must contain "
        "'CIRCUITPY_WIFI_SSID', 'CIRCUITPY_WIFI_PASSWORD', "
        "'ADAFRUIT_AIO_USERNAME' and 'ADAFRUIT_AIO_KEY' at a minimum."
    )
#

I get this:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyError: WiFi and Adafruit IO settings are kept in settings.toml, please add them there. The settings file must contain 'CIRCUITPY_WIFI_SSID', 'CIRCUITPY_WIFI_PASSWORD', 'ADAFRUIT_AIO_USERNAME' and 'ADAFRUIT_AIO_KEY' at a minimum.
willow totem
willow totem
lone axle
#

but I've not read the real definition of either, and I think it's not a huge difference either way.

willow totem
#

I always wonder about Value vs Key vs Argument errors. Sometimes it's obvious, but othertimes the pedant in me is never satisfied

lone axle
#

both are an upgrade over ImportError

short tendon
#

so if it's None, it means it's not there, so the key is missing

short tendon
willow totem
#

with an empty value, not no value πŸ˜„

#

for an empty password string

stuck elbow
#

there is also RuntimeError which is a superclass of ValueError and KeyError

short tendon
#

I just did storage.erase_filesystem() and the settings.toml is empty

willow totem
#

lol I take that back then

#

should be identical with an erased board then install

short tendon
#

@lone axle what exception would you like? RuntimeError works for me

lone axle
#

RuntimeError sounds good to me too.

short tendon
#

Awesome. I have most the code updated. Will open up the first PR tonight (9 files, all the ones in a folder that start with A) and leave a bunch of comments, that will make future reviews easier. (I was also wrong on the count, there's only like 80 files)

manic glacierBOT
#

Not fixed, I have the exact same issue when trying to move some files from windows to circuitpython. I have tested with the version 9.1.4 and 9.2.4. I also tried to move the files from my SD card to the filesystem (I am trying to put Beryllium on my cardputer) using this code for code.py, yet it stops working at the very same moment as when doing it directly from my computer, that is, when copying /Beryllium/lib/ftp_server.mpy :


# SPDX-FileCopyrightText: 2017 Limor Fried for Ad...
manic glacierBOT
#

A couple of thoughts on internal sample data type (that would have to target CP 10):

  • Using floating-point likely is too much (but maybe not?) for audio samples, but in many cases we use int32 in a module and then compress into int16 for output. Would it make sense to use int32 in the entire internal processing chain.
  • If int32 is used for samples, a step is then required to go to int16 for output (or 8) and then we could give options. E.g. hard clipping, the current synthio mix down, or ot...
manic glacierBOT
copper linden
#

i think i might of posted this question before, but can i add micropython libraries to circuitpython?

#

i wanted to expand the bluetooth low energy library

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

For RP2350 boards with PSRAM, buffers for use with DMA may be unpredictably allocated in PSRAM. When DMA attempts to access a buffer in PSRAM, a bus fault occurs. This will manifest as a CircuitPython core code crash.

In the present implementation, SRAM and PSRAM are added to the main tlsf heap as separate pools. tlsf does not differentiate between these pools. It happens that tlsf will allocate memory from the SRAM pool first because it was added first. Once SRAM is filled, allocati...

tulip sleet
copper linden
#

gotcha, would be nice if there were a lot of examples using _bleio

manic glacierBOT
jaunty juniper
#

@storm linden I would open an issue in the Circuitpython repo.
from the original PR it looks like it's enabled only on one RP2040 board, which has CIRCUITPY_USB_HOST disable, I don't know if that's relevant
https://github.com/adafruit/circuitpython/pull/9164

onyx hinge
#

Howdy <@&356864093652516868> ! Double check your clocks & calendars, for Daylight Saving Time has come to the Adafruit factory in Brooklyn and thus to the weekly meeting time! So it's a little over 2 hours from now. To see the meeting time in your local time zone, check out the online calendar https://open-web-calendar.hosted.quelltext.eu/calendar.html?url=https%3A%2F%2Fraw.githubusercontent.com%2Fadafruit%2Fadafruit-circuitpython-weekly-meeting%2Fmain%2Fmeeting.ical&title=CircuitPython Meeting Schedule&tab=agenda&tabs=month&tabs=agenda

onyx hinge
#

If that's accurate, this issue cannot be resolved within circuitpython but would require changes in tinyusb to support multiple different host controllers in a single build.

candid sun
#

<@&356864093652516868> We'll have our weekly meeting in about 1 hour & 20 minutes from now in this text channel and in the circuitpython voice channel. Please take the time to add your notes in advance to the document: https://docs.google.com/document/d/14g8cgraUdNkIX4AiUpA_r2YfkXm_8MIflEEAMV8GrDM/edit?tab=t.0 -- I look forward to everyone's updates!

random junco
#

I can hear both Liz & jepler

onyx hinge
#

if necessary I can be the host today. Except I have this cough...

onyx hinge
#

@candid sun I can do "core" if you like

#

@candid sun I can also grab blinka if you want

candid sun
#

@onyx hinge thank you!

onyx hinge
onyx hinge
#

πŸ‘‹

lone axle
#

Thanks for hosting Liz. Have a great week everyone. πŸ‘‹

manic glacierBOT
candid sun
#

Here is the notes document for next Monday’s CircuitPython Weekly meeting. It is at the normal time of 11am Pacific / 2pm Eastern here on Discord. Everyone is encouraged to attend! Please add your hug reports and status updates even if you’ll be attending the meeting - it’s super helpful! If you are unable to attend but would still like to include updates, feel free to include them in the notes and we’ll read them off during the meeting. Hope to see you there! <@&356864093652516868>
https://docs.google.com/document/d/1Ko1sPKV5IYbYRw7ZtuqmnlXF6drwYaU91RZNFuMBK6o/edit?tab=t.0

short tendon
#

hey @lone axle wanted to check and see if you saw the learn guide PR?

lone axle
short tendon
#

Awesome

manic glacierBOT
jaunty juniper
manic glacierBOT
tulip sleet
manic glacierBOT
spare jacinth
#

Or does it mean "there is a LED" and not "led is this one"?

jaunty juniper
#

in fact in that same code both #if and #ifdef are used

spare jacinth
#

Yeah, just saw it

#define CIRCUITPY_STATUS_LED ((CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_STATUS)) || defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || CIRCUITPY_PWM_RGB_LED)
#

So yeah, always defined as far as i can tell, should be #if

jaunty juniper
#

I don't think it causes errors since new_status_color would do nothing in all of its #ifdef MICROPY_HW_LED_STATUS and such sections, and I don't know that we even have much boards without an LED, I just don't want to do a PR just for that 😬

tulip sleet
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

I had a couple hours to look at this today and haven't made a lot of progress but here's what I've dug up so far.

displayio_display_core_set_root_group does a check to see if root_group->in_group is true and does nothing/returns if it is, so it looks to me like the frame_buffer version ends up doing the same check before setting the root_group as the busdisplay version.

if I remove the circuitpython_splash.in_group test from reset_busdisplay, it results in a `NLR jump failed. Likely memo...

manic glacierBOT
#

Apparently the NLR error is coming from attempting to raise the following error:

    if (!ok) {
        mp_raise_ValueError(MP_ERROR_TEXT("Group already used"));
    }

Which is avoided if the call to the displayio version of set_root_group is skipped because of the in_group test. I'm guessing code.py is too early to use the mp_raise_ValueError function?

manic glacierBOT
#

This problem should be solved, because of the recent PR from @tannewt (#10122). Now we have a saves-partition which is internally mounted on /saves. If you mount your CIRCUITPY-drive from the host computer, you can see the files within
/saves, you can add and delete and modify files, although the C-source code promises something different: https://github.com/adafruit/circuitpython/blob/ca0eec3f1a3dec49245a9fd5883e40eb9d96e2a8/supervisor/shared/filesystem.c#L96.

But every change within `...

manic glacierBOT
#

I didn't check but I suspect the duplicate directory listing in os.listdir() is coming from this code block in extmod/vfs.c:

389         } else {
390             // a mounted directory
391             mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));

since we've decided mount points should exist as directories in CIRCUITPY, we might just want to remove that block as a CIRCUITPY-CHANGE.

#

@bablokb This PR is about how the filesystem shows up in CircuitPython using functions like os.listdir. It's not about how the filesystem shows up on a host computer when mounted as a drive. The fact that the host computer will see the placeholder file in saves on the CIRCUITPY drive, instead of the real save content, would be a separate issue (and likely one without a good easy solution, sadly; but that may just be my natural pessimism showing)

manic glacierBOT
manic glacierBOT
#

@gamblor21 Some notes on your previous items

  • I'm still happy with the performance of ticking every 256 frames. If we moved away from SYNTHIO_MAX_DUR, I think it'd only be for semantics. On lower performance platforms, it may be good have control of that constant.
  • synthio.LFO could more into a module like audiocore, but I don't see an immediate benefit. Maybe less ram usage by not loading in the rest of synthio? LFOs are commonly associated with synthesizers, so it makes sense to me a...
short tendon
#

@lone axle the next batch I'm doing have a secrets.py in the folder. Like this one. Should I just delete it?

lone axle
# short tendon <@382939733107408897> the next batch I'm doing have a `secrets.py` in the folder...

I think I'm in favor of replacing it with settings.toml that contains similar placeholder values with the appropriate names for any values needed by the code.py

# This file is where you keep secret settings, passwords, and tokens!
# If you put them in the code you risk committing that info or sharing it

CIRCUITPY_WIFI_SSID="your-wifi-ssid"
CIRCUITPY_WIFI_PASSWORD="your-wifi-password"
ADAFRUIT_AIO_USERNAME="your-aio-username"
ADAFRUIT_AIO_KEY="your-super-long-aio-key"
#

For now at least. Perhaps there is room for wider discussion about whether we want these files checked in to the repo. I can see some benefits and drawbacks of both ways and don't necessarily have a strong opinion, but lean towards keeping it as similar as possible as it was before at the moment.

short tendon
#

okay, will change. Easy to delete afterwards

manic glacierBOT
short tendon
#

I had an idea, tell me if I'm crazy. This always comes up this time a year (and again later) with apps getting off time. People can use the AIO datetime methods, but those are heavy.

I have a few projects that have the next 5 years of offsets so when I get time via NTP, I can adjust.

I thought about a package that had all of them, but it would be big. But then I was thinking we have the fonts library that installs specific fonts and that I could build it like that, where you could install a certain TZ or a region.

Then you could call NTP with a timezone instead of an offset and it would correct it for you.

And on top of that the library would have a self updating script to have the previous, current and next x years so as the world changes it's always up to date.

Thoughts?

manic glacierBOT
crimson ferry
#

Is there anything in the core that uses an RP2350 (with wifi) state machine by default? I can create 5 PIO UARTs, but then I get RuntimeError: All state machines in use. I should be able to get 6?

#

Also I notice that the PIO UART doesn't have a receiver_buffer_size arg, so I assume it won't be able to absorb as much data in the background as a busio UART with a large buffer (what is the upper limit)?

mortal kernel
#

The "All state machines in use" error is thrown if state machines are exhausted or PIO program space is full.

crimson ferry
#

@mortal kernel Thanks for the explanation. I'm going to test the receive buffering.

mortal kernel
crimson ferry
#

looks like 8 bytes is the limit for the PIO receive buffer

mortal kernel
crimson ferry
#

maybe my test is wrong```py

buffer
bytearray(b'usukbpmugboseyqdtvdqafsgtyxhtuukhwzvmmlueruljointalggueutzmluqeu')

uart_pio.write(buffer)
uart_busio.in_waiting
64
uart_busio.read(64)
b'usukbpmugboseyqdtvdqafsgtyxhtuukhwzvmmlueruljointalggueutzmluqeu'

uart_busio.write(buffer)
64
uart_pio.in_waiting
8
uart_pio.read(64)
bytearray(b'usukbpmug')

#

(hardware : a busio UART connected to a PIO UART)

#

oh, it's 9 received, not 8 o_O, even though in_waiting is 8

mortal kernel
#

There's something in the low-level PIO support code that's returning the 8 I'm chasing down.

crimson ferry
#

if I write <=8 bytes, in_waiting matches the number of bytes read

mortal kernel
#

uart_pio.in_waiting is returning the number of 32-bit words in the FIFO, not the number of bytes. uart_busio.in_waiting looks like it returns bytes. At least that's what I'm seeing reading the code, but it's getting late and it's all a bit blurry...

crimson ferry
#

it's late here too... thanks for looking into it

mortal kernel
#

Feel free to hit me up tomorrow. I'll give it another look in the morning.

mortal kernel
#

@crimson ferry In the fresh light of dawn I've looked at the two flavors of in_waiting again. uart_pio.in_waiting returns the number of 32-bit words in the UART's RX state machine's FIFO. This behavior is documented correctly. Each PIO state machine has a pair of RX/TX FIFOs, each 4x32-bits. Since PIO_UART uses separate state machines for RX and TX, each state machine is programmed to combine its FIFOs into a single FIFO of 8x32-bits. So, the 8 you're seeing means that there are actually 32 bytes in the FIFO.

There is a bug in uart_pio.readinto() which is called by uart_pio.read() where it treats the value of self.rx_pio.in_waiting as a byte count. This should be looked into.

For uart_busio.in_waiting a byte count is returned. This is also correctly documented.

crimson ferry
#

@mortal kernel thanks again for digging in, though I’m still confused because for small byte counts (<=8), PIO in-waiting is accurate. In any case, I’ll file an issue.

mortal kernel
#

For my own info, I'd like to know how you set up your test so I can play along at home. I'm digging into UART emulation on PIO for the first time.

crimson ferry
#
>>> uart_busio = busio.UART(board.GP0, board.GP1)
>>> uart_pio = adafruit_pio_uart.UART(board.GP26, board.GP27)
``` where GP0 is connected to GP27, and GP1 is connected to GP26. Then the code above, and I play with the length of the bytearray sent.
#

(this is a Pimoroni Pico Plus 2 W with CP 9.2.4)

mortal kernel
#

Try changing the line

waiting = min(len(buf) - count, self.rx_pio.in_waiting)

to

waiting = min(len(buf) - count, self.rx_pio.in_waiting * 4)

in uart_pio.readinto()

crimson ferry
#

but for 1-8 bytes sent, in_waiting correctly shows 1-8, and read correctly reads 1-8. sending anything 9 or over shows 8 in_waiting (e.g, sending 128 shows 8), but receives 9 bytes (e.g., 128 bytes sent only gets 9 bytes read).

mortal kernel
#

I think that's at least partly due to the bug in readinto(). Your loopback is easy enough to set up. I'll give it a shot.

crimson ferry
#

complete example comparing busio and PIO UARTs (RP2350, with loopback wires between the two UARTs)

tulip sleet
#

@crimson ferry @mortal kernel I suggest that having .in_waiting return a word count is a bug, even if it's documented. When I look at https://github.com/adafruit/Adafruit_CircuitPython_PIO_UART/blob/fa6496a4dc2d66493402cf6f52707901317b4df3/adafruit_pio_uart.py#L147 it says """Return whether the UART is waiting.""". .in_waiting in some libraries used to return a bool, which is what the description implies.

is https://github.com/adafruit/Adafruit_CircuitPython_PIO_UART/blob/fa6496a4dc2d66493402cf6f52707901317b4df3/adafruit_pio_uart.py#L168 right? It's using .in_waiting. Is the buffering by words or by bytes?

crimson ferry
#

busio returns the number of bytes accurately for in_waiting

#

@mortal kernel if I make the library change, the output is the same through buflen=10, but then it hangs up in the read on 10

#

PIO should behave as much like busio as possible?

mortal kernel
#

@danh The description is wrong in PIO_UART for in_waiting. What it actually does is call into the SDK function pio_sm_get_rx_fifo_level() via common_hal_rp2pio_statemachine_get_in_waiting() via rp2pio_statemachine_obj_get_in_waiting(). The SDK reads the 4-bit hardware level corresponding to the state machine, a count of 32-bit words in the FIFO. The FIFO acts as a SERDES, in this case taking bits from the SM and delivering them as 32-bit words via the FIFO.

tulip sleet
#

anything_UART should have an API like busio.UART and bitbangio, so they can be used interchangeably.

mortal kernel
#

OK, so if I'm understanding correctly we should be returning the raw value from the SDK multiplied by 4 to convert it to bytes.

tulip sleet
#

how can we tell if there is anythingto read? and how do we distinguish between three bytes received and four bytes received?

mortal kernel
#

good question. My assumption is that as soon as there is anything in FIFO it starts reporting 1 word. I think we need an experiment to be sure, the RP2350 datasheet doesn't make it clear.

tulip sleet
#

there must be some way of knowing how many bytes there are, unless it's that nulls are always discarded or something, but that's not a good impl of UART in that case

#

the PIO program itself keeps track??

#

I did not look at the PIO code

mortal kernel
#

The PIO program just looks for the "eye" and then clocks in 8 bits. Dead simple. No overall byte count.

tulip sleet
#

so you can only read four at a time?

#

seems not so useful

mortal kernel
#

Yes, that's a limitation of the PIO FIFO.

tulip sleet
#

could it move on to the next 32-bit word after one byte, so that it's only one byte per word?

#

is this PIO program from pico-examples or similar?

mortal kernel
#

I think so, but again it deserves an experiment to know for sure. And yes, it looks like it came out of the datasheet.

tulip sleet
#

πŸ™ƒ πŸ˜•

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.4 on 2025-01-29; Pimoroni Pico Plus 2 W with rp2350b

Code/REPL

import time
import random
import board
import busio
import adafruit_pio_uart

time.sleep(3)  # wait for serial

uart_busio = busio.UART(board.GP0, board.GP1)
uart_pio = adafruit_pio_uart.UART(board.GP26, board.GP27)

for buflen in (1, 2, 3, 7, 8, 9 ,10, 15, 16, 17, 18,):
    buffer = bytearray()
    for _ in range(0, buflen):
       ...
mortal kernel
#

I'm going AWK for breakfast and a walk. Be back in an hour or so, hopefully with some fresh ideas of how proceed...

tulip sleet
#

@crimson ferry this should be an issue on the library, no? I can transfer it. I don't see it's a core issue

crimson ferry
#

Transferred.

#

I wonder if PIO UART should be in the core. There is no receiver_buffer_size argument in the init. My assumption is that the read buffer will be very limited in how many bytes it can hold in the background while user code is doing something else, so any PIO UART usage will have to be very carefully choreographed.

tulip sleet
sage violet
#

yes its limited to reading raw data i cant manage to read mouse scroll up and down its been a long time.

crimson ferry
#

unless PIO can push to a python buffer, but that sounds weird

tulip sleet
#

that is a recent addition

crimson ferry
#

I wasn’t aware of that one, that sounds pretty cool

mortal kernel
slender iron
#

why are you worried about pio uart?

crimson ferry
#

raspberrypi is limited to two busio UARTs, and there's no bitbangio UART

#

(and there's a bug and perhaps some other improvements, in the library)

slender iron
#

rp2 or broadcom chips?

mortal kernel
#

Digging into it has proven to be a great way to learn about rp2pio.

crimson ferry
#

rp2

slender iron
#

2040 or 2350?

crimson ferry
#

presumably both, I've been testing on RP2350

#

was thinking this morning to verify on RP2040

slender iron
#

looks like you are right. I thought it was more than two hardware uarts

crimson ferry
#

having up to 8 bidirectional UARTs on an RP2350 could be pretty powerful πŸ™‚

slender iron
#

looks to me like the library will need to be switched to the background pio stuff

#

otherwise you are capped by the PIO fifo length

#

busio also has a cap, it is just larger

crimson ferry
#

65535 iirc

slender iron
#

I think its the rx buffer size

crimson ferry
#

yeah, confirmed: busio receiver_buffer_size is 1-65535

manic glacierBOT
#

Let's hope! But a lot of these changes are going to need to be at least 10.x.x. When doing a restructure like this within CPy, is it typical to wait until a major release or to create the new modules and point the old ones to the new modules with a deprecation notice?

The approach depends on what user facing API changes you want to make. Typically we have old APIs coexist with new ones for one major version to give us time to migrate everything over. I think that'd be ok to do at the tail ...

crimson ferry
blissful pollen
#

Quick question: are all CP boards at least 32-bit? I think the answer is yes but just wanted to be sure.

crimson ferry
onyx hinge
#

@blissful pollen yes, all have at least 32 bit addresses & 32 bit registers. it may be the case that the broadcom port has 64-bit addresses and/or 64-bit registers, I don't know for sure. But I'm also curious why you ask the question.

blissful pollen
onyx hinge
#

You can probably think of cortex-m0plus as kind of a baseline of CPUs for CircuitPython (even though there are some others like xtensa & risc-v in the mix now). Multiplying signed 16x16 bits, 16x32 bits & 32x32 bits to an output of 32 bits is all the same instruction (muls).

#

But when treating integer numbers as "fixed point", you're often interested in the upper bits of the multiplication. For instance, if you talk about "Q1.15" numbers and you want to get the product of two of them as another "Q1.15" number, you need the upper bits, just like if you multiply out "99 * 99" you get "9801", but when you multiply ".99 * .99" you need to get ".9801", the top 2 digits instead of the bottom two digits ...

#

so when you shift to doing multiplies on 32 bit quantities that are implicitly representing binary fractions with a fixed precision, you actually need to do a 64-bit multiply (and take the upper part), and that is less efficient than taking the upper part of the 32-bit part of a muls result.

#
int32_t mulshift32(int32_t a, int32_t b) {
    return ((uint64_t)a * b) / (1ll << 31);
}```On cortex-m0plus this compiles to much more complex code than the 16-bit version, calling a function `__aeabi_lmul` to perform the actual multiplicatoin. On cortex-m3, there's a new instruction "smull" (signed multiply upper ll??). So, even though both the rp2040 and rp2350 are "32 bits", they will have very different performance characteristics when multiplying 32-bit fixed point numbers
#

(similarly, rp2350 has a built in division instruction while on rp2040 it's a function call) You can see what each CPU generates here: https://godbolt.org/z/cKhET8vWK

#

I mis-spoke, rp2350 is cortex-m33 (not cortex-m3) but they seem to be the same when it comes to having sdiv & smull instructions available.

blissful pollen
#

Oh cool, thanks! That gives me a bunch of stuff to look into further.

The root issue I've been thinking about is how the audio pipeline could repeatedly saturate 16 bits and mix it down from stage to stage (synth->echo->reverb for example) and maybe it would make sense to keep it 32-bit to the end.

I haven't spent much time ever dealing with fixed point so will dive down that rabbit hole for a while too.

onyx hinge
#

*out_buffer32++ += (*tmp_buffer32 * loudness[0]) >> 16; this is an example of a fixed point multiplication, where some sample is being multiplied by loudness and then shifted down (from shared-module/synthio/__init__.c)

blissful pollen
#

I don't think I quite grasped the shifts I saw before but now it makes a lot more sense.

onyx hinge
#

I know you weren't angling for such a brain dump but there ya go πŸ™‚

#

(also that operation is a bit dubious now that I look at it, because the result of multiplying 32-bit tmp_buffer with 16-bit loudness could be 48 bits, but it's only 32-bit arithmetic that's being done there...)

blissful pollen
#

The brain dump is more then welcome. I've been spending some (too?) much time with ChatGPT and audio source code from other similar software to get ideas and learn. The fixed point part never jumped out at me.

onyx hinge
#

RP2350 datasheet sections 3.7.4.9 gives some info about how long operations take. For instance, a 32-bit multiplication result is available with a 1-cycle delay, while divisions take a variable amount of time related to the operands..

blissful pollen
onyx hinge
#

also see rp2350 datasheet section "3.7.4.9.10. Floating-point coprocessor operations." on cortex m33 32-bit float arithmetic is pretty fast too and it saves you from having to manually track scale factors. you can't forget a >>16, or a spot where you really needed a 48-bit multiply instead of a 32-bit one. honestly if moving beyond 16 bit integer stuff I'd prototype this first, and if it's good enough on rp2350 & some nicer esp32 say "yeah, we're doing [new] audio in floating point now". Stuff like biquad filter coefficients, which REALLY are resistant to reducing to 16-bit fixed point, would be much happier. (some specific things like note phase for direct digitital synthesis in synthio should stay integer though)

blissful pollen
#

So far this is in my long term idea bucket, but for sure needs a prototype to test it out. I am curious on saw a 2040 what speeds are still possible or alternatives. And at a minimum to not break audio on older processers πŸ™‚

slender iron
#

@lone axle you around still and want to talk fonts?

lone axle
slender iron
#

thanks

lone axle
#

@slender iron okay, ready any time.

onyx hinge
wheat siren
#

Would there be any opposition to adding Direction and Value to the DigitalInOut constructor? I've found myself wrapping it into a single function when initialising lots of I/O

# DigitalInOut
def __init__(
    self, 
    pin : microcontroller.Pin,
    direction: Optional[digitalio.Direction] = None,
    value: Optional[bool] = None
): ...

This lets you do things like

led_pins = (board.D1, board.D2, board.D3)

led_io = (
    DigitalInOut(
        p,
        Direction.OUTPUT,
        False
    ) for p in led_pins
)
onyx hinge
#

@wheat siren this has been discussed before (https://github.com/adafruit/circuitpython/issues/5124#issuecomment-896929174 and others) and the official word from @slender iron is as follows:

The reason we don't allow it from the constructor is that it's weird to have keyword arguments that are only valid depending on another (direction). Value and drive mode are for output and pull is for input. The class does default to input so we could add a pull kwarg. That'd simplify the input case. I'd push back against combining them.

GitHub

As it sits right now, I can set up nearly any type of pin input and output in one line. I can, for example, use: led=pwmio.PWMOut(board.D13, frequency=5000, duty_cycle = 32767) And this will start ...

wheat siren
#

Ah thank you!

tulip sleet
# wheat siren Ah thank you!

See https://github.com/adafruit/circuitpython/issues/9845 for a proposal for a different way of doing this that passes pin configurations to anything that currently takes a bare Pin. I am planning to implement this for CircuitPython 10

GitHub

(This issue is an offshoot of #1270.) A number of open issues (#1270, #6009, #7206, #8315, #8941, #8945, #9373, #9821, #9823) have asked for the ability to set pin drive mode, drive strength, or a ...

manic glacierBOT
#

There are two variants of the Lilygo T-QT Pro. I only own one but the difference is the ram/flash setup, like the QT PY S3 (N8 and N4R2 version). It has a display, and no status LED.

I used the VID/PID requested by @tyeth who didn't get to adding the board at the time, sharing the PID between the two variants, if that's OK.
I also sneaked the change of a couple of uses of #ifdef CIRCUITPY_STATUS_LED which should be #if.

The pin names simply match the names used on the pinout card (...

manic glacierBOT
#

Just like many others I I wanted to connect more than 1 display. I will try recompiling CircuitPython tomorrow.

I also understand that it's a tradeoff and objects live outside of VM, etc.

It still would be easier if we could do it without recompiling.
Thus, I am thinking: would it be possible if we could specify max number of of displays in boot.py instead of hardcoding CIRCUITPY_DISPLAY_LIMIT?

lone sandalBOT
lime mason
#

Adafruit Trinkey Proximity issues with version 7.2.1 and beyond not running code for more than a sec

mortal kernel
#

(scroll down in gist for results on Adafruit RP2350 feather w/PSRAM)

manic glacierBOT
mortal kernel
slender iron
#

<@&356864093652516868> Just a quick reminder that the community meeting is in 1 hour and 15 minutes. The US did our time change so we're in the weird shifted period. Talk with you soon! (Notes doc in the pinned messages.)

onyx hinge
#

yup the rp1 pio related repos like piomatter are now included in the reports

#

piomatter is n steps forward, (n^1) steps back right now

willow totem
#

omg yeah, chips challenge was really well done (surprised not more recognised by folks - wish they'd demo'd the challenging block types)

blissful pollen
#

Can’t speak now sorry

onyx hinge
#

(ie., if n=2, then it's 2 steps forward, 1 step back; but if n=1 then it's 1 step forward, 2 steps back. I'm a nerd)

#

@mortal kernel I think some of the clocking you're describing in your notes is similar to what dvhstx does. specifically, it reserves 1 PLL just for hstx and clocks everything else including CPU & USB from a 528MHz PLL.

#

I dunno what PSRAM boundary mode is though

#

can you select() or poll() all the open sockets to get the "data available" flag?

tulip sleet
#

there is a hook mechanism in lwip I could use, but it would require recompiling the arduino-esp32 libraries, I think.

mortal kernel
#

@onyx hinge Let's chat after the meeting.

onyx hinge
#

@mortal kernel depending when we finish I can stick around for a few minutes.

#

A reminder of why we have frozen come before lib would be helpful @slender iron because I know you have a rationale

lone axle
#

Adding a section to our reports that checks frozen modules version against current releases does sound like it would be nice.

onyx hinge
#

a number of boards such as the portals freeze in ConnectionManager

mortal kernel
#

@onyx hinge Thanks for the dvhstx link. That answers my question.

#

On PSRAM boundary crossing mode. The PSRAM parts refresh internally. If you promise the part that you'll pause at at "wrap" boundaries it can refresh then. This allows a faster SPI clock to be used.

#

There's a special 0xc0 op that toggles the control.

onyx hinge
#

@mortal kernel OK then I'll sign off when the meeting is through. source code is worth 100x as much as an explanation from someone who's merely read the source...

lone axle
#

Thanks for hosting Scott, have a great week everyone!

willow totem
#

Would it be too insane to have a different default path order for m0 (trinkeys) and tiny flash boards, i.e. keep frozen first for them, but move path order to have frozen last by default?

slender iron
#

I don't think its worth it. Any place that needs frozen also needs those libraries out of RAM.

#

Maybe we need a troubleshooting/FAQ entry about adjusting sys.path for version issues.

#

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/15NZc6nDGYZSXt41qXQ1whWKbiChyfmh00CQwtD_NlYY/edit?usp=sharing

fleet hollow
#

@slender iron Quick typo on the youtube video of the meeting. Should be March 17th, not 27th. https://www.youtube.com/watch?v=0oO-b3eDTlo

Notes document is available here, with timecodes: https://github.com/adafruit/adafruit-circuitpython-weekly-meeting/blob/main/2025/2025-03-17.md

Join here for the chat all week: http://adafru.it/discord

The CircuitPython Weekly normally is held at 2pm US ET/11am us PT on Mondays. Check the #circuitpython-dev channel on Discord for notices of ...

β–Ά Play video
slender iron
#

my audio isn't as easy as a fix

slender iron
#

FYI Dan and I are going over issues in prep for CP 10.

#

The LUN stuff is destabilizing enough to switch main to 10.

mortal kernel
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.4 on 2025-01-28; Adafruit KB2040 with rp2040

Code/REPL

import usb_cdc
import board


usb_serial = usb_cdc.serial

while True:
    if usb_serial.in_waiting > 0:
        data = usb_serial.readline().decode('utf-8').strip()
        print(f"PΕ™ijatΓ‘ data: {data}")
        usb_serial.write(f"Odpověď: {data}\r\n".encode())

Behavior

Actual Behavior:

When attempting to use usb_cdc.serial...

midnight ember
#

This weeks meeting recording is kind of unwatchable. Sounds like some serious buffering issues. Hope you get it figured out. 😦

slender iron
slender iron
#

@lone axle is it quick for you to do a ruff update? bitmap_font is giving me trouble

lone axle
slender iron
#

thank you!

lone axle
slender iron
#

Thank you!

#

reviewing now

tulip sleet
#

@lone axle did you make a backup recording?

lone axle
# tulip sleet <@382939733107408897> did you make a backup recording?

I did, although it would need a little bit of touchup, I was early on the record button so there are several seconds at the front that could be clipped.

I also accidentally pressed stop recording after the library section of stats but started again quickly, I don't think much was missed but I have 2 files that need to be spliced.

#

I have been practicing ffmpeg some, I think both will be fairly easy. I'll attempt and share a link to the result

tulip sleet
manic glacierBOT
slender iron
lone axle
#

@slender iron in bitmapt_font I think the LVGL_HEADER_SIZE varible got lost somewhere, it's tested against but doesn't seem to be defined.

slender iron
#
# The LVGL file starts with the size of the 'head' section. It hasn't changed in five years so
# we can treat it like a magic number.
LVGL_HEADER_SIZE = b"\x30\x00\x00\x00"
#

not sure how it got lost

#

maybe I hit discard instead of stage

#

🚢 β›ˆοΈ

lone axle
#

@slender iron it's used in bitmap_font.py, so it needs imported over there. I added that in my local copy and it is working though πŸŽ‰

#

ah, it is imported, but it's inside the the block that tried to check against it.

supple prairie
#

Am I a dummy or are there no examples for HSTX on the Adafruit website? I've been looking and can't find them (reportedly there are)

supple prairie
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

I added support for the H750 chip in CircuitPython, so Daisy is the only board so far, but I think skipping the SystemInit() call is valid for any other H750 boards.

Since the microcontroller has so little internal flash (128kB), CircuitPython can only be run from a QSPI external flash (or RAM, or FMC flash), so the clocks, power and (QSPI) controller need to be initialized in the bootloader.

I can delete the "special" bootloader part in the comment, since now there is support for D...

blissful pollen
#

@onyx hinge no rush on this question, but for the synth work does it assume Q15 for most of the math / processing?

I’ve been reading way more about fixed point and now wondering if we should target it as much as possible for effects too.

manic glacierBOT
onyx hinge
#

Its a bit more ad hoc but in general yes

blissful pollen
#

Thanks! I finally got my head around it all and it made sense

manic glacierBOT
#

You're right, there is no print_traceback.

I looked for MP_QSTR_print_exception and it's in py/modsys.c (for sys) and in shared-bindings/traceback/__init__.c (for traceback). The latter is in CPython, so we wouldn't remove that.

sys.print_exception() is present in tests/basics/sys_tracebacklimit.py and in frozen/Adafruit_CircuitPython_asyncio/asyncio/stream.py, so we'd need to fix these up.

We can defer this for now. I am usually the one to update asyncio, usually when ...

tulip sleet
#

(β•―Β°β–‘Β°)β•―οΈ΅ ┻━┻

#

I'm making up release notes for 9.2.5 and will investigate this afterwards.

manic glacierBOT
onyx hinge
#

@tulip sleet that's terrible. argh.

manic glacierBOT
#

I took a quick look at trying to use a settings.toml parameter to define the display limit. Unfortunately the display/bus structures are allocated (dimensioned) at compile time so in order to do set the display limit without recompiling, the memory for the structures would have to be changed to a dynamically allocated model which probably makes it over my head....

manic glacierBOT
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.4-274-g2af397ed1c on 2025-03-06; Adafruit Metro RP2350 with rp2350b
Board ID:adafruit_metro_rp2350

Code/REPL

import supervisor
import sys

while True:
    available = supervisor.runtime.serial_bytes_available
    if available:
        c = sys.stdin.read(available)
        print(c, end='')

Behavior

The code runs and waits until a key is pressed. Once a key is pressed the device reboots ...

tulip sleet
#

@slender iron @onyx hinge @mortal kernel CI fetch issue with the nordic URL's was transient. A re-run worked. When using the URL in a browser, the result is confusing, but wget works fine.

manic glacierBOT
manic glacierBOT
manic glacierBOT
#
[adafruit/circuitpython] New tag created: 9.2.5
orchid basinBOT
#

Automated website update for release 9.2.5 by Blinka.

New boards:

  • adafruit_fruit_jam
  • daisy_seed_with_sdram
  • elecrow_crowpanel_4_2_epaper
  • heltec_vision_master_e290
  • hxr_sao_dmm
  • lilygo_tdongle_s3
  • lilygo_tqt_pro_nopsram
  • lilygo_tqt_pro_psram
  • lolin_s3_mini_pro
  • nordic_nrf5340dk
  • nordic_nrf54l15dk
  • nordic_nrf7002dk
  • proveskit_rp2040_v4
  • red-s2-wroom
  • renesas_ek_ra6m5
  • renesas_ek_ra8d1
  • spotpear_esp32c3_lcd_1_69
  • st_nucleo_u575zi_q
  • st_stm32h7b3i_dk
mortal kernel
tulip sleet
#

https://blog.adafruit.com/2025/03/18/circuitpython-9-2-5-released/
Highlights of this release:

  • Update frozen modules.
  • Enable function attributes and reverse arithmetic operators on most boards.
  • displayio:
    • Add tilepalettemapper.
    • Add VT100 escape code support for scrolling and colors.
  • synthio and audiodelays additions.
  • Add audioio on Espressif.
  • Add spitarget on SAMx (enabled on most SAMx5x boards).
  • Initial work on a Zephyr port.
  • Bug fixes.
manic glacierBOT
#

CircuitPython version and board name

Building any RP2350-based raspberrypi with current top of `main`.

This is *not* a 9.2.5 regression.

Code/REPL

n/a

Behavior

n/a

Description

Including the header sdk/src/rp2_common/hardware_xip_cache/include/hardware/xip_cache.h results in:

In file included from common-hal/picodvi/Framebuffer_RP2350.c:42:
./sdk/src/rp2_common/hardware_xip_cache/include/hardware/xip_cache.h:67:5: error: "PICO_RP2040" ...
jaunty juniper
#

I'm adding the Waveshare-ESP32-S3-Touch-LCD-2 to CP and tinyUF2 and that board is a little weird as it doesn't go into ROM bootloader but tinyuf2 when resetting while holding BOOT, only when plugging while holding BOOT does it go into the bootloader. Now according to the schematics GPIO 0 is also used for the LCD reset pin, so maybe there's something there 🀷

jaunty juniper
#

on the other hand it makes it easier to boot into UF2 mode πŸ˜„

manic glacierBOT
#

The board is Waveshare part No ESP32-S3-Touch-LCD-2
ESP32-S3 2inch Capacitive Touch Display Development Board
https://www.waveshare.com/esp32-s3-touch-lcd-2.htm?sku=29667

  • 8MB Ram, 16MB Flash
  • 320x240 LCD
  • qmi8658c IMU tested with the community bundle qmi8658c.py library (with INT pin)
  • CST816D capacitive touch tested with a modified version of the adafruit_cst8xx library (with INT pin)
  • On-board camera interface, compatible with mainstream cameras such as OV2640 and OV5640
    -...
manic glacierBOT
manic glacierBOT
#
[adafruit/circuitpython] New branch created: 9.2.x
tulip sleet
#

@slender iron @onyx hinge @mortal kernel et al I just created a 9.2.x branch. So main is now for 10.0.0. Any bugfixes for 9.x.x would be PR's against 9.2.x. If we move on to a 9.3.0 we would create a 9.3.x branch off 9.2.x

slender iron
tulip sleet
#

not yet,

slender iron
#

kk, we should be able to merge some of @mortal kernel's changes and then tag them

tulip sleet
#

also I need to fix the readthedocs defaults

manic glacierBOT
slender iron
#

ok, there we go!

manic glacierBOT
#
[adafruit/circuitpython] New tag created: 10.0.0-alpha.0
tulip sleet
#

I tagged 9.2.5 also as 10.0.0-alpha.0, so #10144 is after that.

slender iron
#

does that confuse the version determination?

tulip sleet
#

hmm maybe so, I can move it

manic glacierBOT
#

It is in the current build:

Adafruit CircuitPython 9.2.4-330-gea45b0e2cb-dirty on 2025-03-18; Adafruit Fruit Jam with rp2350b
>>> import sys
>>> dir(sys)
['__class__', '__name__', '__dict__', 'argv', 'byteorder', 'exit', 'implementation', 'maxsize', 'modules', 'path', 'platform', 'print_exception', 'stderr', 'stdin', 'stdout', 'version', 'version_info']

I suspect we'll need to modify modsys.

tulip sleet
#

ok, moved to the first commit after

slender iron
#

thanks!

manic glacierBOT
tulip sleet
#

@slender iron @mortal kernel @onyx hinge This is the easiest way I've found to get new branches into your fork:
git fetch adafruit 9.2.x:9.2.x
also do a git fetch adafruit --tags to pick up the 10.0.0-alpha.0 tag

mortal kernel
tidal kiln
#

this might be expected behavior? or might be indicating something? using a Metro M4 and loading 9.2.5 - it does not show any activity (dmesg) after UF2 is copied and reset.

#

it may be related to the Metro M4 being in a weird state (not sure what last usage was)

#

can load 9.2.4, and it will go into safemode and give a com port

#

which shows:

Auto-reload is off.
Running in safe mode! Not running saved code.

You are in safe mode because:
CIRCUITPY drive could not be found or created.
Press reset to exit safe mode.

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

Adafruit CircuitPython 9.2.4 on 2025-01-28; Adafruit Metro M4 Express with samd51j19
>>> 
#

so i'm thinking of doing a storage.erase() next, but posting here first in case this is worth looking at further?

#
UF2 Bootloader v3.15.0 SFHWRO
Model: Metro M4 Express
Board-ID: SAMD51J19A-Metro-v0
lone axle
#

@tidal kiln I am not sure what could cause that issue, but I just loaded 9.2.5 on my metro M4 with no issues, it boots up and seems to behave normal under 9.2.5

tidal kiln
#

hmmm...my Metro M4 Express "BETA" board comes up fine

#

maybe this one not working is an even older variant

#

components are located different

#

left one works, right one is weird

#

different flash chips

lone axle
#

mine looks closer to the left, but not quite the same silkscreen at least

tidal kiln
#

yah. i think maybe it's just this board. been too long to remember, but i think i got one pre-beta for testing.

wraith crow
#

@tulip sleet I'm going to take another look at the multi-display issue, which tag/branch would you prefer I base my work on in case it results in a PR?

tulip sleet
manic glacierBOT
ionic elk
#

I'm basing my ros circuitpython rclcpy module off rclpy, which has lots of features that will not be supported. Should I still include all unsupported arguments and give them NotImplemented errors?

solar whale
tulip sleet
#

The plain type "M4" and the B in a circle is the giveaway, I think.

solar whale
manic glacierBOT
tidal kiln
solar whale
#

Off the fantail with it! πŸ˜‰ When I used to work in Oceanography and would spend several weeks on research ships at sea, I had a "fantail rule" for dealing with defective 8" floppy discs and mag tapes. If they failed, they were to be taken to the ships fantail and thown overboard so that they could not find their way back to use. This was 45 years ago and we were not quite so conscious of the environmental impact, Probably could have just binned them, but it was fun to fling them off the fantail. The impact of having one get re-used was significant!

manic glacierBOT
#

CircuitPython version and board name

Raspberry Pi Pico and other MCUs using the RP2040/RP2350

CircuitPython 9.0.0  Beta 0   Bad
CircuitPython 9.0.0  Alpha 6  Good

Code/REPL

No REPL Information

Behavior

If using a powered USB hub:

MCU makes file system read only when Windows PC is turned off/on or rebooted

Power off/on to MCU to be able to write to MCU file system

Description

To duplicate the issue:

  1. Plug the MCU into a power USB hub. ...
manic glacierBOT
#

MICROPY_QSTR_BYTES_IN_HASH says how many bytes to reserve for a qstr hash. Typical values are 0, 1, 2.

MicroPython uses 0 for the smallest builds causing a few % penalty in performance. See https://github.com/micropython/micropython/pull/12835. MicroPython uses 2 for builds that are not cramped for space, and 1 for others.

CircuitPython uses 1 for everything.

Trinket build delta
0: -640
1: 0 (default)
2: +664

So changing to 0 for tiny builds will get us some extra space, if we need it in...

manic glacierBOT
#

#10134 added PY_FUNCTION_ATTRS and PY_REVERSE_SPECIAL_METHODS to most of the mpconfigport.h files. It occurred to me that these should be controlled CIRCUITPY_FULL_BUILD (which is on by default), with some exceptions for "small" full builds on SAMD21.

So this refactors that change to circuitpy_mpconfig.h.

I also turned on MICROPY_PY_BUILTINS_NOTIMPLEMENTED more consistently.

I also went through the language-feature flags in py/mpconfig.h to see if there were new ones we...

manic glacierBOT
#

I don’t have a USB-to-Serial converter so I can’t do anything about this at
the moment.

I’ll consider whether it’s worth investing in, but if someone else can do
some validation I can throw up the changes I made.

On Tue, Mar 11, 2025 at 11:36 Scott Shawcroft @.***>
wrote:

I think you need a debug build make BOARD=... DEBUG=1 and then a
usb-to-serial converter on the TX pin.

β€”
Reply to this email directly, view it on GitHub
<https://github.com/adafruit/circui...

#

@anecdata I've retested with Adafruit CircuitPython 9.2.5 on 2025-03-19; Raspberry Pi Pico W with rp2040.

With an empty code.py and a settings.toml:

CIRCUITPY_WIFI_SSID = "xxxxxxxxxx"
CIRCUITPY_WIFI_PASSWORD = "xxxxxxxxxx"
CIRCUITPY_WEB_API_PASSWORD= "jk"

I can access the web workflow through my browser (Firefox on Debian Bookworm) using either http://192.168.1.250 or http://circuitpython.local with no discernible delay.

`curl -iL --compressed "http://circuitpython.loc...

manic glacierBOT
#

Factored common_hal_os_uname() into os_uname(). Removed common_hal_os_uname entirely. Testing:

Adafruit CircuitPython 9.2.4-318-g2f4cd7497d-dirty on 2025-03-20; Adafruit Feather RP2350 with rp2350a
>>> import os
>>> print(os.uname())
(sysname='rp2350a', nodename='rp2350a', release='9.2.4', version='9.2.4-318-g2f4cd7497d-dirty on 2025-03-20', machine='Adafruit Feather RP2350 with rp2350a')

onyx hinge
#

huh I must have just imagined that we had put the web workflow hostname in os.uname

mortal kernel
#

Didn't see it there, let me scan to see if it was in any of the ports...

#

Nope, not there.

onyx hinge
#

no, I don't see it either

mortal kernel
#

It would be handy to have os.uname().hostname. I'll open an issue and see what Scott thinks.

jaunty juniper
#

we don't want to do that, os.uname is a C python thing

#

it does define only 5 attributes and doesn't seem to allow for implementation-specific additions ?

#

but nodename should be the hostname

mortal kernel
#

I see that. CP is doing nodename incorrectly.

jaunty juniper
#

I mean, "implementation-defined" right ? 😬

#

the thing is i'm gonna bet nobody uses nodename on desktop python anyway, since as the docs mentions it's a poor substitute for a hostname, it might even be truncated

mortal kernel
#

Agree, probably not used. Would be nice to get it right, though?

jaunty juniper
#

yeah

mortal kernel
#

OK, I'll make an issue and throw it back in the hopper for now. All the other members of the tuple are static, so implementation will take a little more thought.

jaunty juniper
#

yeah, and the default mdns name cpy-1234-stuff is created dynamically deep into port implementations of the wifi module within common_hal_wifi_init, it could be moved into a dedicated supervisor thing or something

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.5 on 2025-03-19; Pimoroni Pico Plus 2 with rp2350b

Code/REPL

import audiobusio
import audiomixer
import board
import synthio

TEST = False

synth = synthio.Synthesizer()

mixer = audiomixer.Mixer(
    voice_count=1,
    channel_count=1,
    sample_rate=11025,
)

dac = audiobusio.I2SOut(
    bit_clock=board.GP0,
    word_select=board.GP1,
    data=board.GP2,
)

if TEST:
    mixer.voice[0].play(sy...
manic glacierBOT
jaunty juniper
#

should I rebase a PR to add a board on 9.2.x rather than main ?

tulip sleet
jaunty juniper
#

ok, github didn't complain so far, it doesn't seem to redo the checks but that's fine

slender iron
manic glacierBOT
#

CircuitPython version and board name

CircuitPython 9.2.5 (also tried 9.2.4); Waveshare RP2040-GEEK

Code/REPL

# boot.py
import board
import storage
import usb_cdc

import supervisor
supervisor.set_usb_identification(
	vid=0x0123,
	pid=0x0123,
	manufacturer="manu",
	product="prod"
)

Behavior

No error.

Device should be identified as:

usb 1-4: New USB device found, idVendor=0123, idProduct=0123, bcdDevice= 1.00
usb 1-4: New USB device strings: Mfr=1,...

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.5 on 2025-03-19; Raspberry Pi Pico with rp2040

Code/REPL

import board
import rotaryio
import time
time.sleep(4)

encoder_pins = [
    (board.GP0, board.GP1),
    (board.GP2, board.GP3),
    (board.GP4, board.GP5),
    (board.GP6, board.GP7),
    (board.GP8, board.GP9),
    (board.GP10, board.GP11),
    (board.GP12, board.GP13),
    (board.GP14, board.GP15),
    (board.GP16, board.GP17),
    (boa...
manic glacierBOT
#

I'm struggling with C pointers/malloc usage. I've declared the following extern variables:

primary_display_bus_t display_busesx[CIRCUITPY_DISPLAY_LIMIT];
primary_display_t displaysx[CIRCUITPY_DISPLAY_LIMIT];
primary_display_bus_t *display_buses = &display_busesx[0];
primary_display_t *displays = &displaysx[0];

and then I attempt to allocate new memory and point my variables as follows:

display_buses = (primary_display_bus_t*)port_malloc(sizeof(primary_display_bus_t) * CIRCUITP...
manic glacierBOT
manic glacierBOT
orchid basinBOT
short tendon
#

Is there a thought of adding CIRCUITPY_SAVES_PARTITION_SIZE on other boards? Even if it was just a few kb?

manic glacierBOT
wraith crow
#

When I started my PR, I performed a git checkout remotes/circuitpython/9.2.5 (my fork is actually of micropython so I need to reference circuitpython as a remote) which I thought would end up allowing me to post the PR against that tag, however when I do a git compare against the 9.2.5 tag, I don't have an option to create a PR. How do (or can) I perform the PR post against 9.2.5. Not that it's critical, just trying to create as little work for Dan as possible

#

It does look like I can do a merge to the 9.2.x branch, is that the route I should go? I'll merge to 9.2.x, I can always resubmit it if there's a better choice 😁

manic glacierBOT
#

Set the maximum supported number of displayio displays. This value overrides the CIRCUITPY_DISPLAY_LIMIT compile-time flag.

I do have some questions about this solution.

I'm not sure if this fixes #1760 since Tannewt has said he hopes to implement a better solution in CP 11. I'm also not sure main.c was the right location to insert the call to malloc_display_memory but I don't know displayio well enough to know if there was a better place somewhere in the displayio modules.

So far I...

manic glacierBOT
#

CircuitPython version and board name

Adafruit Feather RP2040 with USB Type A Host
CircuitPython 9.2.5

Code/REPL

device.read(ENDPOINT_ADDRESS, buf, timeout=10)

Behavior

It's just a sample

Description

I bought an Adafruit Feather RP2040 with USB Type A Host and installed the special version of CircuitPython for it (https://circuitpython.org/board/adafruit_feather_rp2040_usb_host/) as well as the latest (as of today) related libraries.

I can ...

manic glacierBOT
#

It looks like boards with built-in displays don't like pointer references to the display structures, I was unsuccessful getting a pointer/array combination of variables to work so I think I'll either have to look at the way the boards with builtin displays are accessing the structures or consider leaving the compile time portion of the array in place and just access the dynamically allocated array elements for display indexes > CIRCUITPY_DISPLAY_LIMIT.

Fun for another night.....

slender iron
#

@mortal kernel I've never done JTAG on ESP. I think Jeff did manage to. I usually do printf debugging. DEBUG=1 on the make command will start the ESP_LOGing

mortal kernel
lone sandalBOT
zinc walrus
#

(btw if any CircuitPython dev wants a pico8enc PCB mailed to them, let me know)

@devout jolt Can the pico8enc PCB have the Pico temporarily attached via headers, or does it have to be directly castellated soldered permanently?

onyx hinge
#

bin/start-stub-metros2:exec $HOME/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/bin/openocd -f $HOME/esp32s2-metro-jlink.cfg -c "gdb_port 2331" I may have also debugged the metro s2 with a jlink & openocd

mortal kernel
#

One more quick question, which version of ESP-IDF are we using?

tulip sleet
#

if you go into the esp-idf submodule, you should be able to see that tag in git log at the top

mortal kernel
manic glacierBOT
tulip sleet
manic glacierBOT
mortal kernel
#

I'm having a touch of trouble building an Espressif board. Here's what I'm seeing:

(.venv) β†ͺ make BOARD=adafruit_feather_esp32s3_4mbflash_2mbpsram -j16
- Verbosity options: any combination of "steps commands rules", as `make V=...` or env var BUILD_VERBOSE
-- Building ESP-IDF components for target esp32s3
-- Checking Python dependencies...
Python requirements are satisfied.
Constraint file: /home/rabeles/.espressif/espidf.constraints.v5.3.txt
Requirement files:
 - /home/rabeles/Development/cp-development/issue-10004/cp-repo-issue-10004/ports/espressif/esp-idf/tools/requirements/requirements.core.txt
Python being checked: /home/rabeles/.espressif/python_env/idf5.3_py3.11_env/bin/python
CMake Error at esp-idf/tools/cmake/build.cmake:552 (message):
  
  /home/rabeles/Development/cp-development/issue-10004/cp-repo-issue-10004/.venv/bin/python:
  Error while finding module specification for
  'idf_component_manager.prepare_components' (ModuleNotFoundError: No module
  named 'idf_component_manager')

Call Stack (most recent call first):
  esp-idf/tools/cmake/project.cmake:710 (idf_build_process)
  CMakeLists.txt:12 (project)


-- Configuring incomplete, errors occurred!
tulip sleet
#

export.sh sets up its own venv

#

also you need to do esp-idf/install.sh first

mortal kernel
#

I'm starting again with a fresh repo clone. It's been a while since I built for Espressif, and I see that I should not have used my own venv. Ooops.

tulip sleet
#

also don' forget make fetch-all-submodules at the top level or make fetch-port-submodules at ports/espressif

#

oh also install python packages...

mortal kernel
#

No worries. I'm toying with the idea of putting the entire Espressif process into a Docker container. It doesn't seem to play well with my installation.

mortal kernel
#

Here's what I wrote the last time:

# There are version conflicts between the ESP-IDF and CP Python package
# requirements. We enter the ESP-IDF virtualenv, install CP requirements,
# and then re-run the install script to force version requirements to follow
# the ESP-IDF requirements. Effective while the ESP-IDF virtualenv is active.
#

For a Docker container it looks like this:

RUN cd ${CPBUILDENV_USER_HOME}/temp-cp-repo/ports/espressif && \
    source esp-idf/export.sh && \
    cd ../.. && \
    pip install --upgrade -r requirements-dev.txt && \
    pip install --upgrade -r requirements-doc.txt && \
    cd ports/espressif && \
    esp-idf/install.sh
mortal kernel
mortal kernel
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.4 on 2025-01-29; Waveshare ESP32-S3-GEEK with ESP32S3

Code/REPL

import os
import board
import sdioio
import storage
import bitbangio

CMD_PIN = 35
CLK_PIN = 36
D0_PIN  = 37
SD_SLOT_WIDTH = 1

# example 1
spi = bitbangio.SPI(board.GP36, board.GP35, board.GP37) # always fails
cs = digitalio.DigitalInOut(board.DAT3)
sd = adafruit_sdcard.SDCard(spi, cs) 

# example 2 (always fails)
sd = sdioio.SDCar...
manic glacierBOT
#

There is a default SPI object defined for this board on GPIO35 to 37
https://github.com/adafruit/circuitpython/blob/a0b482c2806ac19962ed26f2d4bbe5ebdef3406a/ports/espressif/boards/waveshare_esp32_s3_geek/pins.c#L67-L69

If you want to use the sd card over SPI, with the sdcardio module, calling it like this sd = sdcardio.SDCard(board.SPI(), board.SD_CS) should work.

Based on the board schematic, the SDIO interface is available too, so `sd = sdioio.SDCard(clock=board.GP36, command=board.G...

#

Hi, I looked at the board definition and there seems to be mistakes in there: it instantiates the SPI bus of the SD card (also defined as board.SPI) to use the display, despite the display being on a different SPI bus according to pins.c.
I don't have the board to test, can you check the following ?

    1. Does the display show anything when the board is running ?
    1. Try this code:
spi = board.SD_SPI()
cs = digitalio.DigitalInOut(board.SD_CS)
sd = adafruit_sdcard.SDCard(spi, cs)
vfs =...
manic glacierBOT
#

hello,

i've tried the code the error now is:

`Adafruit CircuitPython 9.2.4 on 2025-01-29; Waveshare ESP32-S3-GEEK with ESP32S3
Board ID:waveshare_esp32_s3_geek
UID:C34872620D8B
boot.py output:
Traceback (most recent call last):
File "boot.py", line 19, in <module>
File "adafruit_sdcard.py", line 112, in init
File "adafruit_sdcard.py", line 130, in _init_card
File "adafruit_sdcard.py", line 252, in _cmd
File "adafruit_sdcard.py", line 205, in _wait_for_ready
ValueError: No miso...

manic glacierBOT
#

Adafruit CircuitPython 9.2.4 on 2025-01-29; Waveshare ESP32-S3-GEEK with ESP32S3 Board ID:waveshare_esp32_s3_geek UID:C34872620D8B boot.py output: Traceback (most recent call last): File "boot.py", line 19, in <module> File "adafruit_sdcard.py", line 112, in __init__ File "adafruit_sdcard.py", line 130, in _init_card File "adafruit_sdcard.py", line 252, in _cmd File "adafruit_sdcard.py", line 205, in _wait_for_ready ValueError: No miso pin

Oh yeah that would actually not work...
The iss...

#

lwip configuration macro MDNS_MAX_SERVICES not specified for raspberrypi port, so it was defaulting to 1. Increased to 25, the value specified in the espressif port. Results:

os.uname()=(sysname='rp2040', nodename='rp2040', release='9.2.5', version='9.2.5-11-ga0b482c280-dirt)
microcontroller.cpu.reset_reason=microcontroller.ResetReason.SOFTWARE
os.getenv("CIRCUITPY_WEB_API_PASSWORD")=jk
http://slots-code-py.local.:8086 starting...
http://slots-code-py.local.:8088 starting...
Done....
#
jaunty juniper
#

@wraith crow is the SDIO error after a power cycle or after running the SPI code ? Can an SD card switch from SPI mode back to SDIO on the fly ?

wraith crow
#

I'll double check

#

Good call, it mounts fine using SDIO after a power cycle 😁

manic glacierBOT
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.4-310-gca0eec3f1a on 2025-03-11; Adafruit Feather ESP32-S3 Reverse TFT with ESP32S3

Code/REPL

# Actually boot.py, not code.py
import storage
storage.remount("/",False)

Behavior

Adafruit CircuitPython 9.2.4-310-gca0eec3f1a on 2025-03-11; Adafruit Feather ESP32-S3 Reverse TFT with ESP32S3
Board ID:adafruit_feather_esp32s3_reverse_tft
UID:0740D1DC2800
boot.py output:
Traceback (most r...
mortal kernel
#

@danh Is there a mechanism for merging 9.2.x PRs into 10? I'm assuming it will get done manually.

manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

I have been able to cause safemode crashes accessing the automounted SD cards. I've been try reduce the code needed to reproduce and this is what I currently have as code.py:

import sdioio
import board
import storage,os

sd = sdioio.SDCard(clock=board.GP36,command=board.GP35,data=[board.GP37, board.GP33, board.GP38, board.GP34],frequency=25000000)
vfs=storage.VfsFat(sd)
storage.mount(vfs,'/sd')
os.chdir('/sd')

while True:
    tFSize = 0
    nFiles = 0
    nDirs = 2
    p...
manic glacierBOT
manic glacierBOT
#

I assume this isn't actually supposed to automatically mount the SD card to CircuitPython but when an SD card is mounted it "automounts" the cards to the host computer. That's what I'm seeing anyway.

On the sparkfun thingplus RP2040 (no display) the automount to the Host PC does occur, but it takes considerably longer than the S3 board. I was also unable to get the code.py (slightly altered to use sdcardio and busio) to cause the crash, although with the code.py running, the mount to the h...

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

🀦 I made 9.2.6 off of main instead of 9.2.x by mistake. It was early enough that I deleted the tag and stopped the release process, and re-did it properly. If it had been longer, I would have just skipped 9.2.6.

EDIT: This was not such a good idea, because the stubs had already been uploaded to PyPi, and PyPi doesn't let you replace a file.

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.5 on 2025-03-19; M5Stack Atom Echo with ESP32
Board ID:m5stack_atom_echo
UID:052019F95D04

Code/REPL

import wifi
wifi.radio.listen_interval = -1

Behavior

code.py output:
Traceback (most recent call last):
  File "code.py", line 42, in 
AttributeError: can't set attribute 'listen_interval'

Description

I'm trying to disable wifi power savings, which seems to improve r...

tulip sleet
manic glacierBOT
#

I looked at this, and found that listen_interval had not been added to the Radio class dictionary. When I added this:

+    { MP_ROM_QSTR(MP_QSTR_listen_interval),    MP_ROM_PTR(&wifi_radio_listen_interval_obj) },

it showed up.

@EternityForest (author of #9476) not sure how we all missed that, but no one else had tried to use it.

I wonder if we should see if the RP2 WiFi impl has some power-saving implementation that is similar, and maybe come up with a more general API that woul...

manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.6 on 2025-03-23; Waveshare RP2040-Zero with rp2040

Code/REPL

import time
import board
import busio
import adafruit_sht31d

Behavior

Adafruit CircuitPython 9.2.6 on 2025-03-23; Waveshare RP2040-Zero with rp2040

soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Traceback (most recent call last):
**File "code.py", line 15...

manic glacierBOT
#

CircuitPython version and board name

- CPY >= 9.0.0
- same54_xplained

Code/REPL

Not applicable

Behavior

Not applicable

Description

CPY stucks in file system initialisation when built with GCC14.
The same code works fine if it is compiled with GCC10;

Tried the tag 9.0.0;

Here is the back trace of problematic code. Currently no idea what exactly goes wrong here.
`
#0 0x00060e98 in memcpy (dst=dst@entry=0x2003fb1c, src=src@entry=0x4000000, n=...

manic glacierBOT
#

The same issue is observed with CPY 9.2.6;

I had to apply the patch below first:

diff --git a/samd/dma.c b/samd/dma.c
index 4925942..50a2cdb 100644
--- a/samd/dma.c
+++ b/samd/dma.c
@@ -64,9 +64,12 @@ uint8_t dma_allocate_channel(bool audio_channel) {
 }
 
 void dma_free_channel(uint8_t channel) {
-    assert(dma_allocated[channel]);
-    dma_disable_channel(channel);
-    dma_allocated[channel] = false;
+    if (dma_allocated[channel]) {
+        dma_disable_channel(channel);
+   ...
manic glacierBOT
#

So maybe dma_free_channel() is being called when the channel is already freed? We don't know whether the assertion is failing or not, but I think the assertion may be suppressed when not doing a debug build. We'll need to study the code to see whether dma_free_channel() should be idempotent or not.

Another possibility, but maybe less likely in this case.
This kind of problem in the past has been due to something not being volatile or to not putting something in a critical sectin.

In `...

manic glacierBOT
#

So maybe dma_free_channel() is being called when the channel is already freed?

It does assert during the initialisation when built with DEBUG=1.

How did you arrrive at that patch?
This was the reason for my patch.
But this is only the case with latest 9.2.x (namely 9.2.6);

#0  __assert_func (file=<optimized out>, line=<optimized out>, func=<optimized out>, expr=<optimized out>) at ../../main.c:1205
#1  0x000263e4 in dma_free_channel (channel=<optimized out>) at peripherals/samd...
#

I am not seeing this problem. I tested on a QT Py RP2040, with both CircuitPython 9.2.3 and 9.2.6. My test program is simpler:

import time
import board
import busio
import adafruit_sht31d

#i2c = busio.I2C(board.GP29, board.GP28)
i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a microcontroller
sensor = adafruit_sht31d.SHT31D(i2c)

while True:
    print(sensor.temperature)
    time.sleep(1)

I am suspicious that there may be some corruption of the .mpy file...

#

@EmergReanimator CircuitPython is built and tested with the GCC 13.3.Rel1 toolchain found here: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads. This toolchain includes patches specific to ARM cores. Is this the source of the toolchain you are using?

I have used arm-none-eabi-gcc (Fedora 14.1.0-2.fc41) 14.1.0 by default (GCC14).

I have just tried the ARM GCC 13.3 and CPY 9.2.6 without success. The CPY hangs in filesystem_init:

...
#

Here is the short summary of my results.
Unfortunately I could not get CPY 9.0.0 running any more.

ARM GCC10 ARM GCC13 GCC14
8.0.0 :white_check_mark: :no_entry: :no_entry:
9.0.0 :exclamation: :x: :x:
9.2.6 :no_entry: :x: :x:

:exclamation: - unstable, succeeded just once
:x: - hangs in filesystem initialisation
:no_entry: - build failure


  • arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10) 10.3.1 20210824 (release)
  • a...
manic glacierBOT
#

FYI

CPY 9.0.0 runs fine with FS stubs built with GCC 14:
Adafruit CircuitPython 9.0.0-dirty on 2025-03-23; SAM E54 Xplained Pro with same54p20

diff --git a/ports/atmel-samd/boards/same54_xplained/mpconfigboard.mk b/ports/atmel-samd/boards/same54_xplained/mpconfigboard.mk
index d5038030e4..7263398e37 100644
--- a/ports/atmel-samd/boards/same54_xplained/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/same54_xplained/mpconfigboard.mk
@@ -6,9 +6,12 @@ USB_MANUFACTURER = "Microchip"
...
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

I just wanted to check if there was any memory impact, and it's <1KB for 25 slots. Haven't (yet) tried running services on all of those slots. Thanks, eightycc!
<details>
<summary>code.py.</summary>

# Adafruit CircuitPython 9.2.6 on 2025-03-23; Pimoroni Pico Plus 2 W with rp2350b
import time
import os
import gc
import random
import traceback
import microcontroller
import wifi
import mdns

BASE_PORT = 8000
NUM_SLOTS = 26  # up to 25 supported, RuntimeError: Out of MDNS service slots on ...
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.6 on 2025-03-23; Raspberry Pi Pico 2 with rp2350a
Board ID:raspberry_pi_pico2

same issue when using Pi Pico rp2040

Code/REPL

# sample code and mp3 from https://learn.adafruit.com/mp3-playback-rp2040/pico-i2s-mp3
#
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
CircuitPython I2S MP3 playback example.
Plays a single MP3 once.
"""
import ...
mortal kernel
#

I'm attempting to build CP with DEBUG=1 for an Espressif ESP32-S3 and getting a "Too little flash!!!" message:

Memory region         Used Size  Region Size  %age Used
     iram0_0_seg:      107776 B     358144 B     30.09%
     iram0_2_seg:     1203530 B    8388576 B     14.35%
     dram0_0_seg:      169640 B     341760 B     49.64%
     drom0_0_seg:     1585949 B   33554400 B      4.73%
    rtc_iram_seg:        4360 B       8168 B     53.38%
rtc_reserved_seg:          24 B         24 B    100.00%
    rtc_slow_seg:          0 GB         16 B      0.00%
  extern_ram_seg:     1638368 B   33554400 B      4.88%
esptool.py v4.8.1
Creating esp32s3 image...
Merged 3 ELF sections
Successfully created esp32s3 image.

1669856 bytes used, -228064 bytes free in flash firmware space out of 1441792 bytes (1408.0kB).
   4384 bytes used,    3808 bytes free in 'RTC Fast Memory' out of 8192 bytes (8.0kB).
      0 bytes used,    8192 bytes free in 'RTC Slow Memory' out of 8192 bytes (8.0kB).
  16383 bytes used,   16385 bytes free in 'Internal SRAM 0' out of 32768 bytes (32.0kB).
 169640 bytes used,  256344 bytes free in 'Internal SRAM 1' out of 425984 bytes (416.0kB).
      0 bytes used,   65536 bytes free in 'Internal SRAM 2' out of 65536 bytes (64.0kB).

Too little flash!!!
#

Any hints will be appreciatedπŸ™

jaunty juniper
#

you gotta disable some modules to make space

#

I believe it fits with bigger flash if you can use that for debugging

#

like with 8MB+ flash the partition for CP is 2MB instead of 1.4

mortal kernel
#

Been using a Feather w/4MB. I've got a larger Metro around here somewhere...

mortal kernel
manic glacierBOT
#

CircuitPython version and board name

Adafruit CircuitPython 9.2.6 on 2025-03-23; Adafruit Fruit Jam with rp2350b

Code/REPL

from displayio import Group
import supervisor

print("hello world")

main_group = Group()
display = supervisor.runtime.display

display.root_group = main_group

while True:
    pass

Behavior

As I'm working on the Fruit Jam animation (https://github.com/FoamyGuy/Adafruit_CircuitPython_FruitJam_Animation) I'm noticing that when t...

tulip sleet
manic glacierBOT
onyx hinge
#

does that mean there are around 600 * 21 = 21600 build artifacts from each build?

tulip sleet
#

I think there are not 21 active languages, but there might be 18.

onyx hinge
#

oh that's a lot better πŸ™‚

#

😊 I'll be blushing during hug reports today

#

oooh thank you neradoc! that's a cool feature that I have wished for.

jaunty juniper
#

yeah me too πŸ™‚

onyx hinge
#

also y'all are all so smart

lone axle
#

😺

#

Thanks for hosting dan. Have a great week everyone!

thorny jay
#

Thank you Danh.

onyx hinge
#

i was told there would be cake at this retirement party

mortal kernel
#

Thanks Dan!

manic glacierBOT
manic glacierBOT
#

I tried this out, unfortunately the animation code runs out of RAM when I use a build with PSRAM disabled.

There is one version that loads the spritesheets into RAM and it runs out during the load of those sheets:

Traceback (most recent call last):
  File "code.py", line 217, in <module>
  File "adafruit_imageload/__init__.py", line 75, in load
  File "adafruit_imageload/bmp/__init__.py", line 96, in load
  File "adafruit_imageload/bmp/indexed.py", line 85, in load
MemoryError: memory a...
manic glacierBOT
jaunty juniper
#

@tulip sleet I was looking at my CDC issue of not being able to read the buffer when nothing is connected, and realized that the fix that caused that checked if a client is connected, when it probably meant to check if USB is connected (tud_ready).
https://github.com/adafruit/circuitpython/pull/7100
But, when trying to revert the change to compare to the original issue, I believe the problem of accessing CDC before it's ready is now fixed in tinyUSB itself:
https://github.com/hathach/tinyusb/pull/2630
so I don't know if I should make a PR changing the test in CP using tud_ready or tud_cdc_n_ready (which includes tud_ready, so it seems to be a better one) or just revert 7100 since tinyusb takes care of it

tulip sleet
# jaunty juniper <@329766224093249548> I was looking at my CDC issue of not being able to read th...
bool tud_cdc_n_ready(uint8_t itf) {
  return tud_ready() && _cdcd_itf[itf].ep_in != 0 && _cdcd_itf[itf].ep_out != 0;
}

bool tud_cdc_n_connected(uint8_t itf) {
  // DTR (bit 0) active  is considered as connected
  return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0);
}

it looked likes "ready" is less strict than "connected"?

I'd say you could try to revert #7100, but then test whether you can reproduce the bug reported in #6108.

jaunty juniper
#

I couldn't reproduce it so far, maybe be I could test an old version of CP where the issue happens to make sure I get it to happen with what I'm doing

manic glacierBOT
manic glacierBOT
orchid basinBOT
manic glacierBOT
#

This is a fix for the issue I mentioned all the way here: https://github.com/adafruit/circuitpython/issues/7456#issuecomment-1383495476

The issue mentioned in #6018 is now fixed in tinyusb: https://github.com/hathach/tinyusb/pull/2630

The original solution in #7100 caused the buffer to contain inaccessible data, requiring a serial software on the host to be connected to be able to read the buffer (asserting DTR). Another solution would be to test tud_ready() or tud_cdc_n_ready() ins...

orchid basinBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
short tendon
#

@lone axle when you have a moment, I have another secrets.py question. For Macropad_2FA_TOTP the code has the user add multiple totp_keys to secrets - as a list, which os.getenv doesn't support. I see 2 options:

  1. do something like: name|code|color,name|code|color and then break it apart in code
  2. create a secrets.json that we load instead.
    Thoughts?
GitHub

Programs and scripts to display "inline" in Adafruit Learning System guides - adafruit/Adafruit_Learning_System_Guides

lone axle
#

As a longer term solution maybe some day we can support toml arrays or whatever this grouping syntax is from the wikipedia TOML example:

[servers]
  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"
manic glacierBOT
manic glacierBOT
#

@jepler 's suggestion desk checks. quad_enable_status_byte = 2 causes single_status_byte = false after the .toml is ninja'ed, which is exactly what we want.

The only crunchy bit is in supervisor_flash_init():https://github.com/adafruit/circuitpython/blob/a0b482c2806ac19962ed26f2d4bbe5ebdef3406a/supervisor/shared/external_flash/external_flash.c#L238-L248
Here we'll read the configuration register at lines 245-246 and test the WPEN (Write Protection Pin Enable). This should always b...

manic glacierBOT
short tendon
manic glacierBOT
wheat siren
#

I'm looking to add this as a Board (ESP32-WROOM-D) - would it be worth me making a PR? Or is it likely to be too niche (I can keep a fork and run the GitHub Action on there).

manic glacierBOT
#

@EmergReanimator Diff'ing the 8.1.0 and 8.2.0 tags I see the SST26VF064B was added to the list of possible flash parts. What is the flash part # on your board?

I have got a SAME54 Xplained board with 26F064B flash.

@EmergReanimator Please make the change noted above by @jepler to data/nvm.toml/flash/microchip/SST26VF064B.toml and re-test. I'm assuming you've got a board stuffed wit...

tulip sleet
# wheat siren

It's pretty niche, especially since you don't know the details of the board yet. By using a generic ESP32-WROOM board, you'll be able to reference all the pins, etc.

wheat siren
#

I need to check if the flash sizes are the same between the existing WROOM-E and this one

tulip sleet
wheat siren
#

Ah that's good to know.
Image with a smaller specified size than the actual flash should work, but not vice versa?

tulip sleet
last condor
#

hiya, was hoping to hear from some contributors, how difficult is it to port a new board to circuitpython? i've seen (and come into possession of) these generic unbranded ESP32-C3 modules with a tiny 0.42inch OLED, and it seems through some tinkering that they don't differ much from the 01space esp32-c3 oled (mostly in the pinouts and the oled screen driver being sh1106 instead of ssd1306)

stuck elbow
#

it's not hard at all if there is a similar board already

last condor
#

ah, fantastic! thank you very much. since there is no manufacturer listed... well, anywhere i assume the naming convention for this board would be something akin to generic_oled042_esp32c3 ?

stuck elbow
last condor
#

ok, thank you very much for the information

#

actually, this board doesn't seem to support native usb, since everything has to go over the web workflow, would that mean i'd be using the creator/creation id system instead of a vid/pid?

last condor
#

alright perfect. thanks for the help :)

jaunty juniper
last condor
#

the board seems near identical in functionality to the 01space 0.42inch lcd esp32c3, just with a slightly different pinout and display driver (although rather amusingly, the sh1106 and sd1306 drivers are similar enough that a small row of pixels does in fact render in the center) so it could possibly be a subset of that design? but then again it's not officially from them

jaunty juniper
last condor
#

it seems i've raised up a lil dilemma πŸ˜…

jaunty juniper
#

just a legitimate question

tulip sleet
#

These generic boards can vary slightly from one another, and we end up with an plethora of boards that can't be readily identified.

#

If there seems to be a trend among generic boards to be the same (e.g. the "yellow display") we could make up a generic definition, but minor variations blow up the board space.

#

This is my opinion, not necessarily policy

#

I do think we should define some explicitly generic boards and encourage people to use those. For boards with displays the issue is whether it's worth defining the display in board.c for ease of use

last condor
#

most if not all of these small integrated display boards ive found seem to be either ssd1306 or sh1106 (which are very similar regardless) so in this case it could be something like generic_oled042_esp32c3 and/or generic_oled042_sh1106_esp32c3 ? (as an example for the device name itself), it does seem a little long winded though

#

e.g., through digging around i found only one other generic variant that advertises itself as using an ssd1306 display and also has a pin to directly connect a 3.7v battery, but it does seem like these generic boards are a little difficult to pin down and define

jaunty juniper
#

I don't think we need to multiply board defs for board.DISPLAY, and maybe future developments around supervisor.runtime.display or something will make it easier to define the display once in boot.py and keep it alive, but accessible from code.py without having to release_displays and redefine it

#

that reminds me that I have the RP2040 and ESP32S3 variants of the 01space .42 inch board, but they don't have pull ups on the I2C and I can't make the display work in CP so I gave up on them

last condor
#

realistically it does seem that it is similar enough that i can simply re-define pins (e.g., real_SCL = board.IO5 wherever i need to open the display), so a whole new port might not entirely be necessary
in fact that's precisely what i'm doing since i'm using one of these in ""production"" (small plant soil moisture monitor)

#

maybe there could be a place to document little quirks of these generic boards and how to "map" some of them to existing ports?

last condor
jaunty juniper
#

oh that does work

#

it was CP 8.1 at the time too, maybe I should revisit them

last condor
#

either way, i'd love to hear what the official consensus on these generic boards will be as i do have about 7 of this one laying around that i use for various wifi-connected projects, i'll keep an eye out on the creatorid/creations repo in case any discussions happen there

manic glacierBOT
manic glacierBOT
orchid basinBOT
sterile anvil
#

The WIZnet W5500-EVB-Pico2 board doesn't currently have an official CircuitPython build, so I've been using a custom build based on the W5100s-EVB-Pico2. (It's virtually identical aside from the USB PID and the WIZnet ethernet chip itself.) Given that I don't work for WIZnet and I'm not the designer/developer of the board, can I still submit a pull request to get it added to CP?

onyx hinge
#

@sterile anvil yes, many people do that.

sterile anvil
#

Perfect, thanks - I'll submit a PR then!

onyx hinge
#

thank you!

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

While testing a fix for #10003, I discovered that the left and right channel DAC audio output on ESP32-S2 would swap randomly on play. It turns out this is known upstream problem: https://github.com/espressif/esp-idf/issues/11425. The only workaround that worked for me was to entirely reset AudioOut on each play.

I'll include the workaround in a PR, but leave this issue open so it can be removed in the future if and when the upstream bug is fixed.

@MarshallMiller: probably of interest to ...

#

Incorrect processor dependent includes in iobank0.h and platform_defs.h in StateMachine.c. This would keep RP2350 boards from using the 3rd PIO.

StateMachine.c:use_existing_program() storing return from SDK function pio_claim_unused_sm() in unsigned int but later testing for <=0. Fixing this uncovers another bug where common_hal_rotaryio_incrementalencoder_deinit() causes an SDK assert after 9th IncrementalEncoder constructor fails.

orchid basinBOT
manic glacierBOT
#

The Pico SDK has headers common to the RP2040 and RP2350 as well as headers specific to these processors. In some cases, CP RP2 port code includes RP2040-specific headers unconditionally. For example, common_hal/rp2pio/StateMachine.c included src/rp2040/hardware_regs/include/hardware/platform_defs.h causing it to miss the third PIO available on the RP2350.

RP2 port code needs to be examined for other instances of this problem.

short tendon
#

@lone axle how have the sizes been for the library PRs? The next batch will be P which has a bunch for PyPortal. Want to make sure any given PR isn't too much to tackle

lone axle
#

@short tendon The previous one (I haven't looked at the new one yet) is probably almost to the biggest size that I'd want to do in one sitting. Much bigger than that and I'd want to probably take a break and do something different for while part way through the guide page updates, so it may split up into morning/afternoon or across two days depending on what else is on my plate.

short tendon
#

Okay. I think the next one might be a little bigger, but part of that is that it's almost all MagTag. I'll split the next one

manic glacierBOT
#
  • Fixes #10003.
  • Workaround for #10180.

Stumbled on https://github.com/espressif/esp-idf/issues/11425 bug while testing. It causes the left and right channels to be swapped randomly on play, which was very confusing. Worked around by forcing a deinit/init on each play.

I also got confused because board.A0 and board.A1 are not consistently assigned to left/right channels. Added a documentation warning about this.

Shuffled code around a little in `ports/espressif/common-hal/audioio/A...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

Tested on a W5100S-EVB-Pico2 (the WIZnet library handles the difference in the chips). Looks good operationally.

Looks like I made a couple of mistakes in the W5100S-EVB-Pico2 PR (not sure if we change those now as it may break user code). The WIZnet PRs for the original Pico W5100s and W5500 do not have default UART, I2C, or SPI Singletons. However, WIZnet docs (arguably) show a preferred UART on GP0 and GP1 (peripheral 0),...

onyx hinge
#

@mortal kernel do you have a firm handle on the PIO bug{,s} or is there any assistance I can offer?

manic glacierBOT
#

Now working as expected, throwing "All state machines in use" on 9th constructor:

setup encoders
Encoder at board.GP2, board.GP3
Encoder at board.GP4, board.GP5
Encoder at board.GP6, board.GP7
Encoder at board.GP8, board.GP9
Encoder at board.GP10, board.GP11
Encoder at board.GP12, board.GP13
Encoder at board.GP14, board.GP15
Encoder at board.GP16, board.GP17
Encoder at board.GP18, board.GP19
Traceback (most recent call last):
  File "code.py", line 25, in <module>
RuntimeError: All state...
mortal kernel
onyx hinge
#

hah the mp3 bug was also a signedness bug.

#

maybe java was right to not have unsigned types at all

jaunty juniper
#

all signs seem to point to it

#

(sorry)

mortal kernel
#

πŸ˜†

stuck elbow