#circuitpython-dev

1 messages · Page 79 of 1

manic glacierBOT
#

The cardputer is already an implemented board, so I'm fine with the removal of the commented code, though the concept of auto-detecting the display is not at all a bad idea. I'm afraid I don't have the coding knowledge to edit board.c to implement that detection and adjustment myself. If you or someone else is able to write the implementation, I'm more than happy to figure out what pins are pulled in what direction by the presence of the LCD, but otherwise removal of the commented code is pro...

tulip sleet
#

@slender iron do you have a few minutes for tinyusb q's?

slender iron
#

yup!

onyx hinge
#

@lone axle I can grab the blinka section if you want

turbid radish
#

☺️

#

@anneb on Bluesky

#

@circuitpython on BlueSky

onyx hinge
turbid radish
#

Nearly 12,000 subscribers worldwide

#

Yes, I rely on everyone to find good content for the community

onyx hinge
#

would love to hear more about the plexiglass / acrylic hand techniques, I've done VERY bad jobs the few time I've tried it myself (cutting, not even bending)

errant grail
onyx hinge
#

Thank you @lone axle for hosting the meeting. Happy to catch up with everyone!

errant grail
#

Thanks @lone axle !

uncut nexus
#

@tulip sleet Do you know what chip(s) Adafruit plans to use for Matter boards?

onyx hinge
#

@errant grail I'll look forward to probably seeing in the newsletter in that case!

lone axle
#

Thanks everyone, have a great week.

tulip sleet
uncut nexus
#

Thanks!

slender iron
#

(matter over wifi not thread)

lone axle
#

Thank you! I've got it on my list to over. I've got a few other items ahead of it, but be able to in the coming days.

manic glacierBOT
#

I agree we should submodule somehow - microros-ext is sourced from https://github.com/micro-ROS/micro_ros_espidf_component, which I avoided including directly due to the additional requirements in the idf virtual environment, pip3 install catkin_pkg lark-parser colcon-common-extensions empy==3.3.4, and the extended build process caused by colcon fetching all the message type packages. I didn't want them clogging up Circuitpython's CI process, but @dhalbert suggested it might not be a bi...

orchid basinBOT
lone axle
#

Here is the notes document for next Tuesday’s CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern here on Discord, but is on Tuesday instead of Monday. 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/1BTOyxonN09KjzL7GsxcN7HMlbOn4yzkcDvRoX4l-op0/edit?usp=sharing

lone axle
#

I should have thought to ask about this in the weeds, but it slipped my mind.

Has anyone else received an email from a supply chain risk manager at NASA about the library bundle repo?

I received this the other day and then a second message following up on it from the same sender today.

Would there be a good person or place to direct this individual to for the information they're interested in about the bundle?

tulip sleet
stuck elbow
#

nasa is using circuitpython?

wraith crow
#

The ability for auditors to generate work always amazes me....

solar whale
#

"Ground Support Equipment" -- not in flight

orchid basinBOT
slender iron
manic glacierBOT
#

I think it's safe to close this one. Writing to small drives/CIRCUITPY is working fine in macOS 15.2. I can't say what's happening under the covers, but writes feel responsive and reasonably fast now.

I've been running developer releases so I can't say when this really started working correctly, but the final release of 15.2 works well.
<img width="746" alt="Screenshot 2025-01-13 at 5 11 51 PM" src="https://github.com/user-attachments/assets/d1ea8869-2713-4594-a62c-438f74063ef7" />

manic glacierBOT
tiny peak
#

tannewt, I wrote up a playground guide walking through how to run the Zephyr shell with QT Py ESP32-S3 over either USB serial or BLE NUS with the Bluefruit Connect app. It takes a patch to get the BLE thing building, but it's an easy two-line fix.

manic glacierBOT
#

When we switched to the PEP 440 compatible version number "0.0.0+auto.0" instead of "0.0.0-auto.0" we didn't update the preprocess script for frozen modules, so they have been having a wrong version number ever since. Sorry :D
This PR fixes that.

before

Adafruit CircuitPython 9.2.2 on 2025-01-09; Adafruit PyPortal with samd51j20
>>> import adafruit_fakerequests
>>> adafruit_fakerequests.__version__
'0.0.0+auto.0'
...
jaunty juniper
#

(the frozen libraries versions have only been wrong for I assume 2 and a half year without anyone noticing, it's not an emergency 😄 )

tulip sleet
#

@lone axle did you see those emails from readthedocs about missing sphinx.configuration in the Bundle doc build?

lone axle
tulip sleet
lone axle
tulip sleet
#

that's the only one I got, but I'll forward any further ones.

lone axle
#

@tulip sleet I opened https://github.com/adafruit/Adafruit_CircuitPython_Bundle/pull/489 to add that configuration to the bundle. However I do think we'll need to patch the rest of the libraries as well.

I'm not sure why the others haven't generated similar warning messages to be sent, but we don't have that config in our yaml for libraries either. I found this failed build for the same reason https://app.readthedocs.org/projects/adafruit-circuitpython-mpu6050/builds/26830865/ on a library that had a release made very recently. Strangely it currently has "stable" that is newer than "latest" which I don't understand. But I think our banner tag in the readme files points to latest so it shows green even though the most recent stable build failed.

manic glacierBOT
tulip sleet
#

also the Project bundle is named examples.zip; I don't remember that being the case.

lone axle
lone axle
# tulip sleet <@382939733107408897> I stumbled on this while looking for something else. The `...

I've opened https://github.com/circuitpython/CircuitPython_Library_Screenshot_Maker/pull/29 that fixes the esp32spi_simpletest.py screenshot by adding filtering on the subdirectory files. We already filtered main directory files down to a list of shown filetypes, the subdirectories weren't filtered previously though so gpio and it's files got included in screenshots for anything inside of esp32spi/examples/

manic glacierBOT
manic glacierBOT
#

It does not work.
It clic "continue" after choosing the port and connecting, but this next steps goes super fast, not like my other flash with other ESP32 boards, and it indeed does nothing, the firmware is not changed.

However, I was able to flash the https://circuitpython.org/board/espressif_esp32_devkitc_v4_wroom_32e/ file with the flash tool here https://adafruit.github.io/Adafruit_WebSerial_ESPTool/ .

My board now boots with `Adafruit CircuitPython 9.2.2 on 2025-01-09; Espressif ...

jaunty juniper
#

@lone axle hey I have a question about the use of displayio with blinka (on a Pi computer or MCP2221). Can you display an image with adafruit_imageload ? I'm bumping into errors with adafruit_imageload on a BMP (one I can PR, another I don't understand yet), is it supposed to work ? (There might be versions shenanigans ?)

stuck elbow
#

I think on the raspberry pi blinka is using PIL for the images?

jaunty juniper
#

yeah is there a way to make a TileGrid from PIL for use with Adafruit_Blinka_Displayio ?

lone axle
#

The MCP2221 I am less sure about, I don't have specific experience with those expander breakouts. But if it's abstracted by Blinka I would expect it should work the same I think.

stuck elbow
#

but we are talking about displaying things on the monitor connected to the pi, not on an SPI display connected to the pins, right?

lone axle
#

I think PIL is or was used internally in Blinka_Displayio when it takes data from TileGrid / Bitmaps and sends it to the display.

#

I am talking about displaying things on a hardware display connected via SPI or I2C

stuck elbow
#

oh, I see

lone axle
jaunty juniper
#

ok I'll make a fix for one of the problems and open an issue for the other

manic glacierBOT
#

From this open issue https://github.com/adafruit/circuitpython/issues/5470 and discussions in the Adafruit discord server, it looks like the builds for the stm32H7 family have been broken for a while.

Based on my tests, it seems the problem is using the ITCM memory -- it generates a hard fault at runtime. Using the default code placement with no ITCM allows CircuitPython to run correctly.

I am still investigating what causes the hard fault -- help would be welcome -- but these changes...

lone axle
# jaunty juniper ok I'll make a fix for one of the problems and open an issue for the other

was this the other issue?

Traceback (most recent call last):
  File "/home/timc/Adafruit_CircuitPython_ILI9341/examples/imgtest.py", line 38, in <module>
    image, palette = adafruit_imageload.load(f"testimg.png")
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/timc/venv_blinka/lib/python3.11/site-packages/adafruit_imageload/__init__.py", line 92, in load
    return png.load(file, bitmap=bitmap, palette=palette)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/timc/venv_blinka/lib/python3.11/site-packages/adafruit_imageload/png.py", line 177, in load
    bmp[x, y] = pal.convert(
                ^^^^^^^^^^^^
  File "/home/timc/Adafruit_Blinka_Displayio/displayio/_colorconverter.py", line 173, in convert
    self._convert(self._output_colorspace, input_pixel, output_pixel)
  File "/home/timc/Adafruit_Blinka_Displayio/displayio/_colorconverter.py", line 198, in _convert
    rgb888_pixel.pixel = self._convert_pixel(
                         ^^^^^^^^^^^^^^^^^^^^
  File "/home/timc/Adafruit_Blinka_Displayio/displayio/_colorconverter.py", line 210, in _convert_pixel
    pixel = clamp(pixel, 0, 0xFFFFFFFF)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/timc/Adafruit_Blinka_Displayio/displayio/_helpers.py", line 27, in clamp
    return max(min(max_value, value), min_value)
               ^^^^^^^^^^^^^^^^^^^^^
TypeError: '<' not supported between instances of 'tuple' and 'int'
austere acorn
#

@lilac scaffold @strange ravine
https://github.com/adafruit/circuitpython/pull/9962
I created a PR with a fix for what I identified as the H7 problem -- with this, the latest CircuitPython runs on the open MV H7 camera.
Please let me know if it works with the builds for your boards as well.

strange ravine
#

yeeeeeeeeeeeeeeeeeeeaaaaaaaaahhhhhhhhh ill try it in a bit tysm

jaunty juniper
#

I also have crashes with adafruit_display_text if a Label goes off the display area now

#

the original reason I looked into that is somebody in help_with a few days ago noticed that adafruit_imageload can't do jpeg with blinka, because there's not jpegio. Is there a known way to make Tilegrid from say a PIL image for use with displayio, or maybe should jpegio be added to blinka or something ?

#

(once we fix the current state of things)

lone axle
# jaunty juniper the original reason I looked into that is somebody in help_with a few days ago n...

I would consider the addition of jpegio to blinka displayio the proper long-term solution. Ultimately it strives to be in parity with core displayio as far as I understand.

That said I do think it would be possible and fairly straight-forward on RPi to use PIL to load a jpg and then get it's data into a Bitmap object for use with TileGrid and Blinka displayio, but I don't know of any sample code that illustrates it.

jaunty juniper
#

yeah my solution would be to convert it to BMP with PIL on the fly and load the BMP, that seems like a good enough generic solution

manic glacierBOT
#

I don't understand the build stuff you are referring to.

Sorry, let me say that in a less confusing way. Compiling the MicroROS component installs a bunch of python package managers, is slow, and has a lot of verbose build output. To avoid adding that to Circuitpython's CI tests, I made a pre-compiled version, which is what I've included. I've recieved feedback already that that might be less easy to maintain, so I could revert back to including the original component as a submodule if y...

strange ravine
#

its working now, at least from what i can see

#

its getting late so ill do more tests tomorrow

manic glacierBOT
#

A set of improvements to the serial UART console.

  1. Corrects a crash or hang when a write is attempted to the serial UART console before it is initialized.
  2. Allow serial_early_init() to be called earlier in port initialization.
  3. Ensures that all lines written to the serial UART console are properly "cooked", i.e., line endings are translated to '\r\n'.
  4. Refactors serial UART console write routines.
  5. Adds an optional timestamp to serial UART console writes.
  6. Adds a macro t...
manic glacierBOT
#

This PR implements the alarm-module for the RP2350 variant of the pico and fixes #9491.

Notes

  • The PR does not use the new power-domains for the RP2350, but uses plain old sleep/dormant modes. An implementation based on powman is something for a future PR.
  • This PR also reimplements light-sleep/deep-sleep for the RP2040. As @dhalbert stated in #9521: "So redefining light sleep as RAM-preserving, but not activity-preserving, might be worthwhile". With this PR, light-sleep h...
lone axle
#

The patch for adding sphinx config to rtd.yaml file has been run. There were a few that failed actions afterward that I'll check in to. And there are 8 that didn't get patched because their config was newer and just slightly different enough that the patch didn't apply. I'll submit PRs to those instead of worrying about trying to patch them seperately.

It does bring up the question of a potential future patch though. In cookiecutter and the newest repos we use ubuntu-lts-latest inside of RTD build system. But in the older libraries they use ubuntu-20.04. It looks like April 2025 is the EoL for 20.04. The good news is moving to lts-latest means we shouldn't have to patch again in the future.

strange ravine
#

@austere acorn so ive tried circuitpython on 2 of my custom H7 boards and im getting, interesting results
on the first one it will work, kinda, the circuitpy drive takes a bit to load but is rather unstable, maybe its my computer.
on the second board it straight up doesnt work, unsure why.
ill keep testing

tulip sleet
strange ravine
#

no yeah its a problem with either circuitpython or my boards coz same happens when i try to use them on my main computer

lone axle
# tulip sleet I didn't know there was lts-latest -- that's not too much churn but still pretty...

I think their available options inside RTD are slightly different from actions at least. We use ubuntu-latest in the github actions containers I believe. I'm not sure if those end up on the same release cadence or not, but it will be nice to have them both onto some form of "latest" so that they're moving forward automatically even though it may mean we have to fix things for the new version occasionally.

tulip sleet
manic glacierBOT
#

Allow serial_early_init to be called earlier

Initializing the serial UART console earlier than its default can be useful when debugging inside a port-specific port_init(). Since serial_early_init() is not serially reusable, a guard is implemented that ignores additional calls to serial_early_init(). This guard also serves to prevent writing to an uninitialized UART. Here is an example from RP2's port_init():

    // Initialize RTC
    #if CIRCUITPY_RTC
    common_hal_...
manic glacierBOT
#

Thank you for adding these features, which will be very handy. I had one question about naming.

Often when I am debugging, I do not use CONSOLE_UART, but instead just use mp_printf(&mp_plat_print, ...), so that my print's are interspersed with prints from the CircuitPython program. I think I mentioned briefly about making a DEBUG_PRINTF-style macro that printed to &mp_plat_print. It would also be handy to do such logging with timestamps as well =, to &mp_plat_print.

The above coul...

lone axle
#

It seems like Github may be experimenting with or rolling out a new "sub-issue" feature. Never seen this in the UI before that I can recall

manic glacierBOT
#

Often when I am debugging, I do not use CONSOLE_UART, but instead just use mp_printf(&mp_plat_print, ...), so that my print's are interspersed with prints from the CircuitPython program. I think I mentioned briefly about making a DEBUG_PRINTF-style macro that printed to &mp_plat_print. It would also be handy to do such logging with timestamps as well =, to &mp_plat_print.

The macro wraps mp_printf() so it does intersperse with plain old console output sent to the serial UART. Likewise,...

tulip sleet
#

@mortal kernel re your PR, let's do a more interactive conversation about this.

shut copper
lone axle
manic glacierBOT
#

I'd just like to comment that this looks awesome, having ROS on CircuitPython could open up lots of opportunities. I'm currently thinking of making a CircuitPython sensor -> ROS factory utility class - so you could just set up your sensor, pass it into the class and it starts publishing on an appropriate topic - so an accelerometer+gyro would start publishing IMU messages for example.

manic glacierBOT
manic glacierBOT
orchid basinBOT
#

Hi, I believe you are talking about the installer on circuitpython.org
Here is a web version of esptool to install binaries, and a guide:
https://adafruit.github.io/Adafruit_WebSerial_ESPTool/
https://learn.adafruit.com/circuitpython-with-esp32-quick-start/web-serial-esptool

I'm not sure where it's linked to on the site. It is referenced when there's a UF2 bootloader section. Maybe we could link to it for ESP32 boards without a UF2 bootloader in particular, since it's the main way to install...

manic glacierBOT
#

This was one of my #circuitpython2025 requests. Filing a issue to track this.

Context:

  • Being an already power efficient board compared to the other dual core ESP boards(S3, S2 etc), I thing this board would benefit from a low power connectivity solution like zigbee, as wifi is a notoriously power hungry connectivity solution.
  • Adding zigbee support to the c6 would be very beneficial in battery powered use cases (for environmental mo...
manic glacierBOT
#

Hi!

Flashing adafruit-circuitpython-stm32f411ce_blackpill_with_flash-en_US-9.2.2.bin on a WeAct STM32F411CE BlackPill
(buyed on the official WeAct store on AliExpress) no CIRCUITPY folder appear and the MCU get stuck.

With adafruit-circuitpython-stm32f411ce_blackpill_with_flash-en_US-9.2.1.bin no problems, it works as expected.

On DFU-boot:
[mar dic 17 11:50:47 2024] usb 1-4: new full-speed USB device number 21 using xhci_hcd
[mar dic 17 11:50:47 2024] usb 1-4: New USB device found, i...

manic glacierBOT
manic glacierBOT
#

CircuitPython version

Adafruit CircuitPython 9.2.2 on 2025-01-09; Ai Thinker ESP32-CAM with ESP32

Code/REPL

import microcontroller
microcontroller.cpu.temperature

Behavior

Nothing happens. no output.

P.S.
It works in micropython.

The same happens with another ESP32 board I have.

In espruino it was removed and then re-added a couple of days ago:
https://github.com/espruino/Espruino/issues/2585

Description

No response

Additional in...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

@dhalbert great! I missed that! but using pulse io, how can I continuously get pulses (until there are no pulses for 10 seconds)?

What I need is an array of pulse lengths (possibly at 80Mhz or 160Mhz sampling rate/accuracy).

From the other end I receive pulses. I need to collect them all until there are no more pulses for a few seconds (end of transmission).

It's not clear how to do that from the docs.

manic glacierBOT
#

This functionality was removed from ESP-IDF some time ago due to not working well at all: https://github.com/espressif/esp-idf/issues/146. It was temprature_sens_read(). Yes, that was the actual spelling.

MicroPython returns the raw temperature reading by reading some registers. Due to the the inaccuracy and instability, I think we will skip that. It would be a support burden for us.

Re https://github.com/espruino/Espruino/issues/2585: it looks like it was put back for chips that support ...

tulip sleet
#

@slender iron @onyx hinge Thach gave me a fix for the 9.2.2 bug of ESP32-S3 not showing up on USB ports. I tested it and it works. It is temporary in the sense that it should be fixed by ESP-IDF upstream. I will make a PR for now. I can also release a 9.2.3 today with the fix (+ other recent rather innocuous PR's). Think I should do a release?

onyx hinge
#

seems like it would be a nice regression to fix.

tulip sleet
#

Yeah - half a dozen people have reported it, and maybe more have not

slender iron
manic glacierBOT
slender iron
#

This doesn't cover the STM issue though right?

manic glacierBOT
tulip sleet
#

I tried that fix on ESP32-S3 and it didn't fix it.

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

On second thought, we rely on the remaining length of the sample to calculate the ticking length (see the n variable below). In this logic branch, the sample is set to NULL and hence we tick the LFO in one fell swoop instead. In order to optimize this, we'd have to calculate n beforehand and add an additional self->sample != NULL check. I don't see this helping too much. If it's still a concern, it's simpler to just remove LFO ticking when there's no sample.

spare jacinth
#

i remember tinyuf2 worked funny on my board a year(ish) ago, though

manic glacierBOT
#

I've taken a different approach here. Storing this value and current_delay_ms as uint32_t was an arbitrary choice, so I've instead reverted both back to floats. I've added in another pre-calculated variable for the length of one audio frame (sample) in milliseconds, and I'm checking against that determine if we need to recalculate delay buffer parameters. The minimum value of the delay is handled within recalculate_delay. Before, delays could only be manipulated by an LFO in millisecond...

small cypress
#

@slender iron Hey, while I didn't see all of the stream, I think I remember you saying something about how it might be useful if you could see logs from your HomePod mini when it comes to CircuitMatter work? Did you work out how to do that? While I can't work out how to get it to throw logs into the macOS Console app like other Apple devices do, Apple have logging profiles you can install from here and then you can get it to ouput logs and export them somewhere. Have a feeling you'd probably want the "HomeThread (HomePod)" one, plus maybe the general HomePod one. You can't quite watch them in real time, but it's probably better than nothing.
https://developer.apple.com/bug-reporting/profiles-and-logs/?platform=tvos&name=homepod

slender iron
#

@crude blaze MBEDTLS_BUILTIN is on anyway

slender iron
crude blaze
orchid basinBOT
manic glacierBOT
#

Please mark this as a draft PR. The Pico-W (and probably the Pico2-W) need some more investigation. In my tests, the CYW43 did complain with messages like:

[CYW43] cyw43_kso_set(1): failed
F2 not ready
F2 not ready
[CYW43] STALL(0;129-129): timeout

There is a cyw43_enter_deep_sleep() function called from common_hal_alarm_enter_deep_sleep(), but I am missing the counterpart. Since this only sets WL_REG_ON to false, it might be simple.

Pinging @eightycc: any id...

manic glacierBOT
#

@bablokb The [CYW43] cyw43_kso_set(1): failed message may be occurring because simply turning off power to the WIFI radio as is done in cyw43_enter_deep_sleep() does not put the driver into a quiescent state. Similarly, properly powering the WIFI radio back up requires a sequence of operations involving an interrupt from the CYW43 that appears to be entirely missing.

I'll reproduce the failure here and get back with a more detailed analysis.

manic glacierBOT
manic glacierBOT
#

I got the same issue with version 9.2.3:

`import digitalio, board, time
from adafruit_hid.keyboard import Keyboard

pin0 = digitalio.DigitalInOut(board.D0)
pin0.direction = digitalio.Direction.INPUT
pin0.pull = digitalio.Pull.UP

pin4 = digitalio.DigitalInOut(board.D4)
pin4.direction = digitalio.Direction.INPUT
pin4.pull = digitalio.Pull.UP

time.sleep(0.5)

print("Pin 0: " + str(pin0.value) + ", pin 4: " + str(pin4.value))`

The output is:

Pin 0: False, pin 4:True

@juansulca, which vers...

manic glacierBOT
#

I am not seeing this problem with QT Py RP2040 running 9.2.3.

Adafruit CircuitPython 9.2.3 on 2025-01-17; Adafruit QT Py RP2040 with rp2040
>>> import board
>>> from digitalio import DigitalInOut, Direction, Pull
>>> 
>>> pin0 = DigitalInOut(board.D0)
>>> pin0.direction = Direction.INPUT
>>> pin0.pull = Pull.UP
>>> 
>>> pin4 = DigitalInOut(board.D4)
>>> pin4.direction = Direction.INPUT
>>> pin4.pull = Pull.UP

when measured with a voltmeter I am seeing 3.3V on both D0 and SCL.
D4 is th...

manic glacierBOT
orchid basinBOT
manic glacierBOT
#

In common_hal_alarm_set_deep_sleep_alarms() we're missing code for putting the CYW43439 into a quiescent state before pulling the plug on the WIFI radio by calling cyw43_enter_deep_sleep(). We're also missing code for bringing the CYW43439 back up after exiting deep sleep. That requires pretty much a complete re-initialization of the chip. There's no similar code in Micropython (i.e., powering down/up the WIFI radio), so we're on our own for an implementation.

The CYW43439 does expose ...

thorny jay
#

Checking Circuit-Python.org with my filter to see the new board: https://circuitpython.org/downloads?sort-by=date-desc I was suprise to see some old board on top such as: https://circuitpython.org/board/gb_m4/

CircuitPython for Game Boy is a work in progress, check out the weekly “Show and Tell” or “Top Secret” segment on ASK AN ENGINEER or when it’s ready, the new product videos on YouTube.Links and more Twitter thread. A Python powered GameBoy-compatible cartridge with a SAMD51 - GitHub. GBIO bran...

manic glacierBOT
#

At first I thought it crashed.. instead it's just the serial console messed up.

Adafruit CircuitPython 9.2.2-14-gab5c17d864 on 2025-01-16; Ai Thinker ESP32-CAM with ESP32
Board ID:ai-thinker-esp32-cam

>>> import microcontroller
>>> microcontroller.cpu.frequency
240000000
>>> microcontroller.cpu.frequency=120000000
>>> microcontroller.cpu.frequency=80000000
>>>
>>> microcontroller.cpu.frequency=20000000
▒▒▒▒▒▒▒

Same happens if you set 40 Mhz

>>> import microcontroller
>>> micro...
#

This is a "beware of the consequences" thing. As mentioned in https://docs.circuitpython.org/en/latest/shared-bindings/microcontroller/index.html#microcontroller.Processor.frequency:

Warning

Changing the frequency may cause issues with other subsystems, such as USB, PWM, and PIO. To minimize issues, set the CPU frequency before initializing other systems.

Also discussed in the original PR, #9342.

tulip sleet
manic glacierBOT
#

The function works perfectly on WROOM-32 (devkit v1) and also on EPS32 CAM I have.

I see no burden nor a problem.
Just copy the code from micropython.... no matter if it's an internal temperature and to many it might seem "wrong". It's not on my devices. And they are pretty standard and very similar even if the esp32 cam form factor is different.

ESP32-CAM

Detecting chip type... ESP32
Chip is ESP32-D0WD-V3 (revision v3.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse...
manic glacierBOT
orchid basinBOT
tulip sleet
#

@lone axle re an "all libraries update" thing like we just did. People are noticing and a little confused (e.g. https://forums.adafruit.com/viewtopic.php?p=1042524#p1042524) that circup is updating all their libraries.

In the case of an infrastructure change like this, but no code change for the user, perhaps we should not do a huge number of releases, but simply push the change to main on the libraries. If/when I library needs a release update, the change will be incorporated.

What do you think?

manic glacierBOT
manic glacierBOT
#

I'm experiencing the same issue (no CIRCUITPY drive after reset) with CPy-9.2.2 on two Waveshare boards (WS ESP32-S3-Zero and WS ESP32-S3-Matrix) when plugged directly into a Linux laptop (Mint-22). However, @dhalbert 's workaround is working for me: plugging the boards into an intermediate USB-Hub (e.g. an HP-Dock) makes the CIRCUITPY drive appear

Problem is fixed with the new CPy-9.2.3 on both Waveshare boards:
CIRCUITPY appears with direct USB connections...

lone axle
# tulip sleet <@382939733107408897> re an "all libraries update" thing like we just did. Peopl...

If we don't do a release then every library will get flagged in various Library has new commits since last release within _____ report sections on https://circuitpython.org/contributing/library-infrastructure-issues which makes it a bit more difficult for me to do a real release sweep each week to catch any libraries that had PRs merged without a release made because I typically load that page and then open in new tab the ones that appear in those lists to work from.

It would be a bit difficult to try to work out which libraries actually need a release and which ones just have a change that doesn't need one.

#

If we can come up with some solution that makes it easy at a glance to know which libraries "really need" a release and which ones don't then I'd be okay with it. But with the current way the reports work I would prefer to make the release even though the change was minor / irrelevant for usage on device.

tulip sleet
lone axle
tulip sleet
shut copper
#

If there was some metadata with the library updates circup could present that to help guide the users.

manic glacierBOT
#

This sounds likes hundreds of millions of pulses at the proposed rate. Where are these pulses coming from? This sounds a like a logic analyzer application.

Yes. Sort of. They come from the tape port of a commodore 64.

For example, this works:

 [int(machine.time_pulse_us(machine.Pin(13), 0))>>2 for x in range(100)]

[14, 32, 65, 97, 130, 4, 16, 32, 65, 97, 130, 10, 16, 32, 64, 97, 129, 6, 16, 32, 64, 97, 130, 10, 16, 32, 65, 97, 130, 10, 16, 32, 65, 97, 130, 10, 16, 32, 65, 97, 130, 10...
manic glacierBOT
manic glacierBOT
#

I used CircuitPython with ttgo display and it worked as expected out of the box . In the case of sunton_esp32_2432S028 i used the default with the bin from here https://circuitpython.org/board/sunton_esp32_2432S028/ The text does not work as in the pic , the code i used for Bitmap is copy paste from the site

Thanks for this, I ended up tweaking and posting to https://github.com/clach04/cyd_clocks/blob/main/circuitpython/bitmap_test.py

manic glacierBOT
manic glacierBOT
#

Seems like there are several existing projects for this, for instance, https://github.com/sweetlilmre/tapuino, that you could adapt code from, if you need to go that way. I see from Wikipedia the basic data rate is about 300bps, and the signal transitions out of the port are no more than about 1 MHz. Also a bit of analog circuitry at the tape output could make things easier, it appears, and reduce the sampling requirements.

I know about that. And it's not exactly what I want to do.. also, ...

manic glacierBOT
manic glacierBOT
#

@dhalbert any idea how to have a stable stream of pulse length? In every test I continue missing pulses...
but [int(machine.time_pulse_us(machine.Pin(13), 0))>>2 for x in range(100)] gives the kind of results I want.

P.S.
I don't understand why the pulse length reports is 4 times bigger than it really is. (hence the >>2).
It looks like it's measuring with a clock of 4 mhz?

manic glacierBOT
#

Because common_hal_alarm_set_deep_sleep_alarms() with its call to cyw43_enter_deep_sleep() leaves the CYW43439 in an unrecoverable state (at least with the code as it is), I'd suggest removing the call to cyw43_enter_deep_sleep() and seeing what the power consumption hit is. Just a nit to pick, but the function as is includes a hard-coded pin number.

It may be worthwhile to look into the power management features of the chip exposed by cyw43_wifi_pm() in cyw43-driver. Presently `...

manic glacierBOT
#

Perhaps I am blind,
but everywhere I read I should use adafruit_requests but there is no such module on esp32.

Adafruit CircuitPython 9.2.3 on 2025-01-17; ESP32 Devkit V1 with ESP32
Board ID:doit_esp32_devkit_v1
UID:4AFC21A0E74F

Modules:

>>> help('modules')
__future__        collections       max3421e          supervisor
__main__          countio           mdns              synthio
_asyncio          digitalio         memorymap         sys
_pixelmap         displayio         mic...
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

CircuitPython version

Adafruit CircuitPython 9.2.3 on 2025-01-17; ESP32 Devkit V1 with ESP32

Code/REPL

#If you save this as code.py and the run it on boot or soft boot, it will only show 0 and hitting control C will end with 0 (no pulses received)
import board,pulseio,digitalio,time
sense=digitalio.DigitalInOut(board.D14)
sense.direction=digitalio.Direction.INPUT
input("PRESS RETURN TO START\n")
sense.direction=digitalio.Direction.OUTPUT
p=pulseio.PulseIn(bo...
jaunty juniper
#

So, I have looked more at making adafruit_httpserver work with adafruit_esp32spi, like I did a few versions ago with UniversalSocket. But by implementing the changes directly into the ESP32 library.

Added missing methods from Socket:

  • 3 I haven't implemented, and "work" by being empty: setsockopt, listen, setblocking
  • 2 are implemented:
    • bind uses the ninafw start_server()
    • accept gets a client socket from that server (if any)

Changes had to be made to the ESP32SPI library:

  • re-add the socknum argument to the Socket() constructor. It's not in the python socket API, but we need to be able to wrap a Socket object around a socket number returned by ninafw when getting a client connection to the server.
  • ESP_SPIcontrol.socket_write returns the number of bytes written, so that:
  • Socket.send now returns the number of bytes written (as does sendto) to match the python socket() API.
  • SOL_SOCKET and SO_REUSEADDR have been added to SocketPool.

One change had to be made to the httpserver library:

  • try/except the import of the ssl module in the server module.
    I don't know if Nina supports opening ssl server sockets btw.
manic glacierBOT
#
  • Fixes #9868

Changes PIO background read/write to use only DMA0, not DMA1. This is a minimal change that does not change the current use of a static IRQ handler in ports/raspberrypi/audio_dma.c. It reverts to using only DMA0, and uses two background_pio... arrays to distinguish between read and write. picodvi now works again.

If this works, then I can explore using irq_add_shared_handler() as discussed in #9868.

@timchinowsky I tried to test this using a loopback test from h...

crimson ferry
#

it would be cool to use native ssl with esp32spi, if that’s possible

#

though most boards w/o wifi or eth don’t have ssl enabled

jaunty juniper
#

I think another thing I'll need to do is check adafruit_httpserver for memory use, it's gonna be really tight (especially as the library grew quite a bit)

jaunty juniper
#

are there rules for the default content of alarm.sleep_memory ? On an ESP I get zeros everywhere, on a Matrix Portal I get random data

#

fun fact: if adafruit_binascii is present, httserver loads it, which loads the entire library in memory because of how it's architectured (that could be optimized too), if absent it just prints a warning (maybe only in debug mode) that it's necessary for websockets

crimson ferry
manic glacierBOT
manic glacierBOT
#

Closes https://github.com/adafruit/circuitpython/issues/8151

First of all, I'd like to thank @qutefox for the initial work!

What I've done is:

  • adapt the code to newer CP versions (notably switching from STATIC to static)
  • fixing the byte ordering (due to i.MX chips endianness, byte order was [3,2,1,0,7,6,5,4])
  • fixing filtering and masking
  • fixing the reception of CAN frames (the "read" flag was never cleared, causing the code to read the same buffer indefinitely)
  • Add ...
manic glacierBOT
#

CircuitPython version

Adafruit CircuitPython 9.2.3 on 2025-01-17; Raspberry Pi Pico 2 W with rp2350a

Code/REPL

import time
import gc

import board
import digitalio
import audiobusio
import audiomp3

import wifi
import socketpool
import ssl
import adafruit_requests

class Player:
  def __init__(self,i2s_pins):
    self._buffer  = bytearray(16384)
    self._decoder = audiomp3.MP3Decoder("dummy.mp3", self._buffer)
    self._i2s     = audiobusio.I2SOut(*i2s_pins...
manic glacierBOT
manic glacierBOT
#

@bablokb Thanks for giving that a try. I was able to reproduce on a Pimoroni Pico Plus 2W with a debug build. MP3 playback is hanging up in an interrupt loop involving isr_irq10. Looks like a bug involving PIO/DMA. I've reproduced it a few times and it always winds up here:

Thread 1 "rp2350.dap.core0" received signal SIGINT, Interrupt.
0x200005aa in isr_irq10 () at audio_dma.c:465
465	    for (size_t i = 0; i < NUM_DMA_CHANNELS; i++) {
(gdb) bt
#0  0x200005aa in isr_irq10 () at audio_d...
manic glacierBOT
manic glacierBOT
dawn rampart
#

Hello - I am setting up a new board with a built in LCD. The driver is ST7789. I have setup the driver and display in the firmware board.c - and it uses a fourwire bus. But the board also has a microSD card and the display and sd card share the clock and MOSI lines. Every time I try to setup the SPI to the SD card, I get the error that the CLK is already taken by the display bus. If I try to point the sdcardio to look at the display bus, I get the error that that bus is a fourwire bus, not SPI - which all makes sense. Thoughts on how I might be able to use both the LCD and the SD card slot? Board files: https://github.com/bwshockley/circuitpython/tree/master/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47 shows how the display is initialized.

GitHub

CircuitPython - a Python implementation for teaching coding with microcontrollers - bwshockley/circuitpython

#

And these are the pins in use:

jaunty juniper
manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

The backtrace is from the GDB command bt. I build with DEBUG=1 to get symbols and object code that's partially optimized but not to the extent that it's too scrambled to make sense of. My test hardware is an RP2040 board running debugprobe attached to SWD and a serial port on the Pimoroni Pico Plus2W. The other tool is OpenOCD, I use the Raspberry Pi Foundation's fork. I follow the instructions in Appendix A of "Getting Started with Raspberry Raspberry Pi Pico Series".

dawn rampart
jaunty juniper
manic glacierBOT
dawn rampart
stuck elbow
jaunty juniper
#

that's a bulid with built-in display

stuck elbow
#

ah, sorry then

jaunty juniper
manic glacierBOT
#

The interrupt loop and the state of the DMA section are interesting. CircuitPython overrides isr_dma_0() with its own implementation. The loop occurs because DMA is raising the IRQ due to bits set in DMA_INTS0, specifically those for channels 7 and 10. Since CP's isr_dma_0() doesn't test any of the DMA_INTSx bits in IRQs it loops. It's strange and unexpected that DMA_INTS0 bits are set for these channels.

#

Thank you for the review!
I will make the required changes -- it seems I'm left with some old style files from when I started work on this.

I am not collaborating with Electrosmith, I just tackled this project as a personal challenge, after seeing a lot of people ask for CircuitPython / micropython support for the Daisy Seed board.

Electrosmith do have their own bootloader, but it is still closed source, and they seem very reluctant to share the code or any details about it. I am no...

manic glacierBOT
#

CircuitPython overrides isr_dma_0() with its own implementation.

This is not a good idea and I want to fix this. There is discussion in #9868 about this, and #9980 uses that routine. As a first step for solving #9868, I want to make DMA0 be the shared DMA used for multiple purposes. I am awaiting some reworked tests to test #9980. After that, I'll switch to using irq_add_shared_handler() for all the uses of DMA0, and re-test

I haven't looked at this issue in any detail. Is there a sim...

tulip sleet
#

<@&356864093652516868> We'll have our weekly meeting (delayed one day due to a holiday) in this channel and the CircuitPython audio channel in less than 1.5 hours, at 2pm US Eastern time / 11am US Pacific time. Add your notes: https://docs.google.com/document/d/1BTOyxonN09KjzL7GsxcN7HMlbOn4yzkcDvRoX4l-op0/edit?usp=sharing

manic glacierBOT
manic glacierBOT
#

From the "I can't fix it, but I can bypass it with one of these" department: The data_hw->ints0 bits for channels 7 and 10 were coming on because something is setting the corresponding channel bits in data_hw->intf0. A combination of testing data_hw->ints0 instead of data_hw->intr and clearing any bits set in data_hw->intf0 fixes the bug. I still cannot explain how those bits got set in the first place.

void __not_in_flash_func(isr_dma_0)(void) {
    for (size_t i = 0; i < NU...
blissful pollen
#

Lurking no notes

manic glacierBOT
lone axle
short tendon
#

@tulip sleet that's so exciting! If you are working on the Nina firmware, let me know how I can help!

lone axle
#

Thanks for hosting Dan! Have a great week everyone 👋

errant grail
#

Thanks!

random junco
#

thanks for hosting Dan, have a good week all

tulip sleet
#

thanks for attending!

manic glacierBOT
mortal kernel
#

@danh Any insight into #9983 or would you like me to keep digging?

tulip sleet
mortal kernel
modest hazel
#

is pulseio not available for the micro:bit v2? I tried modifying the makefile to "force" it and it's throwing an error undefined reference to 'pulseio_module'

modest hazel
#

I did make clean at the port/nordic folder level, should I be doing that at the top level?

#

Also, I'm on 9.0.0

modest hazel
#

okay, let me give that a whirl...

jaunty juniper
#

is it not in there ?

modest hazel
#

Yeah, that's why I was confused when it didn't work

#

okay, that seemed to have worked, thank you!

jaunty juniper
#

the module is there in CP 9.2.3, what was your issue ?

modest hazel
#

I'm not sure why it wasn't working, but using make clean BOARD=microbit_v2 first seems to have fixed it. 🤷‍♂️

modest hazel
#

Or - maybe it didn't. The build went okay, and I moved this

CIRCUITPY_PULSEIO = 1  #force it

outside of all of the conditionals in the makefile, but when I use help(modules), pulseio isn't in the list. 😦

spare jacinth
#

instead of help() i would just try and import pulseio, in case the list getting printed gets messed up somehow
but im going to assume that fails as well 😬

modest hazel
#

Yup - module not found when I did that just now

spare jacinth
#

also, since makefile is more of a text language, maybe your comment is getting the value get "read" as 1 , i would also remove the comment (and maybe the spacing with equals sign) to make sure it is a verbatim 1 and not some combination of whitespace and 1
otherwise the checks on other files to see if it is enabled might fail, i think i saw at some point an issue/PR for similar issue

#

but most likely the issue is something else that i dont know about, this is more of a quick test than anything

modest hazel
#

okay, let me give that a spin.

#

okay, this looks promising...import pulseio now seems to be working - and that was just from moving the comment, so I think you're theory was right.

#

And, this seems to have solved the bigger problem I was fighting, which was getting an ultrasonic censor to work with my micro:bit, so thank you!

jaunty juniper
#

oh 9.0.0 why did you need 9.0.0 ?

modest hazel
#

I could update (and would if I needed to), but this is a custom build and 9.0.0 was where I last forked it. No other reason really.

jaunty juniper
#

oh in ESP32SPI we have this about settimeout:

If value is 0 socket reads will block until a message is available.
But this is what Circuitpython does (and C python)
0 means non-blocking. None means block indefinitely.

#

also it uses time.monotonic() which is not great for measuring timeouts for projects that might want to stay running for days maybe

dawn rampart
#

boards/waveshare_esp32_c6_lcd_1_47/board.c: In function 'display_init': boards/waveshare_esp32_c6_lcd_1_47/board.c:43:28: error: implicit declaration of function 'common_hal_board_create_spi' [-Werror=implicit-function-declaration] 43 | busio_spi_obj_t *spi = common_hal_board_create_spi(0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ boards/waveshare_esp32_c6_lcd_1_47/board.c:43:28: error: nested extern declaration of 'common_hal_board_create_spi' [-Werror=nested-externs] boards/waveshare_esp32_c6_lcd_1_47/board.c:43:28: error: initialization of 'busio_spi_obj_t *' from 'int' makes pointer from integer without a cast [-Werror=int-conversion] cc1: all warnings being treated as errors

#

Pull 9987

jaunty juniper
#

missing includes ?

#

at the top of the file

manic glacierBOT
tulip sleet
#

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

modest hazel
#

Hi - is there a way to get at least some of the functionality in the micro:bit v2 library working in circuitpython?

manic glacierBOT
manic glacierBOT
#

@bablokb Good to know. The root cause is missing code to handle the case where the MP3 decoder fails to synchronize with the first buffer of the stream. This leads to a cascade of errors that eventually hangs in an interrupt loop. To actually fix the bug I'm detecting the error and throwing a "DMA source error" from the player when it occurs. Your code will need to catch and retry for this case. I'll be submitting a PR shortly.

manic glacierBOT
#

Fixes #9983.

Add handling for errors that may occur during setup of an audio DMA player. audio_dma_setup_playback() calls audio_dma_load_next_block() to fill one or two buffers with audio source data. This PR adds preservation of the error indication in the new dma_result field in audio_dma_t and examines it in audio_dma_setup_playback(). If an error indication is present, shuts down the player and throws an "Audio source error".

For #9983, the error indication occurs frequent...

manic glacierBOT
slender iron
modest hazel
slender iron
#

led matrix is tricky I think because it is directly driven

#

buttons, buzzer and accel should be doable from CP

manic glacierBOT
#

@FK-sauve Thank you for looking at these messages.

in my comments, I asked you not to expand messages when their meaning is clear in context. The French translation is already one of the largest translations, due to the verbosity of French. This can make the translation come very close to overflowing board builds that are already very full. Try to keep messages as short as possible.

(I speak French at an intermediate level, but don't have much experience with technical French idioms.)

jaunty juniper
modest hazel
#

I had thought of that specific library - my company modified it a bit to drive an RGB8x8 SPI matrix, but we were using the Pico and i took advantage of the second processor to just handle it in the background. I don't think I have that luxury on the micro:bit

#

It's not an urgent need by any means, just a nice-to-have at this point. Ideally I'd like to drive it in the C-level code and just expose an API.

jaunty juniper
#

it runs on the pewpew which is SAMD21, so I think it should work at least as well 🤷

modest hazel
#

Yeah, I'm not great with the concurrent task stuff but I could probably figure it out given enough time... 😉 At least I've got a starting point!

#

We are still in the proof-of-concept stage so it's just a lot of exploring and low-hanging fruit stuff right now.

manic glacierBOT
#

CircuitPython version

Adafruit CircuitPython 9.2.3-1-g401295f6dc on 2025-01-21; LILYGO T-Deck (Plus) with ESP32S3

Code/REPL

import time
>>> time.localtime(2147483647)
struct_time(tm_year=2038, tm_mon=1, tm_mday=19, tm_hour=3, tm_min=14, tm_sec=7, tm_wday=1, tm_yday=19, tm_isdst=-1)
>>> time.localtime(2147483648)
Traceback (most recent call last):
  File "", line 1, in 
OverflowError: overflow converting long int to machine word

Behavior

Yea, 1/1 of...

manic glacierBOT
#

I've tested this build using the example provided in the gist above. The program locks up with the following traceback:

Traceback (most recent call last):
  File "", line 16, in 
  File "pio_i2s.py", line 361, in write
  File "pio_i2s.py", line 340, in write_ready
  File "pio_i2s.py", line 316, in _get_write_index

The changes in this review result in a functioning test with an error output of 0.

manic glacierBOT
#

My script hard resets once every 24 hours to keep time.monotonic refreshed. The battery monitor init error happens infrequently because it only happens on boot once a day. Instead of attempting retries I just do a microcontroller.reset in the try/except loop. It ensures that the rest of the script only works if the battery monitor inits correctly. I only visually notice it happens when I see the boot screen reset twice. It's been a valid work around that has been working for months. Doesn't...

manic glacierBOT
#

Hello,
The verbosity of French is high, making it difficult to contract. I have noted the fact that the context should not be repeated, such as Bluetooth, and I am now looking for short words for this translation. Best regards, thank you for these clarifications.

Cheers,
Franck

De : Dan Halbert @.>
Envoyé : mercredi 22 janvier 2025 19:17
À : adafruit/circuitpython @.
>
Cc : FK-sauve @.>; Mention @.>
Objet : Re: [adafruit/circuitpython] Translat...

manic glacierBOT
#

@bablokb Please give this a try. There may be more gravel in this gearbox.

Works perfectly and the retry in case of an exception is so fast that from a user-perspective it is not noticed.

I do think there is some other error lurking around, because when I play this French url: http://icecast.radiofrance.fr/francemusiquebaroque-midfi.mp3 the playback stops about after half a second. But this seems to be handled internally (no crash) since I2SOut.playing will switch from True to `Fa...

manic glacierBOT
mortal kernel
#

We're getting close to CircuitPython issue/pull number 10,000. Any celebrations or prizes planned?

jaunty juniper
#

I'm sure there'll be a blog post

manic glacierBOT
manic glacierBOT
orchid basinBOT
manic glacierBOT
#

ports/raspberrypi/audio_dma.c uses defines isr_dma_0() to handle all DMA 0 interrupts. Right now it's both audio and PIO. This is not recommended (see https://github.com/adafruit/circuitpython/issues/9868#issuecomment-2549122843). Change to use irq_add_shared_handler() to set up handlers as needed.

We should document somewhere as well which DMA irq's are ok to share and which are used exclusively. RP2040 has DMA 0 and DMA 1. RP2350 has 0 through 3.

fleet hollow
#

@blissful pollen @onyx hinge Thank you for all the help on the #9776! I'm very happy to have that one buttoned up. 🚀

onyx hinge
#

🚀 🔉

blissful pollen
onyx hinge
#

correction, one channel is a triangle

manic glacierBOT
#

Following the merge of #9776 , shared_bindings_synthio_lfo_tick and all synthio_block_slot_get calls will need to be moved into the buffer loop at L258, a second num_samples argument will need to be provided, and the buffer loop will need to be limited to SYNTHIO_MAX_DUR samples per iteration. See Distortion.c for a good example of this which also ticks the blocks when no sample is provided.
https://github.com/adafruit/circuitpython/blob/10cd4f091c8a3d556df781deee0b1bd870c332ab/share...

blissful pollen
#

@fleet hollow Which of the PRs did you want to look at next?

fleet hollow
#

I've got a comment on #9804 for @onyx hinge to take a stab at. I'll be working on updating #9876 to be merge ready. Both are related to changes implemented in #9776.

#

It's not ready yet, but I've been working a lot on https://github.com/adafruit/circuitpython/pull/9909 since I've got good hardware to test it on. It works for basic loopbacks, but otherwise I'm running into output underflow issues and problems related to audiomixer. I'd love some insight with all the buffer dma schenanigans, but it's pretty complicated.

GitHub

New class, audiobusio.I2S, which can be used to both record and playback audio over a unified I2S bus (single pair of bit clock and word select pins).
Notes:

This functionality currently relies on...

blissful pollen
#

Okay cool, feel free to tag me on any you want a review/test on. I'll take a look at 9909 as well to see what I see

fleet hollow
#

I've also been working a bit on arduino-pico lately for similar functionality. The implementation is much simpler than CircuitPython, but there might be something to glean from it. https://github.com/earlephilhower/arduino-pico/pull/2775

GitHub

I've added a bi-directional mode to the I2S library using INPUT_PULLUP as the value of direction for the constructor. Certain resources of the object have been split into input and output v...

manic glacierBOT
#
[adafruit/circuitpython] New branch created: sparkle_update
fleet hollow
#

@blissful pollen I've got #9876 merged back up to main. Feel free to review/test when you get the time. 🙂

jaunty juniper
#

oh that could make all of them with the RTD updates, but requests does need the fix

manic glacierBOT
manic glacierBOT
#

I added two small changes:

  • keep WLAN alive for light-sleep/deep-sleep when connected via USB
  • fix AON-wakeup for RP2350

The code from the PR is now also working for Pico-W and Pico2-W, but it is necessary that the user disables WLAN (wifi.radio.enabled = False) before switching to light-sleep (and "slow-sleep" also btw, since the CYW does not like changing clocks).

Looking at the measurements, the W variants draw a lot of current, probably more than what can be attributed...

viscid trench
#

Is there a way to enable compression functionality in uzlib in CP?
I'm looking at the CIRCUITPY_ZLIB option, but i think that only enables decompression..?

viscid trench
blissful pollen
tulip sleet
mortal kernel
#

@danh Here are some thought on RAM log I was hoping you could give me some feedback on:

I've been thinking about the "cooking" of line endings ('\n' -> '\r\n') that happens on some (but not all!) serial console output. I think it would be helpful to make whether or not line endings get "cooked" an attribute of the serial destination (UART, tud, BLE, etc.) instead of trying to get it right in the string to be printed. I'd like to see all serial output go through a single simplified path.

#

Related, it may clarify/simplify messages (including logging) to have three virtual destinations: STDOUT, STDERR, and STDLOG. Each destination would have one or more default physical destinations that could be adjusted at run time.

#

A feature of RAM logging is the ability to recover the log after a complete system crash. This works by walking the tlsf free blocks early in start up and reviving the ramlog_t object based on a magic number and its complement. For all ports except Espressif it's trivial to get a pointer to the tlsf heap. Espressif has its own modified version of tlsf that is buried deep in IDF that's problematic for this feature. Is it worth digging deeper into Espressif now or leave this until later?

jaunty juniper
tulip sleet
jaunty juniper
#

thanks 👍

tulip sleet
mortal kernel
# tulip sleet I think this is a good idea. You could do a scan through all of RAM looking for ...

The reason that I start by scanning the tlsf free blocks is that I use a call to tlsf_malloc_addr() to revive the ramlog_t object. Otherwise, I have a problem of what to do with the ramlog_t once I've found it. If I call port_malloc to allocate space to copy it into, I run the risk (especially with a large ramlog_t in PSRAM) of having the newly malloc'ed area overlapping the ramlog_t I want to recover, possibly even corrupting it with block meta data from a split.

#

Also, the Esp hardware appears to sparsely populate RAM blocks in a larger address space, so without a cue from IDF/tlsf I won't have a clue of where to scan.

tulip sleet
# mortal kernel The reason that I start by scanning the tlsf free blocks is that I use a call to...

So how about instead of using the regular heap, allocate a single ramlog object using port_malloc(), using a size specified in settings.toml ? If no size is specified, then ramlog is not available. That will get the object off the regular heap. If the allocation is done early, it will also be at the same place all the time. Or you could remember its location in a static. Or use a magic number to find it and its size.

#

you have to look at the existing object to see if it was in use before initializing it.

#

If the ramlog object was in use (not "closed"), or something like that, then when code.py or boot.py starts, it would be available to inspect, but writes into it would not be available (until explicitly reset). DOes that make any sense? What do you do currently with the ramlog on startup? Does it get copied to the filesystem?

mortal kernel
#

Thanks, Dan, for the great feedback! At this stage I've been using compile-time flags to select start-up behavior of ramlog (do nothing, attempt recovery, pre-allocate ramlog_t or start logging). Putting this into settings.toml makes sense. It will delay ramlog start until later in initialization, but I think leaving the compile-time flags in place will cover cases where logging is needed early in boot. CYW43 startup is a good example of a case where earlier ramlog startup is needed.

#

Here's the ramlog_t object to give you an idea of how it works at the lowest level:

typedef struct _ramlog_t {
    uint32_t magic;             // Magic id number
    uint32_t c_magic;           // ...and its complement
    uint64_t last_log_time;     // Last log message time in subticks (1/32768 second)
    mp_uint_t log_buf_sz;       // Size of the log buffer in bytes
    mp_uint_t next_idx;         // Index of next byte to write in the log buffer
    bool logging_enabled;
    bool wrap_enabled;          // Wrap log buffer around when full
    bool wrapped;               // Log buffer has wrapped around since last reset
    bool prev_nl;               // Previous log byte was a '\n'
    uint8_t log_buf[];
} ramlog_t;
#

On top of the low-level logging, there's a ramlog binding that encapsulates the ramlog_t object, a Python singleton object RamLog, and their associated control stuff. The RamLog object implements the stream binding, so it can be unloaded by Python code and can also be used as a target for Adafruit_Logging. The binding has methods to initialize/deinitialize, reset, enable/disable, enable/disable wrapping, and so on.

#

Here's an example unload():

import ramlog
import storage

ramlog_obj = ramlog.RamLog()

def unload(fname: str, reset=True, enable=True) -> None:
    """Unload the RamLog to a text file."""
    # Test that filesystem is mounted rw
    if storage.getmount("/").readonly:
        print("Filesystem is mounted ro, cannot unload RamLog")
        return
    # Disable the RamLog to prepare it for unloading
    ramlog_obj.log_enable = False
    # Unload the RamLog
    log_lines = log_bytes = 0
    with open(fname, "w") as f:
        while True:
            line = ramlog_obj.readline()
            if not line:
                break
            log_bytes += f.write(line)
            log_lines += 1
    print(f"Unloaded {log_lines} lines, {log_bytes} bytes to {fname}")
    # Optionally reset/enable the RamLog
    if reset:
        ramlog_obj.reset()
    if enable:
        ramlog_obj.log_enable = True
broken falcon
#

i keep running in to really disappointing memory allocation errors with the pyportals. as soon as youve added some buttons, sounds, fonts and labels to make a cool interface, requests dont work anymore (30 kb free memory to fetch a 3kb json doesnt work, everybody says due to fragmentation). now, i have at least 30 pyportals. can they be upgraded with a esp32s3 or something with a lot of ram so these projects are possible. most importantly; is there anything else one can do to increase memory (like an extra chip or something)? or a quite deep dive into memory allocation function? or request itself?

My students are going to make an assignment were they present their AIO feeds (io.loop) , get historical feed data (http requests) and the current weather forecast. thats a nice versatile project, but it seems impossible at the moment. any tips?

stuck elbow
#

I suppose it would be possible to write a requests-like library that uses preallocated buffers instead of allocating them dynamically, just nobody did it yet

#

I think I also saw in here mentioned a json library that can parse it while it's streamed, without having to download it all at once

orchid basinBOT
slender iron
#

(but increase flash use)

manic glacierBOT
#

I propose broadening this enhancement request to include all time related functions that currently round or truncate unnecessarily.

Time related functions need not arbitrarily round time/sleep resolution. Doing so wastes cycles (maths) and makes polling less performant. A millisecond is a long time on an mcu running at 240mhz, even in an interpreter.

I disagree with the argument that "not super precise" is ok for python because of interrupts or gc -
Interrupts, scheduling of other proces...

broken falcon
stuck elbow
#

I'm sure improving the documentation would be easier than soldering extra ram.

broken falcon
# broken falcon well, i tried that rabbithole, but we never understood how to use it. the exampl...

of this format: (im going to post this in the general chat as well.

{
  "feed": {
    "id": 1958829,
    "name": "temp",
    "key": "esp32s2.temp"
  },
  "parameters": {
    "start_time": "2025-01-10T18:44:43Z",
    "end_time": "2025-01-17T18:44:43Z",
    "resolution": 60,
    "hours": 168,
    "field": "avg"
  },
  "columns": [
    "date",
    "value"
  ],
  "storage": "agg",
  "data": [
    [
      "2025-01-10T19:00:00Z",
      "20.316816416666665"
    ],
    [
      "2025-01-10T20:00:00Z",
      "20.3822235"
    ],
    [
      "2025-01-10T21:00:00Z",
      "20.414748"
    ],
    [
      "2025-01-10T22:00:00Z",
      "20.42719525"
    ],
    [
      "2025-01-10T23:00:00Z",
      "20.414236416666668"
    ],
    [
      "2025-01-11T00:00:00Z",
      "20.4240675"
    ],
    [
      "2025-01-11T01:00:00Z",
      "20.42496075"
    ],
    [
      "2025-01-11T02:00:00Z",
      "20.433898944444444"
    ],
    [
      "2025-01-11T03:00:00Z",
      "20.461606541666665"
    ],...
slender iron
#

that's what the CP version is modelled after

manic glacierBOT
#

In the current implementation of the audiodelays.Echo.mix parameter, the source audio sample is first combined with the echo sample and then mixed again with the source audio sample using the value of mix parameter. This effectively only allows you to control the level of the effect audio and not the level of the source audio (see the following graph, red=source, blue=effect).

image

In this update, I...

manic glacierBOT
#

Hi @SeanTheITGuy

I tried to flash my Spotpear ESP32C3 LCD 1.4 device with the version 9.2.3 of CircuitPython from that link:
[https://circuitpython.org/board/spotpear_esp32c3_lcd_1_44]. After a small fix on the CircuitPython site, I was able to flash it. However, it seems that the firmware makes the board rebooting over and over, with the following errors:

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x4038...
manic glacierBOT
#

@gabriel-gagnon Can confirm this is not your problem. 9.2.3 does NOT work on this board. It results in, exactly as you say, a boot loop.
I went through the older versions, and it worked up to 9.2.1, but something was introduced in 9.2.2 that causes this issue.

https://adafruit-circuit-python.s3.amazonaws.com/index.html?prefix=bin/spotpear_esp32c3_lcd_1_44/en_US/

If you can grab 9.2.1 from there and flash, you'll most likely find it works perfectly. I'm not sure what issue might have ...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

Just to make sure I understand correctly, the idea is at 0.5 both the original and effect play at full (1.0) volume, as opposed to at 0.5 they both play at 0.5 volume?

From the graphs above it seems we lose the ability to go say 70% original 30% effect? That was the original intention of the mix parameter.

I'm not familiar enough with how other synths do this so just wondering. @todbot any thoughts if you have a moment as you originally gave me the idea?

viscid trench
manic glacierBOT
onyx hinge
#

@slender iron do you have something queued up for #10000? otherwise, I have two minor PRs

onyx hinge
#

ding ding ding

manic glacierBOT
#

in ports/espressif/mpconfigport.h there's a section for each different IDF_TARGET. So the needed change might be

diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk
index 06f8c87c57..310558b867 100644
--- a/ports/espressif/mpconfigport.mk
+++ b/ports/espressif/mpconfigport.mk
@@ -85,6 +85,7 @@ CIRCUITPY__EVE ?= 1
 ifeq ($(IDF_TARGET),esp32)
 # Modules
 CIRCUITPY_ALARM_TOUCH = 1
+CIRCUITPY_AUDIOIO = 1
 CIRCUITPY_RGBMATRIX = 0
 
 # SDMMC not sup...
manic glacierBOT
manic glacierBOT
manic glacierBOT
onyx hinge
manic glacierBOT
jaunty juniper
#

why does that make me want to write a script that uses the github API find out which numbers are missing ?

manic glacierBOT
#

For some reason when I used ffmpeg to convert some 96 khz sample rate wave files from 24 bit sample size to 16 bit it decided to use a 40 byte format chunk. This patch allows the 40 byte chunk if the existing format constraints are met. I would attach the converted files but I worry about copyright issues.

The wave files that I was converting are located at:

https://www.soundonsound.com/techniques/sos-audio-test-files-downloads.

The command that I used to perform the conversion was:
...

manic glacierBOT
#

Just to make sure I understand correctly, the idea is at 0.5 both the original and effect play at full (1.0) volume, as opposed to at 0.5 they both play at 0.5 volume?

Because the original sample is combined with the echo sample right from the get-go, it isn't possible to get both the effect and the sample at 50% volume (without an audiomixer, see comments below about levels).

https://github.com/adafruit/circuitpython/blob/52b5b2da1a5443927678c953b1e8bbd3cf1cbfab/shared-module/audio...

#

Thank you for the fix. I am going to try to understand why this made the board work. It makes it match other boards that do work. But the "LEGACY" layout should not make a difference if you don't care about preserving CIRCUITPY. The partition table is replaced when the .bin is flashed.

Even more mysterious, but possibly a clue to resolving the "why", is why it worked as-was on 9.2.1 but not on 9.2.2+.

manic glacierBOT
#

Tested on metro rp2350 with import go_kbd. It works in the normal & reversed pinout; and it works on any one PIO.

this also depends on https://github.com/adafruit/Pico-PIO-USB/pull/2

<details>
<summary>content of go_kbd.py</summary>

import digitalio
import board
import usb_host
import rp2pio
import array

# Force allocation on a given state machine
# Note that StateMachine() happens to allocate in the order 2, 1, 0
# (sdk pio_claim_free_sm_and_add_program_for_gpio_ran...
onyx hinge
manic glacierBOT
midnight ember
#

@tulip sleet pinned google doc hasn't been updated from last week. i have a hug report to write. 🙂

onyx hinge
midnight ember
#

Thank you

tulip sleet
#

thanks for pinning it @onyx hinge

manic glacierBOT
#

this ifdef-guard is not needed, as this file will only be built when CIRCUITPY_AUDIOIO is enabled. Please remove it.

In the case that CIRCUITPY_AUDIOIO is incorrectly enabled on a board without SOC_DAC_SUPPORTED, it's preferable to get an error when building this file (due to an undefined symbol or unavailable header, for instance) than giving a link time error.

You can include a comment or an assertion that this only works when SOC_DAC_SUPPORTED if you like (e.g. maybe `MP_STATIC_ASSER...

manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

CircuitPython version

Adafruit CircuitPython 9.2.3-14-g52b5b2da1a on 2025-01-26; Adafruit Feather ESP32-S3 TFT with ESP32S3

Code/REPL

import board
import time
import array
import pulseio

f = open("/codes.txt", "r") # https://github.com/mario872/Sonic-Screwdriver/blob/main/Software/src/codes.txt
# Just moved some lines around from https://raw.githubusercontent.com/adafruit/Adafruit_Learning_System_Guides/master/CircuitPython_TVBGone/codes.txt
input() # To ma...
manic glacierBOT
#

Hi Dan,

A short message to inform you that I am working to reduce the size of all strings to minimize the impact on the firmware size.

There is a better way to translate ‘broche or broches’ in most of the messages; in fact, we use ‘Pin’ like native English speakers. In the same spirit, for ‘microcontroller’ we use ‘board’.

We should be able to save about 100 bytes for all the translations with this request.

Best regards,

Franck

De : Dan Halbert @.***>
Envoyé : dima...

manic glacierBOT
#

@FK-sauve broche is fine if it's the more common usage (at least, say, when I look at French-language Arduino sites). Your grammatical changes are probably the most effective changes in terms of saving space.

The error messages are compressed when they are stored. A highly-repeated word like broche will be well-compressed.

Thank you for looking at this, since it helps a lot making the translation more complete and yet still fit on smaller boards.

tulip sleet
mortal kernel
onyx hinge
#

@tulip sleet I think we get this right in StateMachine _transfer -- we loop while dma_channel_is_busy. after the loop we clear the stall bit, then way below if requested we wait until the stall mask is set.

mortal kernel
#

@onyx hinge Did you have an chance to look into potential PIO clock jitter?

onyx hinge
#

@mortal kernel you mean this old discussion? I didn't think about it since then.

mortal kernel
#

I'm interested in your thoughts on it. I did get a pair of Raspberry Pi Pico 2W boards. So far I've not had a failure with either a 2 or 3 PIO divider.

onyx hinge
#

This program is set pins, 0 / set pins, 1. mcu is RP2350B at 150MHz. Divisor is 2. The wave is square at 37.5MHz (150/4) as expected. It only moves around by +-1 scope capture cycle.

#

divisor 3 is also stable & square

#

divisor 3.5 is unstable, with pulses of different lengths.

#

2.5 is stable but not square.

#

(2+56/256) ~ 2.2539 is very unstable

#
import adafruit_pioasm
import board
import rp2pio
import microcontroller

DIVISORS = [2, 2.25, 2.5, 3, 3.5]

def cycle(seq):
    while True:
        yield from seq

program = adafruit_pioasm.Program("""
    set pins, 0
    set pins, 1
""")

for divisor in cycle(DIVISORS):
    with rp2pio.StateMachine(program.assembled,
        first_set_pin = board.A0,
        set_pin_count = 1,
        frequency = int(microcontroller.cpu.frequency / divisor)) as sm:

            print(f"{divisor=} {sm.frequency=}")
            input("Hit enter to cycle frequency")
```My test program
mortal kernel
#

@onyx hinge Thank you! I'm surprised that 3 is stable, but it is good news.

onyx hinge
#

divisor=2.25 sm.frequency=66551126
Due to rounding, I think this actually tested divisor (2+65/256)

#

real 2.25 has a very short repeating pattern of alternation

#

divisor=2.249 sm.frequency=66666666

#

afk for a grocery (coffee beans) run

mortal kernel
#

In combination with the RM2 (but not the older CYW43439) any instability in the clock around 22 MHz results in the gSPI interface oscillating between CPHA=0 and CPHA=1 on CYW43 to host responses. Ouch!

manic glacierBOT
#

Thank’s Dan, i doesn’t know that all this stuff was compressed, I will try to use the same word as possible to save space.

Have a good day,

Franck

De : Dan Halbert @.>
Envoyé : lundi 27 janvier 2025 15:26
À : adafruit/circuitpython @.
>
Cc : FK-sauve @.>; Mention @.>
Objet : Re: [adafruit/circuitpython] Translations update from Hosted Weblate (PR #9996)

@FK-sauve https://github.com/FK-sauve broche is fine if it's the more c...

manic glacierBOT
#

Can anyone confirm the neopixel works on this board?
I bought a Worldsemi WS2812B-2020 and soldered it to my board on the footprint (my board came with a missing neopixel) and so far, no luck having it run, using neopixel_simpletest.py, with pixel_pin = board.NEOPIXEL or pixel_pin = board.IO21. All I get is a small light blip from the neopixel when I connect the board to power.
Maybe I solder...

#

Compression by "words" is enabled for builds where translation compression level (CIRCUITPY_MESSAGE_COMPRESSION_LEVEL) is above 5. This level is not applied to all boards, because it does increase build time.

During the build, the translation compression code uses a heuristic algorithm to choose common character sequences (which need not be aligned at word boundaries, even though the code calls them "words") to represent as a node in the huffman encoding tree: It estimates the savings for...

orchid basinBOT
onyx hinge
#

@lone axle @slender iron will you be able to read core & libraries sections?

lone axle
#

Yes, I am.

onyx hinge
#

<@&356864093652516868> good morning! We're about 2 hours from our weekly meeting. Take a moment to add your notes to https://docs.google.com/document/d/1JpgiZ0ps-KhwsvriKFn21Ss0hKLDFCD1_NPpAN1C2Vc/edit?usp=sharing then if you can join us in the CircuitPython voice channel at 2PM ET/11AM PT. We love hearing what you're up to!

manic glacierBOT
manic glacierBOT
onyx hinge
#

@slender iron not sure if I'm overlooking something but on Metro RP2350 USB stops working when the program exits, meaning that a USB keyboard can't be used in the repl if it's set up by boot.py. This is presumably because the USB host power pin gets turned off. Is there something sensible to be done about this? One thing that crossed my mind is to add a "host power" pin to the usb_host.Port constructor, which can always be None if there's not a power control...

slender iron
onyx hinge
#

@slender iron should I do that for metro rp2350?

slender iron
#

sure! I was hoping to do auto init

#

(same for HSTX if it detects a connection))

onyx hinge
#

OK I'll toss in a PR to do that.

#

ooh can HSTX detect?

slender iron
#

I think the connector has I2C lines we could test if they are pulled up

onyx hinge
#

we'd still want to support the user changing geometry or color depth but I guess you can release_displays()....

lone axle
#

Thank you!

onyx hinge
#

please suggest modest improvements to piomatter, it is very barebones at the moment and not super friendly.

manic glacierBOT
jaunty juniper
#

is there code anywhere to read a keyboard (let's say classic 6KRO for starters) with USB host, like there is for midi ? (like adafruit_usb_host_midi)

manic glacierBOT
tulip sleet
#

@onyx hinge notice I copied the raw markdown from the report and did "Paste as Markdown" to get it as googld docs formatted text in the notes. It will go back to Markdown when you do File->Download as markdown

slender iron
manic glacierBOT
lone axle
#

We'll get a first look at playing .wav files in CircuitPython. We'll supply some sample files and also discuss how files should be formatted. We'll cover the ways in which certain boards require some libraries and not others. We'll show code for CircuitPlayground boards (both Bluefruit and Express - import statements are different), and we'll wr...

▶ Play video
jaunty juniper
# slender iron circuitpython should automatically inject the keystrokes as serial input

that's not what I'm talking about, I just want to fully read the keyboard, including all modifier keys, combinations, etc. Like you would to make a USB-to-BLE converter or HID remapper thing.
The "kernel driver" delivers strings and also acts on actions like ctrl-C. It's an interesting feature, especially with set_user_keymap() (even though it doesn't do unicode characters), but it's no way to read the actual keyboard inputs.
(There's also a bug I yet have to open an issue on where reading with input() or sys.stdin gives a UnicodeError when pressing left-alt + another key.)

I started writing code to read a keyboard HID reports (on host USB Feather), and it mostly works but I still have more work to do on it, and i'm afraid of missing key changes when typing a little fast. I kind of wish there was a C keyboard driver that delivers a queue of events with timestamps (for each report change), keypad style.

slender iron
austere acorn
#

agreed! 😄

#

smt32H750 chip, with 1 MB ram but only 128kB flash
https://electro-smith.com/products/daisy-seed

Electrosmith

Supply Chain: Stable Daisy is an embedded platform for music. It features everything you need for creating high fidelity audio hardware devices. Just plug in a USB cable and start making sound! Programming the Daisy is a breeze with support for a number of languages including C++, Arduino, and Max/MSP Gen~. To get star

#

All my work was getting CP to work out of the external QSPI flash

#

Thanks @slender iron !
I wanted to make sure if it's worth continuing, documenting and publishing my work for now.

#

Gotcha!

#

I will check it out!

#

People on the daisy seed discord keep asking about python support, but with the currently missing audio modules in CP, not sure how useful it would be anyway....

slender iron
#

I'd hope synthio would "just work" once enabled

mortal kernel
#

Thanks all. See ya later.

slender iron
errant grail
#

Thank you!

lone axle
#

Thanks for hosting Jeff, Have a great week everyone!

onyx hinge
#

👋

slender iron
slender iron
#

I'd expect SDRAM to "just work"

austere acorn
slender iron
#

zephyr doesn't have a filesystem itself usually

#

circuitpython needs it though. it is tricky to do both because all of the flash code does need to be loaded into ram (or maybe we figure out how to do split builds.)

manic glacierBOT
orchid basinBOT
manic glacierBOT
#

CircuitPython version

9.2.1

Code/REPL

from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from cycling_power_service import CyclingPowerService
from adafruit_ble import BLERadio
import time

ble_radio = BLERadio()
advertisement = ProvideServicesAdvertisement(CyclingPowerService())
ble_radio.start_advertising(advertisement)

def advertise_ble():
    while True:
        print(ble_radio.connections)
        if len(ble_radio.connections) >...
manic glacierBOT
orchid basinBOT
manic glacierBOT
manic glacierBOT
onyx hinge
#

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/1XVbpKF0WlpLap2RIqy4IgeEOFLTUaBdCRs_qWGoj1Qs/edit?usp=sharing

onyx hinge
#

something I tried that doesn't seem like it's going to work out: I noticed that circup takes a bit of time after downloading the bundles to unzip them. I thought maybe it would be faster if it just extracted files from the zips as needed. And Python has zipfile.Path which can work similar to pathlib.Path...

but iterating over files inside the zip file seems to be a lot slower than iterating over them in the filesystem, to the point that you might as well just unzip them.

though there could be something wrong with my WIP code too

manic glacierBOT
#

Hi, i have tested this on TTGO T-Display-S3 1.9 (16m8m) and the ESP32-S3-DevKitC-1-N8R2

the snippet above is an oversimplified version of what i am running for the total bike computer. With the interface and everything active it uses about 170kb (for TTGO) vs the 60kb (DevKitC) that this sketch is using.

sometimes the device allows me to connect to and then crashing at a third connection and sometimes i can just connect one device

i was using gc.mem_free() to check the memory usage is thi...

manic glacierBOT
manic glacierBOT
#

@dhalbert: I am still working on this, trying to fix a pin-alarm related problem. I found this piece of code while searching for a solution (see: https://github.com/adafruit/circuitpython/blame/d965980a986c44c3048fd744e7112c5dda782288/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c#L31):

    if (_not_yet_deep_sleeping) {
        // Event went off prematurely, before we went to sleep, so set it again.
        gpio_set_irq_enabled(gpio, events, false);
    } else {
        // Went...
jaunty juniper
#

(and have the json be in the zip)

manic glacierBOT
#

I have finished reviewing the 1001 messages for your project. I understood Jeff's remark about compression. It is delicate to apply it during translation; however, a certain effort, which you will notice, has been made to limit the vocabulary while preserving the spirit and meaning of the message.

Very instructive, Jeff. Thank you for these clarifications regarding the construction.

Wishing you a good reception,

Franck

De : Jeff Epler @.***>
Envoyé : lundi 27 janvier ...

manic glacierBOT
manic glacierBOT
#

CircuitPython version

CP 9.2.3 on a Adafruit ESP32 Hazzah

Code/REPL

# The version is for the ESP32-S2 Feather with AHTx0 connected to onboard
# STEMMA-QT connector.
#
import os
import adafruit_connection_manager
import socketpool
import ssl
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import wifi
import time
import board
import digitalio
import alarm
import busio
import adafruit_ahtx0

PUBLISH_DELAY = 60
MQTT_TOPIC = "environmentTopic"
USE_DEEP_SLEEP =...
manic glacierBOT
#

I think that watchdog timeout is intended to cause a safe mode reset, though I'd welcome correction if I'm wrong.

Even if that's the case, it looks like the documentation could be improved here, clarifying what kind of reset the watchdog produces.

By putting code in safemode.py, you can control what happens after various types of safe mode resets:

Safe mode may be handled programmatically by providing a safemode.py. safemode...

manic glacierBOT
#

I really don't know if the WDT code I'm using is really working. It's hard to test if connected to Mu or Thonny. That coupled to the fact that if the WiFi connects correctly you should never have a WDT event. Back in CP 7.2 days the WiFi had issues with fringe located ESP32-S2s where I'd see my loop counter go to zero and I'd know a WDT reset had occurred. However since CP 9.2.1, I update all my wifi connection logic to the new method and now I've never had a WDT event on a ESP32-S2.

This ...

tulip sleet
#

@slender iron when you are available could we talk about C3 problems? Thanks. Maybe you have some ideas:

  1. C3 DEBUG=1 builds in 9.2.1 or later (at least, could also be earlier) don't work at all. They crash early with Guru Meditation Error: Core 0 panic'ed (Instruction access fault). Exception was unhandled.
  2. enabling CIRCUITPY_BLEIO with ESP-IDF 5.3.2 causes a boot loop. Does not crash with 5.3.1 -- I did not test the functionality. I've been looking at the REGISTRATION_FUNCTIONS and any changes in the CMakefile.txt for the bt component -- nothing obvious yet.
    1 is kind of hindering debugging 2 🙂
manic glacierBOT
#

I think that watchdog timeout is intended to cause a safe mode reset, though I'd welcome correction if I'm wrong.

It seems to me that based on my testing on the ESP32-S2 back on CP 7.2 that the WDT did what it said, either RAISE or RESET. A reset always yanked the chain on the reset pin and you got a clean start up. Hence the loop counter in SRAM cleared.

I could see the Safemode being a REPL feature the way that Deep Sleep is simulated in REPL.

mortal kernel
#

@slender iron I've been poking around in Zephyr source to see what BLE support might be there for RP2 and came up empty. Any pointers you can share?

jaunty juniper
#

so I have a freshly installed Feather Huzzah 32 where the Web workflow doesn't seem to run on 9.x (whereas a V2 for example doesn't have that issue), I don't think it is purposefully disabled, can someone who has the board check ?

manic glacierBOT
slender iron
tulip sleet
slender iron
tulip sleet
mortal kernel
slender iron
manic glacierBOT
#

Thank you for doing this! I tested on a Metro ESP32-S2, with some 16k and 22050 wav files. They worked fine. One file had pretty low audio level, and I heard significant noise. I'm not sure if that's leakage or the relatively poor performance of the DAC. I tried the same on a Metro M4 with AudioOut, and it was quieter.

I also tried with an audiomp3.MP3Decoder source. That caused a Hard Fault into safe mode. The audio file is attached (zipped up)
[16000.mp3.zip](https://github.com/user...

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

Okay, I've been digging through the safemode documenation and on the Learn article I see an interesting statement.
https://learn.adafruit.com/circuitpython-safe-mode/safe-mode-reasons

SafeModeReason.WATCHDOG
An internal watchdog timer went off. Something is looping or taking more time than expected. This is not the watchdog timer used for microcontroller.watchdog. If microcontroller.watchdog is enabled to do a reset, it will do a regular reset; it will not go into safe mode...

manic glacierBOT
#

And it times out, it will yank reset and no safe mode. That seems like a bug, but all I can do for testing is put in the safemode.py and see if I can force the reset that way after a WDT happens.

As described in the doc, watchdog timers are not related to internal watchdog errors. watchdog was implemented before safemode.py. You could use WatchDogMode.RAISE (https://docs.circuitpython.org/en/latest/shared-bindings/watchdog/index.html#watchdog.WatchDogMode.RAISE) to raise an exception...

manic glacierBOT
#

So it sounds like this case is really a bug that the WatchDogMode.RESET is entering safemode and not resetting the ESP32. My current test is to enable the watchdog timer again and have the savemode.py to simply do a reset. So if my program is still working in the morning and my loop counter has reset then I know the workaround is working. Then it's up to you experts on how you want to fix it.

#

So it sounds like this case is really a bug that the WatchDogMode.RESET is entering safemode and not resetting the ESP32.

I thought you were saying your test above that explicitly does a 70 second watchdog is not entering safemode. Maybe I'm confused. I want to emphasize that the word "watchdog" means completely different things here. SafeModeReason.WATCHDOG is for internal watchdogs that have nothing to do with wdt.

You can check for a wdt watchdog reset by looking at `micr...

manic glacierBOT
#

Until today, I was not aware of safemode. I used the code:

from microcontroller import watchdog as w
from watchdog import WatchDogMode
w.timeout = 70  # Set a timeout of 70 seconds
w.mode = WatchDogMode.RESET
w.feed()

to force what I thought was a real reset like a power up reset. I think it works on the ESP32-S2, but not on the ESP32. On CP 7.2 it helped me out a lot. But on CP 9.2 I've never had a WDT trigger that I know of on a ESP32-S2. I could test with or without the REPL wor...

#

So this is a change since CP 7.2. I'm testing the version of safemode.py you showed above now. If it works overnight connected to Thonny, then I'll test just connected to USB Power.

I guess I should implement the safemode.py on even my ESP32-S2 that don't seem to even need a WDT. The CP 9.2 wifi connect that changed, to me, is a positive and that is why my ESP32.S2 run for 45 days before the loop count rolls over to 0 instead of ever resetting by WDT.

manic glacierBOT
tulip sleet
manic glacierBOT
mortal kernel
manic glacierBOT
manic glacierBOT
#

So in my original post I listed in the Behavior section that the reason for entering safemode was (TG1WDT_SYS_RESET). I now know this was not from my WatchDog timer code. I did the follow test.
code,py

# SPDX-FileCopyrightText: 2023 anecdata
#
# SPDX-License-Identifier: MIT
import time
import alarm

time.sleep(5)
#This sleep is needed due to a bug

from microcontroller import watchdog as w
from watchdog import WatchDogMode
w.timeout = 15
w.mode = WatchDogMode.RESET
w.feed()

time.sleep(30...
manic glacierBOT
#

This means that my WatchDog timer will reset the system if it occurs and if an internal issue sends me to safemode, my safemode.py will reset the system just like the WDT from w.mode = WatchDogMode.RESET

Yes, that is correct. I tested on a HUZZAH32 and an ESP32-S3 with this test program (modified from yours), which prints out why the board was reset:

import time
import alarm
import microcontroller
import watchdog

# Sleep a bit so we can see the output
time.sleep(2)

print(f"{micro...
slender iron
mortal kernel
# slender iron so AIROC does have BLE support in Zephyr?

As far as I can tell, it does. Take that with a grain of salt because I'm basing that on my reading of the code, not an actual working example. The BLE part of Zephyr on CircuitPython is coming into focus for me now. Zephyr has a generic HCI driver that interfaces by various means with a subset of the current zoo of BLE hardware implementations. CircuitPython will interface with this generic driver, obviating the need for port-specific BLE code. Am I seeing it?

orchid cliff
#

Hey guys - I have an "older" Metro M4 Express. I installed 9.2.4, and it seems to be missing vectorio I had 9.1.4 on it, which does have vectorio. The download page does correctly not show it as one of the modules now... No biggie I went back to 9.1.4

orchid basinBOT
manic glacierBOT
manic glacierBOT
onyx hinge
#

(in the user's non-distilled application)

tulip sleet
#

it is not my conclusion. But using micrcontroller.watchdog does not trigger safe mode

#

i agree it was confusing. Sometimes the user posted things that did not happen, which I misread at first

#

that is, the user said "sometimes I get this [below], but that did not happen under circumstance X"

manic glacierBOT
#

DEBUG builds stopped working with ESP32-C3 boards with esp-idf 5.3.x. It causes a crash very early in startup, before main, which appears to be due to serial startup problems. See below for details.

9.1.4 works; 9.2.0-beta.0 (which starts with ESP-IDF 5.3.1) does not.

ports/espressif/esp-idf-config/sdkconfig-debug.defaults was changed between these versions to include:

CONFIG_ESP_CONSOLE_SECONDARY_NONE=y
# CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG is not set

Taking these away, ...

slender iron
#

anyone know what shell is used by python on windows from asyncio.create_subprocess_shell()?

onyx hinge
#

@slender iron def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): self._proc = windows_utils.Popen( args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr, bufsize=bufsize, **kwargs)I tracked through several layers, and I still can't tell you, but it's whatever windows_utils.Popen(shell=True) does.

#

windows_utils.Popen subclasses subprocess.Popen and passes shell= through transparently

slender iron
#

I think I'll jam a test script into our windows CI build to test it 🙂

onyx hinge
#

Changed in version 3.12: Changed Windows shell search order for shell=True. The current directory and %PATH% are replaced with %COMSPEC% and %SystemRoot%\System32\cmd.exe. As a result, dropping a malicious program named cmd.exe into a current directory no longer works.
This note in the docs makes me think it's cmd.exe. https://docs.python.org/3/library/subprocess.html#subprocess.call

slender iron
#

trying to determine if I can do cat and >

#

👍

tulip sleet
#

cmd.exe is pretty basic, not a unixy shell at all

slender iron
#

it looks like it does have > support though

#

I really need a zephyr on windows build CI job

blissful pollen
slender iron
#

thanks @blissful pollen. I'm getting a new windows-zephyr build going on CI

slender iron
#

I can't remember how much of their display stuff we use

onyx hinge
#

not much I don't think. but maybe the content would be a clue how to use the qspi peripheral for displays in the first place. a trail of breadcrumbs to follow

orchid cliff
manic glacierBOT
#

The documentation of the mix parameter is not super clear to me. Please check it over with an eye to whether it needs to be revised with this change, and whether it could be clearer.

The documentation of mix was actually fairly close. I've just added the expected result of 0.5 as to better represent the new implementation.

I noticed the description of decay was different between the constructor and the property. I found the constructor to better represent that property, so I updated...

manic glacierBOT
#

I've discovered that the frequency-shifting echo algorithm has a functionality bug in regards to how it fills the echo buffer during playback.

Currently, it pulls a sample from the echo buffer, calculates the decay, mixes in the input sample, and then iterates over the buffer from its current position to its next position (using the delay rate with bit shifting). If delay_ms is shorter than max_delay_ms, this loop may iterate over 2+ elements of the buffer. If there is data already in ...

blissful pollen
#

@fleet hollow just FYI hoping to look at those PRs soon / this weekend

fleet hollow
#

@blissful pollen It's mostly small stuff, so shouldn't be a big deal. Just getting that echo effect fine-tuned 😸

#

@blissful pollen By the way, I've been doing research into reverb algorithms lately. Seems like it's mostly a mix of comb and all-pass filters which require quite a bit of floating point calculations. I've successfully implemented freeverb (https://github.com/sinshu/freeverb), a public domain reverb effect from way back in 2000, on an RP2040 in arduino-pico. The most I could get out of it was mono output with a sample rate of 8000hz. Any more and I'd drop buffers. Even though it was a bit lo-fi, it still sounded really good. I think there's potential to fork that repo and convert as much of the calculations to 16/32-bit integers as possible. Granted, the RP2350 might handle it like a champ regardless.

blissful pollen
blissful pollen
slender iron
#

would it be weird to have files checked into the REPO that list the modules enabled on a board? that way the stub stuff doesn't need to generate it

manic glacierBOT
#
  • Fixes #8561.

On RP2040, light_sleep_until_alarms() would turn off some clocks during the light sleep by clearing some bits in clocks_hw->sleep_en0 and clocks_hw->sleep_en1. Those clocks are turned off when a wfi() or wfe() happens. But light_sleep_until_alarms() failed to restore the original values of those registers after a light sleep. So the next time a wfi() or wfe() was used, even not during an explicit light sleep, those clocks would get turned off. This caused th...

slender iron
#

@tulip sleet have time to talk CP config this afternoon?

manic glacierBOT
#
tulip sleet
jaunty juniper
#

it would be nice to have a static source of that information other than a file in the cp.org repo

#

(or the RTD docs matrix)

manic glacierBOT
tulip sleet
lone sandalBOT
slender iron
#

the challenge is that it is based on the final zephyr board device tree

jaunty juniper
#

yeah that would require pre-commit check and something similar to make translate

slender iron
#

I'm thinking that I can autogenerate it, put it in boards/ and then when the CI builds the board it'll make sure it is the same

#

but for other uses it can just be read directly

#

(I'm figuring out how to fix the docs build)

#

without installing zephyr and doing a build

tulip sleet
#

is the device tree generated from CIRCUITPY_WHATEVER = ... settings?

slender iron
#

the device tree is generating CIRCUITPY_ setting equivalents

tulip sleet
slender iron
#

device tree is what zephyr uses for config though

tulip sleet
#

but can we generate the device tree from some set of our own settings, and then after that let zephyr run its own config?

#

we don't have to use gnu make variables, we can use something else (though I would hate for it to be kconfig)

lone sandalBOT
tulip sleet
#

e.g. a .toml or .json file generates a .mk file, and/or it generates the device tree

slender iron
#

I'm working to get the build generating a toml file with per-module info

#

I can even add comments for humans about why a setting is what it is

manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

Hi,

@dhalbert Thanks for your quick reply!
I changed it to CIRCUITPY_ALARM = 1 and compiled for the Maker Go ESP32C3 Supermini (my first time compiling circuitpython!)

And it works perfectly - got down to 7uA!

The original adafruit-circuitpython-makergo_esp32c3_supermini-en_US-9.2.4.bin is 1449kB.
With the added ALARM it became 1464kB so I think it worth it!

Attached here in case anyone wants to try (remove the ...

orchid basinBOT
manic glacierBOT
manic glacierBOT
#

I believe this falls into sort of a known issue or expected behavior category, so I'm fine closing it.

That being said, from absolute newest:

Adafruit CircuitPython 9.2.4-4-g5d39e467fb on 2025-01-31; Adafruit Grand Central M4 Express with samd51p20
>>> import board
>>> import pwmio
>>> a = pwmio.PWMOut(board.D8)
>>> a.deinit()
>>> a = pwmio.PWMOut(board.D8)
>>> a.deinit()
>>> a = pwmio.PWMOut(board.D7,variable_frequency=True)
>>> a.deinit()
>>> a = pwmio.PWMOut(board.D8)
Traceback (most...
manic glacierBOT
#

I took a quick look at the Grand Central pins.c and noticed that D8 is actually used by the SDIO databus as one of the SDIO_DATA lines. The SAMD common-hal sdioio/sdcard.c module has an empty never_reset function which if it had any code in it, would probably explain why ctrl-D wasn't releasing the resource. I'm guessing somewhere else in the sdioio sdcard construction the data pins are marked for no-reset and if that's the case, it might explain why a ctrl-D doesn't clear the resource. On th...

manic glacierBOT
manic glacierBOT
manic glacierBOT
#

The version of LWIP used by RP2 builds hangs up internally when it thinks its statically allocated pcb pool or pbuf pool is exhausted. The hang-up manifests itself as a memory error returned by tcp_write. Socket code in CP waits 50 ms and then retries the write. This retry/fail condition persists until LWIP's tcp_slowtmr fires and LWIP clears whatever internal condition made it think a pool was exhausted and continues operating normally for a few frames. tcp_slowtmr is a 500 ms periodic...

manic glacierBOT
manic glacierBOT
manic glacierBOT
manic glacierBOT
#

CircuitPython version and board name

v9.2.2 thru v9.2.4
Adafruit Qt Py S2 with SRAM (product # 5700)

Code/REPL

import time
import board
import displayio
import i2cdisplaybus
import adafruit_displayio_ssd1306  # OLED
import adafruit_ahtx0  # WeAct T&H Sensor
import adafruit_sht4x  # Adafruit sensor

time.sleep(2)  # give me time to open serial window after power

# set up I2C with OLED display & AHT20 sensor
i2c = board.STEMMA_I2C()
displayio.release_displays...
manic glacierBOT
manic glacierBOT
#

See #9965, which was prematurely closed. Copying notes from there. See the first PR for various measurements.

This PR implements the alarm-module for the RP2350 variant of the pico and fixes #9491.

Notes

  • The PR does not use the new power-domains for the RP2350, but uses plain old sleep/dormant modes. An implementation based on powman is something for a future PR.
  • This PR also reimplements light-sleep/deep-sleep for the RP2040. As @dhalbert stated in #9521: "So redefin...
manic glacierBOT
#

Re-based local modifications to the top of LWIP's main line. Performance problems still persist. Preliminary list of bugs in LWIP affecting CP:

  • When a connection is first established on a TCP socket, scrambled code in tcp_input erroneously detects an application rejection of the first frame. This is due to bad arguments sent via the macro TCP_EVENT_RECV. The result is a delayed ACK, sometimes delayed by several hundred milliseconds. Eventually LWIP will deliver the frame and send the A...
manic glacierBOT
#

When a transmission is sent to a TCP socket that is smaller than the TX buffer fill level required to trigger transmission, it will linger in the buffer until a timeout occurs. This imposes a performance penalty on small transmissions and possibly also on the final part of a larger transmission. I'm thinking that this is necessary to avoid sending small fragments to LWIP, but perhaps it can be better tuned by looking at time since last fill in addition to TX fill level.

manic glacierBOT
#

This latest patch switches to dynamically allocating the scratch buffer and also corrects some other problems that I found. One was that the audio quality is very bad in stereo mode with the APLL clock so I switch to using the DEFAULT clock for sample rates over 19600. The DEFAULT clock cannot be used for sample rates lower than 19600. I considered adding logic to scale up sample rates below 19600 by just duplicating the samples 2^n times but I'm not sure if that is necessary. There was also ...

manic glacierBOT
manic glacierBOT
#

Here is a trace showing the first LWIP bug described above.

Client (192.168.1.217:42582) sends a SYN packet to begin 3-way TCP handshake:
<details>
<code>
37.179.473(00.047.302): cyw43_ll_process_packets
37.179.504(00.000.031): cyw43_read_reg_u16 BUS_FUNCTION 0x4=0xbe2020
37.179.565(00.000.061): cyw43_write_reg_u16 BUS_FUNCTION 0x4=0x2020
37.179.595(00.000.030): cyw43_read_reg_u32 BUS_FUNCTION 0x8=0x20928
37.179.626(00.000.031): bus_gspi_status 0x20928 0x104
37.179.656(00.000.030): cyw43...

manic glacierBOT
#

Issue #7613 was tied to BLE being in use, but I can actually reproduce something similar without using BLE.

So testing the code above on a Seeed Studio Xiao and Feather NRF52840 Express I discovered that the sleep times are related to the operating system used. I made the code a little more complex so I can see the time values when it's going well without overwhelming the logs, and see it freeze:

import time
bad = False
while True:
    t0 = time.monotonic()
    time.sleep(0.002)
    t1...
jaunty juniper
#

Is the only way to change the partition table to change a board's sdkconfig ? To build a QT PY ESP32S3 with BLE I had to change mpconfigport.mk, which I expected, but I can then set CIRCUITPY_BLEIO=1 as an argument to make without having to change the board files. Having the same flexibility for partition tables would be nice

tulip sleet
jaunty juniper
#

ah thanks, let me try that then

jaunty juniper
tulip sleet
#

you could use no-uf2 but I think there's no real advantage to that

#

4MB-no-ota is fine