#circuitpython-dev
1 messages · Page 80 of 1
... actually, there are no no-ota UF2 bootloaders? so it doesn't exist?
that's why we're waiting for 10.0 to do this
yeah I was under the impression that the UF2 bootloader needs to match, so I installed with the bin
I didn't think it through 🙂
and I can do esptool.py erase_region 0 0x210000 to keep the drive when updating
(but still erase the flash that will be overwritten to be safe)
there is a partitions-4MB-noota.csv in tinyuf2 which matches, so I could compile that for my own use but eh
Re-based local modifications to the top of LWIP's main line. Performance problems still persist.
Thanks for investing so much time into this problem! So this is an upstream problem in LWIP? Is my interpretation correct?
This performance bug is giving me a chance to exercise my ramlog module, so just for that reason it's a useful exercise. Also, I enjoy shooting bugs that have a number of asynchronously interacting parts.
Consider my entries in this issue to be a work in progress. For example, yesterday I was convinced that a bug in LWIP was causing the performance glitch during a 3-way TCP handshake detailed above. On reflection and some more study I now see that it is not an LWIP bug but instead it is a ...
This may be totally unrelated, but in https://github.com/espressif/esp-idf/issues/14603 I found an ESP32-S2 problem with the old I2C driver. We switched to the new driver, but I wonder if there is a regression of some kind in ESP-IDF or how we use it.
<@&356864093652516868> the weekly meeting will be occuring at the usual time of 2pm Eastern (just under 1 hour from now). You can add your notes to the doc https://docs.google.com/document/d/1XVbpKF0WlpLap2RIqy4IgeEOFLTUaBdCRs_qWGoj1Qs/edit?usp=sharing We look forward to hearing from everyone!
CircuitPython Weekly Meeting for February 3, 2025 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you can’t make the meeting and would s...
@slender iron https://github.com/dhalbert/circuitpython/tree/nrfx-update
This is from 2 years ago. There is a commit for the nrfx repo, not sure what version it is exactly.
- The original idea was to just to start using the
nrfx_*_init_check()routines which they added, kind of on my request, but several years too late. Right now we have our own patches to make the driver inits be idempotent. This would get rid of those adafruit-specific patches. - But as I got into it I found many other changes that made it look like significant work, and I ran out of time. I think maybe the I2C driver changed, or some other driver, and there were other significant changes that required noticeable refactoring on our part.
See https://github.com/NordicSemiconductor/nrfx/issues/43 re the idempotence
The ESP32-C5 is the first dual-band chip with 2.4 and 5 GHz WiFi. I got one of the first engineering samples to show to you.
Because it is based on the C6, we first have a look at this chip. Then we try the new board on 5 GHz. And finally, we use the Zigbee test functionality with Home Assistant.
My second channel: https://www.youtube.com/HB9BL...
I am in favor of discontinuing 8.x
Thanks for hosting Dan, have a great week everyone!
Thanks Dan!
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/1r4p9vARPphE1LlejdCZIOuOJ1eD_ZxGTvukjTnw3Ryg/edit?usp=sharing
CircuitPython version and board name
Adafruit CircuitPython 9.2.4 on 2025-01-29; Raspberry Pi Pico with rp2040
and:
Adafruit CircuitPython 9.2.4-5-g3236a0f200 on 2025-01-31; Raspberry Pi Pico with rp2040
("absolute newest" as of noon PST 3 Feb 2025)
Adafruit CircuitPython 9.2.3 on 2025-01-17; Raspberry Pi Pico with rp2040
Adafruit CircuitPython 9.2.2 on 2025-01-09; Raspberry Pi Pico with rp2040
Code/REPL
import time, board, rotaryio
encoder1 = rotaryio...
LWIP maintains a 250 ms "fast" timer and a 500 ms "slow" timer. These values probably made sense 20+ years ago, but now cause pain by inducing timeouts that are expensive to recover from. Configuring these to 25 and 50 ms resolves the 3-way TCP handshake delay by reducing the delay processing the first data packet to no more than 25 ms.
LWIP memory management is almost infinitely configurable. Of course this is both a blessing and a curse. I've been experimenting with different static alloc...
Update: It appears to get out of hanging if a change happens on encoder2. But then encoder1 does not work.
I tested this with a QT Py ESP32-S2, an AHT20, and a 128x32 OLED SSD1306 display, https://www.adafruit.com/product/4440. I did not attach an SHT41. The I2C devices were daisy-chained.
I could not get it to act up. I also tried a Feather ESP32-S2 with the AHT20 and the display above, and also two FeatherWing SSD1306 displays, 128x64 and 128x32.
I tested both with a code.py that ran immediately and with a test.py that I invoked via the REPL.
Do you have another SSD1306 OLED display you c...
From 9.2.1 to 9.2.2 the big thing seems to be my PIO re-org to support the high pins on rp2350b (#9901). I know there were also changes to interrupts (or was it DMA? which this driver doesn't use-- #9980) but those seem to have occurred after 9.2.3.
I actually ran it (unintentionally) on two different displays but both the same type other than one is white and the other yellow. First one is on my aquarium monitoring setup and was the one I discovered the issue with and took the video (link on the Adafruit forum post). The following day when I put together the same setup on my desk and used the other OLED and it did the same thing.
However, worth noting I was using the same Qt Py S2 for all testing. The first time playing with it I had ...
if I recall correctly I did the lwip implementation before we had tlsf. I think having it allocate via tlsf is an interesting idea and could be worth pursuing.
OK just performed a full erase, update bootloader (18.2 to 20.1), load CP v9.2.4 UF2, copied the code above from here into MU, and used Circup to install the ssd1306, ahtx0, and sht4x libraries. I didn't put anything else on the board. It still behaves the same.
A new thing I noticed, which I think I forgot to try before, is if I initialize all three, it also runs normally. Comment out the SHT41 initilization line 17 and the OLED+AHT20 combo starts crawling again.
The main difference betwe...
Sorry for another follow-up. When I measured the I2C bus total pull up it isn't make sense. Then I realized while the AHT20 has its own pullups, they are not in parallel with the rest of the bus because the onboard LDO between 3.3V input and 3.3V output on the board. So total pull up value for all three devices measured while disconnected from the S2 is a bit over 6.1k which is a reasonable value. Just wanted to mention it for completeness. However since I never unplugged any of them and only...
It is true I am doing a daisy-chain but the daisy-chain is really just parallel, like your STEMMA/QT breakout. Electrically it is the same except for the wire lengths. This is the program I am using, really the same as yours. I just commented out the SHT4X() and it didn't help.
If you have another SSD1306 display I would say try that.
I have heard of counterfeit SHT30 boards but not AHT20.
import time
import board
import displayio
import i2cdisplaybus
import adafruit_displayio_ssd1...
I have heard of counterfeit SHT30 boards but not AHT20.
Well I wouldn't call it a counterfeit. It is a custom board made by WeAct using the same 3rd party's AHT20 sensor. If WeAct had simply taken the Adafruit PCB design and reproduced it verbatim, that would be a counterfeit. Designing their own PCB around the same 3rd party sensor is not.
On the OLED subject, I only have the two OLEDs of the same design. While I love Adafruit products, and try to support you guys by buying as much A...
I should have been more precise. I have worked with users who had boards that seemed to have counterfeit SHT30 chips (they acted oddly and/or had different I2C addresses). I have not heard of a counterfeit AHT20 chip.
(Adafruit's boards are open source. The layout can be copied. If the board is marked as Adafruit, then that's counterfeit. But if it's the same design, but does not pretend to be Adafruit, it's just a copy.)
Do you have any other sensor boards that provoke this slow behavio...
There are dozens of variations of these boards - all the details are nicely spelled out here:
https://github.com/rzeldent/platformio-espressif32-sunton/blob/main/esp32-8048S043R.json
Instructions for getting many of them working with LVGL can be found here too: https://github.com/lvgl-micropython/lvgl_micropython/discussions
Ah gotcha on the sensor chip being the part you meant that is counterfeited. For whatever it is worth, I have that same WeAct sensor on 4 long running setups (all running CircuitPython code) and was using another on a temporary test running a Qt Py with a lipo using an Adafruit Charger BFF running Wippersnapper. I haven't had any issue with them up until the recent Qt Py S2 update to 9.2.4. Two of the other three besides this one are S3 boards and no problems. The remaining one is an Adafruit...
Could you give a sample URL for the display you bought? I'll see if there's anything unusual about it.
@rgov: you could test the artifact of PR #10023. This will use dormant mode without reset for lightsleep like you suggested. According to my measurements, we are now in the same range as the blog-post claims for MicroPython.
(gdb) where
#0 _transfer (data_out=<optimized out>, out_len=0,
out_stride_in_bytes=0 '\000', swap_out=false, swap_in=false,
in_stride_in_bytes=1 '\001', in_len=536939816,
data_in=0x20080dd7 "\020l\344\n\020d\344\n\020\020\n\001 \r\001 d\344\n\020l\344\n\020\254\377", self=0x20010d28) at common-hal/rp2pio/StateMachine.c:984
#1 common_hal_rp2pio_statemachine_readinto (self=self@entry=0x20010d28,
data=data@entry=0x20080dd7 "\020l\344\n\020d\344\n\020\020\n\001 \r\001 ...
Do you have an oscilloscope or logic analyzer so you could check the SCL clock frequency or otherwise compare 9.2.1 with later versions?
@jepler @bablokb In combination with LWIP periodic timer change, using tlsf for all of LWIP's memory needs nails it. I'm now seeing the original performance report running in about 700 ms. This also appears to fix intermittent "unknown error" reports from networking components. It also reduces the RAM footprint for LWIP significantly. Since this is a change that affects all CYW43-based networking on the RP2 port, I'll be submitting a pull for discussion and testing shortly.
I wrote some code so that I didn't need any encoder knobs for testing.
# Test simulated encoder (issue #10024) for metro rp2350
# Connect jumper wires from RX/TX/D2/D3 to A0/A1/A2/A3
# Each encoder should count.
import board, rotaryio
import digitalio
d = digitalio.DigitalInOut(board.D0)
d.switch_to_output(False)
e = digitalio.DigitalInOut(board.D1)
e.switch_to_output(False)
f = digitalio.DigitalInOut(board.D2)
f.switch_to_output(False)
g = digitalio.DigitalInOut(board.D3)
g.switch_to...
.. for duplicate programs, like two IncrementalEncoder instances.
Closes: #10024
Also removes a workaround that's no longer needed after a pico sdk update.
git push --force-with-lease will force but only if your local copy of the branch matches the remote one.
I didn't perform any testing but the changes look like they should have addressed the memory usage problem. Did your testing include playing an mp3 file?
Thanks for working on this. I don't want to change the behavior of light sleep though.
I don't want to change this now. If we want to, then we should do it on a major version boundary.
I'd prefer that this PR only turn peripherals off if they aren't in use, which matches the current suggested behavior. If you want to sleep with things off, then you need to turn them off using deinit.
WeAct Studio has a storefront on everyone's favorite Chinese site ;) and here is the specific sensor listing https://www.aliexpress.us/item/3256806723829530.html
I don't own a scope, nor logic analyzer, of my own, but I am sure I can borrow a scope from work (not sure what we have for logic analyzers). Another "perhaps this weekend" task.
This would make light-sleep more or less an alias for normal time.sleep() and therefore useless for anybody running on batteries. The idea of this change is to provide a viable option that is much better. Current light-sleep for the Pico-W is at 60mA - nobody needs this kind of a "sleep", anybody who is using it is tricked by the naming of the api suggesting something different. Anybody who wants everything working while sleeping (which is actually a self-contradiction) should use time.sl...
Light sleep can wake up after other events besides time duration. It isn't the same.
CircuitPython should track if anything is in use and vary how it sleeps depending on the state.
I don't want code to resume in a different state than when it entered. If I start audio and then light sleep it shouldn't turn it off, even if that means it doesn't save as much power.
This port is meant to grow to encompass all existing boards. For now, it is a port while we transition over.
It is named zephyr-cp to differentiate it from the MicroPython zephyr port. They are separate implementations.
@tulip sleet you ok reviewing the zephyr port PR? I'll un-draft once the CI is ok
If you have audio running, then time.sleep() does exactly what you need - it does not save much power but everthing including audio keeps running. Perfect and wonderful! You don't loose anything by switching from fake light-sleep to normal sleep. You don't need fake light-sleep in this case. It does not save anything for you.
Aand of course you could also spin-wait on a GPIO if you want, that is basically what fake light-sleep currently does.
So there is a good alternative without dra...
I am going to take the discussion out of the code comment, and probably repeat some stuff from #9521.
I will take the blame for the original "light sleep" name, in #3767. I was looking at the Espressif model of light sleep, which did shut down wifi. Eventually we decided we didn't want it to do that, or shut off other peripherals: we just wanted it to sleep as innocuously as possible, without shutting down anything that was in use, but still saving some power. Sometime after that we figure...
@slender iron what graphics mode should feather rp2350 dvi come up in if it detects a monitor is detected? Right now I coded 320x240x8bpp but that's an arbitrary choice.
I think limor suggested 320x240x16bpp
OK, I can do that
maybe not if it doesn't leave much ram left
I'm testing with a feather I soldered psram to so that's not a good test
maybe it should be less if there isn't psram?
>>> import gc
>>> gc.mem_free()
335056
```If it's without psram, the 8bpp mode leaves 335k free
@16bpp ```>>> gc.mem_free()
261328
This update resolves issue #9837. It makes the following changes:
- Updates the lwIP stack to its current top of main. Update is necessary to support fully dynamic memory allocation. This involves re-basing a local change. For now it's on a branch in my private repo: https://github.com/eightycc/lwip/tree/circuitpython9.
- Updates lwIP periodic timer configuration from 500/250 ms (slow/fast) to 50/25 ms. This improves network performance where the large timer intervals were inducing retr...
@bablokb Forgot the pre-commit hook in my repo, but the build artifacts should be fine. Please give it try.
This should be considered an RFC. Some bits should probably be moved to common code & tidied up.
If connected to a HDMI monitor, an eeprom will be on the i2c bus with address 0x50.
When it's found, configure the display to 320x240x16 (default), or to user settings. Invalid user settings cause a safe mode with a misleading error: "Heap allocation when VM not running." This is because common_hal_picodvi_framebuffer_construct throws an exception for invalid parameters (width, height, and c...
I'm not arguing to keep the same implementation. I'm arguing to keep the API the same.
The light_sleep_until() implementation can be improved to get the lower power states that @bablokb wants without changing the API contract. It requires additional code to track which peripherals are active and only turn off the switched domain when none are in use. It will require that folks who want low power to track what is init and deinit it around the light sleep. Folks who don't track power could...
Any objection to moving core python file lint and format to ruff? That matches MP
is this something that changed since the last merge?
MP changed it in 1.22. My zephyr PR changes requirements-dev.txt which causes a cache miss for black and then fetches a newer black. So I'd rather move to ruff than a newer black
huh, we merged 1.22.2 in before 9.2.0, so I don't know why we didn't get on the ruff train then
so yeah go for it!
Yes, I tested with the mp3 that @dhalbert provided along with several other ones.
Probably different CI setups
Verified that fix https://github.com/adafruit/circuitpython/pull/10025 does make two encoders work on RP2040 Pico and RP2350 Pico2.
Thanks for testing @todbot !
I am asking about the display, the OLD SSD1306 board.
Duh! Sorry. Me read gooder. ;)
Not that the colors matter much but the white one I bought here...
https://www.aliexpress.us/item/3256806808213099.html
and the yellow one here...
https://www.aliexpress.us/item/3256806186748120.html
I found a display (generic, not Adafruit-branded) just like that in my collection. It works fine. So I think it's something about the AHT20. Given that taking that away with all other combinations fixes the problem, it's causing a stall of some kind apparently.
Oddly though it does work when I initialized all three (OLED, AHT, & SHT) which is just weird.
Well if you can't reproduce it, I guess for now we can leave it be until new info comes up from someone else or if I pick up an Adafruit version of the AHT20 I will report back. For now that setup is running 9.2.1 which works and if I ever need to update it further I can switch to an S3 or perhaps just throw a TFT at it. This issue isn't a critical one for me so I can work around it.
Thanks for l...
One more thing to try:
import busio
#...
i2c = busio.I2C(board.SCL1, board.SDA1, frequency=400000)
#...
It may work better at higher or lower frequencies. If not at 400000, try 200000, and 50000. 100000 is the default.
Note that you have to use SCL1 and SDA1. SCL and SDA are not connected to the STEMMA/QT port on the QT Py ESP32-S2. They make a separate bus connected to the SCL/SDA pins on the board edge.
I would keep it simple: add an optional aggressive=False parameter to light_sleep_until. And document that anybody using aggressive=True is in charge of testing peripherals and re-initializing peripherals as necessary.
It would also be interesting if we actually know what we are talking about. I only know of wifi not being connected after light-sleep. But this is not fundamentally different to what you have today: if you light-sleep long enough, your router will also disconnect you s...
@slender iron I'd like to push a branch from my private lwIP repo to the Adafruit lwIP repo. This is an update of lwIP to top of main with a local Adafruit modification rebased and applied. How to proceed?
just make a PR to that repo
@mortal kernel I assume you mean your public fork of lwIP? I don't think PRs can be made from private repos into public repos.
When I have done work in circuitpython that needs changes to a submodule, I've created a PR into the adafruit fork of the submodule at the same time as I created a PR into circuitpython. The circuitpython PR points the submodule at the unmerged PR.
After everything is approved, the submodule PR is merged and the circuitpython PR is updated to point to the tip of the submodule's main branch before it is also merged.
When applicable, I also create a PR upstream. For instance, if you're fixing an outright lwip bug that exists upstream, it's good practice to also PR the fix into the official lwip repo.
boy lwip doesn't make a lot of releases, do they. 2023, 2021, 2018...
oh and call out and link the submodule PR when you make your CP PR
@onyx hinge and @danh Thanks for the tips! I've submitted my PR (#1) to adafruit/lwip. I re-synced my personal public origin repo to lwip_tcp/lwip , branched it, and then re-based the Adafruit secondary host support on top of the current top of master. Hopefully this will merge properly.
Once that's merged, I'll update my CircuitPython pull to point to the new circuitpython9 branch.
lwIP looks like it has one lonely dev.
awesome thank you @MarshallMiller !!
Ok, I've merged it into adafruit/lwip. Looks like they are about to release 2.2.1 too.
Using PR artifacts, simple non-TLS HTTP response on Pico W HTTP is now consistently under 50ms (ranged from 30-250ms with 9.2.4), on Pimoroni Pico Plus 2 W it's now 15-25ms (also ranged from 30-250ms with 9.2.4).
HTTPS on Pimoroni Pico Plus 2 W is now 1-2sec. Slight improvement from 1.5-2.25sec.
HTTPS on Pico W now times out rather than [getting](https://github.com/adafruit/circuitpython/iss...
Thanks Dan, I will give that a try later. Also, I had to make a DigiKey order this morning so I threw in an Adafruit AHT20 breakout board on there, so I will try that first and see how it acts. If it acts normal then that indeed points to the WeShare version & I will then try your last suggestion on the clock speed. On the other hand, if it slows down as well, then we have a mystery why my setup slows and your nearly identical setup does not. Anyway, I will post back when I get new informati...
@anecdata Thank you for testing this out. Much appreciated. Where this update should also help is with stability and throughput. Switching to all dynamic allocations for lwIP reduces the static RAM size from 116K to 72K, good for the memory-constrained RP2040. Of course lwIP will consume memory for control blocks and buffers, but how much memory that costs depends on the app, not on a guess of the size of a given static allocation pool. We were blowing through some of the static allocations i...
hug report to eightycc for working on that lwip stuff!
This is stupendous work! (I started reviewing last night.)
I do not see anything to change. I was wondering about whether some of the commented-code in the networking files could be deleted (some things are implemented), but even if so, that can be done on a later pass.
We can get the stuff in the zephyr-cp README into the Building CircuitPython guide sooner or later.
I did not review all the ruff formatting changes in the inline doc or various .py files, which files were affected ...
Thanks for working on this! I'm very excited for a CP computer.
I'd return mp_const_none instead. That way the check can use an if instead of try/except or hasattr.
Do we want to check this more often than on init? Is it ok electrically to hotplug the connector?
Want to pre-verify it? Or you could make framebuffer construct return a status code instead.
Let's not add an additional parameter. Instead, let's vary the behavior on if the wifi is active or not since that's what you are aware of. Other peripherals that get deinit can be bugs we fix when it comes up. I know it's tricky to check all of that up front.
I'm continuing work on the networking stuff so the next PR will replace it all. Thanks for the review!
I like the idea of factoring out the "check resolution details" code and calling that to pre-check. will also update the docs, leaving this note in place until I do that.
no idea. @ladyada is hot plugging the monitor OK? would it make sense to check this for instance just before each time code.py is run?
@slender iron on feather rp2350 (with my changes?? could it matter?) I am seeing the display go blank during flash read/write. I didn't expect that to matter, since isn't it all the code supposed to be on core1 and the framebuffer in SRAM so nothing can stop it or slow it down?
this is one that I soldered PSRAM onto fwiw
we decided in our internal meeting to only check at power on. A user can hit reset or have their code.py create the display object if they really want to hot plug.
@devout jolt it randomly occurs to me you should be able to do 12x rotary encoder on rp2350 now, 4 on each of the 3 PIO peripherals.
Nice! I can resurrect this project! https://github.com/todbot/pico8enc (I did get it working on RP2040 by creating a DualIncrementalEncoder pio-based class
too few pins to do the switches though, unless you use rp2350b
I forget why you couldn't get to 8 on circuitpython without modifications
could use 4051 mux for the switches 🙂
with rp2040
ran out of statemachines if I also wanted to do Neopixel
oh a neopixel too. yeah.
and i2s audio needs one state machine as well. because how could you NOT do audio on the next one.
so 10 knobs + i2s + neopixel. you know, after you're done with all your other ideas
sounds like a fun time ahahah
CircuitPython version and board name
Adafruit CircuitPython 9.2.4; Pimoroni Pico Plus2 with rp2350b
Code/REPL
import audiobusio
import audiodelays
import board, time
import synthio
SAMPLE_RATE = 48000
AMPLITUDE = 0.2
MIX = 1.0 # Would need to be 0.5 if #9994 is merged
TIME = 40
DEPTH = 8
RATE = 1.0
OCTAVE = -1
audio = audiobusio.I2SOut(
bit_clock=board.GP0,
word_select=board.GP1,
data=board.GP2,
)
synth = synthio.Synthesizer(
sample_rate=S...
Hi, just wanted to follow up to see if there's changes to be requested on this feature. I added some commits a few months back to address the concerns you've expressed so far. I know you guys are busy, let me know how I can help or if there's something I missed!
maybe an interrupt is blocked? I'm trying to remember if there is an interrupt between frames
To be honest, this is getting too complicated for me and I still believe it misses the real target use case of low-power systems. From an academic perspective this "keep things running that are running"-mantra might be ok, but from an economic perspective it is not. Somebody has to sit down and implement this logic, either up-front or after bug-reports as you say. And this is beyond my reach and my time.
So I am leaving the stage, happy with my Pico2W running at 1.8mA instead of 60mA durin...
Tested this with the original setup. Page load with 9 requests is now down to about 1.2s (ranging from 1.1-1.8, repeated loads are mostly below 1.2s). So this is a huge improvement.
I also repeated the iperf3-test. Throughput is up from 389 Kbits/sec (see #9837) to 3.95 Mbits/sec now.
Do you see any chance that I could backport this to 8.0.5? I know this is a very old version, but I need it due to memory constrains (independent of network use). 8.0.5 has 152K to start with, while 9.2.4 ...
@bablokb Thank you the tests! This update depends on tlsf so it won't work with CP versions earlier than 9.0.0. If you haven't already, give this update a try on the Pico W. It reduces the static RAM footprint substantially, so hopefully your app will fit without resorting to backporting.
@tannewt Please move this PR out of draft status and review.
The following issues may benefit from this PR: #9576, #8017, #9124, #8799, #7318, #9150, #9127, #8964, and #8115.
stdbool appears unneeded here, as bool isn't used in these prototypes.
we would prefer to use the name "main" if we're not going to use "circuitpython9". An Adafruit person can update the "default branch" name in github options if that's needed.
Let's go with cricuitpython9 for the branch name. Would you like a new PR to adafruit/lwip?
Check. Left over from a tlsf under tlsf experiment that went badly.
If you haven't already, give this update a try on the Pico W. It reduces the static RAM footprint substantially, so hopefully your app will fit without resorting to backporting.
Good point. Just checked: the PR-artifact has 128K available, 9.2.4 has 71K available but 9.0.0 was at 125K. What in the hell did they add in between?! The 125K from 9.0.0 were about 7K short (even without any networking, wifi never imported). So maybe if I can find and remove the bloat from 9.0.0 to 9.2.4 it mig...
@bablokb That's interesting. There could be another library using static allocations that got added or reconfigured after 9.0.0.
According to https://git.savannah.gnu.org/cgit/lwip.git, it looks like lwip 2.2.1 was released yesterday??
According to https://git.savannah.gnu.org/cgit/lwip.git, it looks like lwip 2.2.1 was released yesterday??
Crazy coincidence or preternatural foresight?
CircuitPython version and board name
Adafruit CircuitPython 9.2.3-17-gfe23bd7cf8-dirty on 2025-02-04; Adafruit Metro RP2350 with rp2350b
Code/REPL
import board
import picodvi
import displayio
import framebufferio
displayio.release_displays()
fb = picodvi.Framebuffer(320, 240, clk_dp=board.CKP, clk_dn=board.CKN,
red_dp=board.D0P, red_dn=board.D0N,
green_dp=board.D1P, green_dn=board.D1N,
...
It looks like picodvi on rp2350 uses an IRQ on core0 to start the frame via irq_set_exclusive_handler(DMA_IRQ_1, dma_irq_handler); in common_hal_picodvi_framebuffer_construct which is running in core0. So, it's expected that flash writing blocks this irq. we'd need to place the irq handler on core1 for this to work. or else not fully block this specific interrupt during flash writes, as it should be safe.
CircuitPython version and board name
Adafruit CircuitPython 9.0.5 on 2024-05-22 Adafruit Feather RP2040 with rp2040
Code/REPL
ValueError: incompatible .mpy file
Behavior
mit haystack observatory
rps 2/6/2025
done in the attempt to save memory space for execution
$ python3 -m mpy_cross ~/eclipse/gps/staging/gnss_imu_mag.py
import gnss_imu_mag as gim
gim.my_main()
Description
I'm looking for a version of mpy_cross that works wit...
Find a recent version here: https://adafruit-circuit-python.s3.amazonaws.com/index.html?prefix=bin/mpy-cross/
Look in the operating-system-name directories at the top for a 9.2.x version.
mpy-cross doesn't change much. Any 9.x.x version should be ok.
thank you, I'll close after I get it running
this works, thank you.
The URL that I initially used for the circuitpy "welcome" was not the same as the one in dhalbert's reply,
that one had a broken link, with led to googling and finding many dead ends.
However, its all good in the end.
thank you!!!
I've tested the proposed fix, and it doesn't appear to resolve the issue. I've also toyed around with a few other adjustments to no avail. Any ideas as to why this could be happening would be greatly appreciated.
@onyx hinge Following up on your review comments, I'd like to create a PR to push a new circuitpython9 branch from my public repo (https://github.com/eightycc/lwip/tree/circuitpython9), but github won't let me do it.
undo! mpy-cross from the URL in the previous reply is still out of date
I tested against the .py file, not the .mpy file
./mpy-cross-macos-11-8.0.5-x64 ./gnss_imu_mag.py
the build runs but the import returns the same error:
mit haystack observatory
rps 2/6/2025
done in the attempt to save memory space for execution
$ python3 -m mpy_cross ~/eclipse/gps/staging/gnss_imu_mag.py
import gnss_imu_mag as gim
gim.my_main()
the rp2040:
0;?🐍Done | 9.0.5soft reboot
Auto-r...
hi,
the date of the mpy_cross file is 2023, circuitpy v8 was still prevalent 2 years ago
the "forums" link in my first post pointing out the problem was dated from february a year ago.
Please look inside these directories, as listed below and at the top of
https://adafruit-circuit-python.s3.amazonaws.com/index.html?prefix=bin/mpy-cross/
The 8.x.x builds at the top leve are out of date, yes, but don't use those:
../
0 linux-aarch64/
...
thank you again, I'm all set for sure this time
this is what happens when I work in panic mode before taking a break for lunch lunch
This is from https://github.com/circuitpython/web-editor/issues/266
Would like a way to do the equivalent of setting
wifi.radio.hostname="newhostname"prior to callingwifi.radio.connect(), but viasettings.tomlso that the CPy dhcp client requests "newhostname" along with requesting an IP address. This way it would take effect when using web workflow.I tried assigning to CIRCUITPY_WEB_INSTANCE_NAME but that didn't seem to affect what hostname the dhcp client requests. Presum...
PRs update automatically with the state of your branch
I try not to post before breakfast, same idea :)
And this is beyond my reach and my time.
Totally understandable. Thanks for getting it this far!
Hopefully we can find someone to finish this up soon.
Looks like common_hal_mcu_disable_interrupts guards flash writes:
We could have it mask by priority and set the DMA interrupt so it is higher. We need to ensure it can run without flash then though.
I don't think running on core1 helps because we're trying to avoid accessing flash by disabling interrupts.
The last PR I submitted to adafruit/lwip wound up on the master branch where what I really wanted was for it to become a new circuitpython9 branch. I see that happened because github's pull request generator selected master as its destination. Trying to fix it with a new PR, I updated the circuitpython9 branch in my public repo to include the 2.2.1 release commits. but when I try to create a new PR github refuses to allow me to select circuitpython9 as the destination. I'm missing something obvious, but I'm not seeing it.
Please document mosi_packet too. Is the expectation that this memory isn't mutated after the function call?
Please include a basic example here so that we can see what the API use looks like.
//| def wait_transfer(self, *, timeout: float = -1) -> bool:
I think I'd call this wait since it doesn't initiate the transfer.
I think you'll want to store the buffer objects here while a transfer is in progress. If you don't the garbage collector may clean them up while a transfer is in progress.
Thanks for the ping! Sorry for not getting back to you. I was on leave last fall (and will be later this year again.)
Please ensure the CI tests are passing too. That way we can merge if it is ready.
PRs don't bring in a new branch name. They merge changes from one branch (your cp9) to another (adafruit/master). Why do you want a different branch? adafruit/master is the one used by circuitpython and there is a separate lwip master that we can reference.
I was following the pattern I saw in the lwip repo: the Circuitpython mods were on branch circuitpython8. @onyx hinge called out the use of the name master, so I thought it would be logical to put the rebased local mods on circuitpython9.
ok, I'll change it directly
Investigate possible workaround mentioned here (setting clock stretching timeout to max): https://github.com/espressif/esp-idf/issues/2551#issuecomment-2586345597
Thank you! Sorry for the kerfluffle.
np
thanks for fixing it up! would you mind updating to 2.2.1 proper?
probably just the changelog update but it'd be nice to know it is a released version
thank you @mortal kernel, I appreciate you being responsive even about minutae!
I was having trouble with pre-commit always finding files to change, because the ruff run during two different steps of pre-commit were different.
Installing the requirements with pip install -r requirements-dev.txt didn't resolve the problem, because the ruff version was not pinned. So, pin it now.
Makes sense , since pre-commit-config.yaml requires explicit versions.
By placing certain fields in a fixed location in all sample types code can be reduced & reused. For instance, the same property object can be used for every sample type's sample_rate property.
The sample proto functions like sample_rate become superfluous since once an object is verified to support the audiosample protocol, direct access to the fields in the base object is possible.
However, it's necessary to carefully initialize all the new fields. Some sample types, like Synthesiz...
This also helps set the stage for #9877: The data for managing the first/second buffer would be placed in the common structure, and the logic in the wrapper to get_buffer. Then, the individual sample implementations need no longer care about the single channel case.
interesting, some espressif boards have audiomp3 enabled but no audio output enabled. This used to not be a build error, but in #10036 it is.
That's interesting. I really like that PR (I'll take a look at it later in more detail). I was actually wondering earlier if it would be possible to also remove the memory buffers we use to buffer audio in many places to one object they could all share.
I'm not exactly sure how that would work. Has the RAM size of these buffers been an issue in practice, or is it more a theoretical benefit?
the other thing I'd say in retrospect about the new audio functionality is to consider whether it REALLY needed to work on anything but 8-bit signed samples. but it may be too late for that now, until version 10.
Just theoretical at the moment.
8-bit or 16-bit? I was thinking about that as well.
8-bit 16-bit
It would make the code cleaner, and it would not be hard to write a 8 to 16 bit converter effect or vice versa
CircuitPython version and board name
Adafruit CircuitPython 9.2.4-7-g1c0b37e504 on 2025-02-04; Pimoroni Pico Plus 2 W with rp2350b
Code/REPL
import board
import rotaryio
import time
encoder = rotaryio.IncrementalEncoder(board.GP15, board.GP14)
while True:
time.sleep(0.1)
print(encoder.position)
# Code to test output of encoder using digitalio
#
# import board
# import digitalio
# import time
# encoderpin1 = digitalio.DigitalInOut(board.GP14)
# e...
I just verified this on Pico 2 RP2350. The issue is with the series resistors. Having the external pull-up resistors and the filtering caps are fine. Add the series resistors and rotaryio stops registering pulses. Use 1k resistors instead of 10k and it works. (Seems almost like this is somehow related to the RP2350 E9 errata)
On Pico RP2040, rotaryio works in all cases. Adding the series resistors or any of the other external components in that filter circuit does not affect functio...
That's interesting. There could be another library using static allocations that got added or reconfigured after 9.0.0.
I retested and it turned out to be a wrong assumption about what happens when entering the REPL. I used this code:
import gc
print(f"free memory: {gc.mem_free()}")
from the REPL and from code.py. Depending on what happened before you enter the REPL (with CTRL-C), results are extremely different. So running from code.py 9.2.4 gives me 138K and your PR 183...
This PR removes the one second delay before the initialization of the CYW43. I don't think it is necessary, since nobody else is using a delay. Neither MicroPython nor any of the examples distributed by the RPi foundation (pico-examples, pico-extras and so on). I also searched the net and did not find any code that adds this delay.
Removing it cuts the boot-time of the Pico-W by almost 50%.
@todbot thanks Tod! Your work around should be easy to do on the PCB just need to desolder those resistors and replace with a wire. Will try tomorrow.
cyw43_spi_reset() implements the correct delays around powering down then up the CYW43's WiFi section during initialization in cyw43_ll_bus_init(), so this patch looks good to me. Maybe @jepler has some insight into the circumstances around adding the 1 second delay?
We added it in https://github.com/adafruit/circuitpython/pull/7313 to fix a problem reported in #7112.
I never saw or reproduced the problem, and we have no real idea how many boards/chips might be affected. However, we had at least 2 community members in that thread reporting a problem that the delay appeared to fix.
I do not know what we would do to be confident that it was OK to remove or decrease the delay, unless someone had in hand a device that reproduced the problem.
Thanks @wtuemura and @andibing!
@anecdata The RP2350 has hardware acceleration for SHA-256 controlled by MBEDTLS_SHA256_ALT, but it doesn't appear to bot active on in CircuitPython builds for the RP2350. This will impact HTTPS timings. I'll look into it more deeply and submit a PR if necessary.
There is a merge from MicroPython on Oct 16, 2023 that defines CYW43_EVENT_POLL_HOOK (see https://github.com/adafruit/circuitpython/blob/d7886450267b4fc04e910549facd021b3372b3fa/ports/raspberrypi/cyw43_configport.h#L21).
And according to the cyw43-driver source, this hook is necessary to perform background tasks "during long blocking operations such as WiFi initialisation". So this sounds like the solution of the initial problem #7112 (which hints at USB-devices not enumerating correctly...
This just delegates to .deinit().
Also, reuse identity_obj for default __enter__.
Saves about 800 bytes on metro rp2350.
I do not know what we would do to be confident that it was OK to remove or decrease the delay, unless someone had in hand a device that reproduced the problem.
Thanks for the background info. Starting up the CYW43 is touchy. I'm now convinced we shouldn't change it.
Neat!
Some have
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
and some are
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
Are these the same thing? Should there be just one choice?
The one-second delay came from a test UF2 I gave to one of the folks in #7112. It was meant to make it completely clear that a delay would help. There is some looking in that issue at the CYW43 datasheet where it looks like 85 msec is the startup time. But the real test is to find a Pico W that fails without the delay, and then experiment. I was unable to reproduce the original problem, so it seems sample-based.
Perhaps we could remove the delay and replace it with a retry of cyw43_arch_init_with_country() on a fail? For testing purposes, I'm thinking we can force a failure by decreasing the delays cyw43_spi_reset().
If I read #7112 correctly, the OS did not see the Pico-W, probably because the USB-enumeration failed. But now, after merging MicroPython as linked above, that should not happen again because usb_background() takes care of this?!
Just to give you an idea why this 1s delay is important: I am running a project which does long-term environmental monitoring in schools in Africa, far away from any wall-plug. With all kinds of tricks we can now run about 2 years on a pair of AA-batteries. Curr...
That's a good question! I used a #define so that default___enter___obj is now mp_identity_obj but I could just change all the references. Or, I could change the few that use mp_identity_obj directly to use the macro, just for consistency.
(I suspect but don't know for sure that mp_identity_object might have been added later after we added default_exit_obj)
It's super sus that this didn't build any boards! ci_set_matrix found the changed files but decided not to build any board...
aha I figured out why ci_set_matrix wasn't building what it should. 😰 that script gives me cold sweats whenever I look at it, but I think I can fix this problem.
is default___exit___obj a macro too? I guess I'd just make it consistent, one way or another
No, default___exit___obj is a function object, just defined in a central spot.
Recently in #10026 this script was altered so that sometimes items are removed from boards. However, this could have side effects. For instance, when a file like shared/runtime/context_manager_helpers.c is modified, it doesn't match any per-port or per-board rule so we execute boards_to_build = all_board_ids. But if the object all_board_ids refers to has been modified by boards.remove(board) in an earlier iteration, then we don't end up really building all boards.
Noticed during ...
a macro is OK. It's nice that default___enter___object and default____exit___object have analogous names. Principle of least surprise. I'd use those names.
makes sense to me as well. I'll change the existing sites that are definining the __exit__ method from mp_identity_object to default___enter___obj for clarity & consistentcy, even though the latter is a macro that expands to the former.
Thanks for figuring this out!
yup, me too. I was surprised when a header file change didn't trigger any rebuilds
I was glad to get to that "aha" moment
I wonder if 10 pre-releases should be minor branches off 9.x stable that changes the partition layout
I don't think we want a hard branch because there aren't that many additional changes
or maybe we do 10 as a small and quick stable release
Thank you! I may have run into this too.
What did they add in between?!
USB Host was added and it has code that needs to live in RAM (so it can run while flash accesses happen). We don't load it when we need it so it's always there.
we have to do the TinyUF2 builds with the new partition tables first, and give them some clear names. Not sure if they should be new boards or additional artifacts produced in a board directory. They could be given clearly specified names that point out the difference.
What do you not want to include in 10 that might be in main?
we could have a live discussion about this vs typing
Oops, this should have been a draft because I hadn't tested it on any hw. I will do some basic testing when I'm back at hone, hopefully any problems are minor
@mortal kernel this may of be interest?? https://github.com/micropython/micropython/pull/16623
at least it may point out a potential problem, not necessarily the fix we want
@tulip sleet It may be better as a tinyuf2 issue so thach can weigh in
thanks!
it's probably ok to just switch all 4mb boards to the noota version
release it as a major version bump of tinyuf2 and say it is required for cp 10
but maybe the filenames should have "cpy10" in them so people don't smash their 9.x boards by accident
9.x uf2 should still work with the newer tinyuf2. they just won't take as much space
good point
- as long as ota_0 just gets ota_1 added
not sure what you mean by that
I checked, noota has uf2 and the fat fs in the same location as the ota version
This is one of several statically allocated pools eliminated by going to dynamic allocations in lwIP. Maybe MicroPython should do the same?
you could comment in that PR 🙂
Ultimately, yes.
so if I read right, in theory, a lot fewer of the memory allocation exceptions that people see would be attributable to fragmentation
Not sure about that. The VM takes chunks from tlsf and manages its own object allocations inside them.
ah, ok
TLSF manages a heap outside of the VM. The VM requests chunks of the outer heap to use as its heap.
naive question: why not allocate directly from TLSF?
we'd then have to scan all of the TLSF heap for garbage collection.
right, tlsf requires manual alloc/free
the MP VM does pointer collection to know what is still in use
thanks, that's making some sense
the MP split heap functionality where it grows with use actually speeds up the collect process I believe
Another benefit I've seen is that VM heap can be completely purged without affecting lower-level allocations. I've taken advantage of this in my ramlog facility.
since it can be small when using little memory
@slender iron [I'm writing the issue] we can't do BLE on ESP32-S2, so should we get rid of ota_1 on ESP32-S2 also? I can't remember how short we are on S2 for space
I can't either. I think it is fine to leave. I don't know what else we're going to add to it
The biggest ESP32-S2 Feather builds, for example, have about 20kB free. So we could leave them alone, I think.
does the board def have stuff disabled?
nope, nothing is disabled
I thought -ggdb just controlled whether debug information was generated, not optimization. and that debug information was present in the .elf but not the .bin or .uf2. I wonder why just adding that flag, and not changing anything else, makes this espressif build overflow.
are you adding that directly or via DEBUG= or something?
I agree that's what the gcc doc says
+++ b/ports/espressif/Makefile
@@ -174,7 +174,7 @@ ifeq ($(DEBUG), 1)
# You may want to enable these flags to make setting breakpoints easier.
# CFLAGS += -fno-inline -fno-ipa-sra
else
- CFLAGS += -DNDEBUG
+ CFLAGS += -DNDEBUG -ggdb
What did they add in between?!
USB Host was added and it has code that needs to live in RAM (so it can run while flash accesses happen). We don't load it when we need it so it's always there.
The difference I noticed was actually due to the fact that the REPL does not garbage-collect before it starts - something I wasn't aware off. So nothing was added, the lower RAM was only due to whatever ran before the REPL started.
so maybe the/some debug info is in the .bin?? I certainly used to use strip a lot when doing native compiles.
i think it's a linker question, maybe
lots of functions (according to nm --print-size) get bigger with -ggdb. for instance, mp_obj_str_binary_op grows by 84 bytes for .. some reason
(gdb) disas app_main
Dump of assembler code for function app_main:
0x4009fa10 <+0>: entry a1, 32
0x4009fa13 <+3>: or a1, a1, a1
0x4009fa16 <+6>: call8 0x4009e63c <main>
0x4009fa19 <+9>: retw.n
# debugging off
(gdb) disas app_main
Dump of assembler code for function app_main:
0x4009db80 <+0>: entry a1, 32
0x4009db83 <+3>: call8 0x4009c8d4 <main>
0x4009db86 <+6>: retw.n
End of assembler dump.
In this case it's inserting a nop-like instruction (I think that 'or' is OR'ing the a1 register with itself), only when -ggdb is turned on. In a bigger function like mp_obj_str_binary_op it's harder to find all the changes, but the first one's also an insertion of that same or a1, a1, a1 instruction, just before a call8.
but the whole function is actually organized differently and it rapidly diverges after that.
well, that's interesting to know.
I've seen the same with -ggdb, it does seem to interact with optimizations. If you're looking for debug with a smaller flash footprint, try -Og.
@slender iron if you are currently working with nRF5340 then you need to make sure you have a an image defined for the network core and have a transport defined to use for talking to the ble controller on the network core from the application core, if there is no firmware on the network core you can't do BLE, the app core has no access to the radio
https://docs.zephyrproject.org/latest/connectivity/bluetooth/bluetooth-arch.html might be helpful to get a better idea of the interplay
the app core firmware will always be a host only build and the network core a controller only build (can be a combined build but rare that you want that)
anybody know why some tables use MP_ROM_QSTR and others used MP_OBJ_NEW_QSTR? e.g.,```c
{ MP_ROM_QSTR(MP_QSTR_TOUCH), MP_ROM_PTR(&pin_PA07) }, // neokey trinkey
{ MP_OBJ_NEW_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA12) }, // cp32-m4
It seems like in the configurations where we build, `MP_ROM_QSTR` expands to `MP_OBJ_NEW_QSTR` but with different build choices extra curly brackets may be necessary to appear in a ROM table.... but I'm not too sure about this.
The zephyr_serial_uart___exit___ code was not deleted in this file. Did you mean to do that?
Nice cleanup, one place I noticed.
This was a MicroPython changeover, as I think you know. Worth looking at whether there are remaining MP_OBJ_NEW_QSTRs in their code.
I've rebased this on main to resolve conflicts but I still need to mentally process & implement @relic-se's note about ticking in Filter.c. It's my hope that with some of my recent code saving PRs this might fit in flash now.
CircuitPython version and board name
Adafruit CircuitPython 9.2.4 on 2025-01-29; Waveshare ESP32-C6 LCD 1.47 with ESP32-C6FH4
Code/REPL
# NO code to run
Behavior
After the flash restart, I noticed that the area of the low dropout regulator (LDO) feels overheated when touched.
However, I only have one unit available, so I am not sure if this issue is unique to my device.
Interestingly, when I flash the factory images, there is no overheating situa...
I'm doing a sysbuild so I think both should be included. That's my intent for CP firmwares. I want all firmware needed in one.
I removed those resistors and bridged the connection where they were, but kept the the caps and pull up resistors. Testing the rotaryio code again all looks good, it is registering the encoder turns now and updating the position in both directions correctly. Thanks again @todbot for the support.
Should I close this issue as there is a workaround, or leave it open for a CircuitPython fix?
No, apparently I missed this change at the time
Should I close this issue as there is a workaround, or leave it open for a CircuitPython fix?
I think, yes, this is probably an E9 problem. There's no fix except to document not to use a >8.2k resistor to ground.
Just to be clear, are you still using 5V pullups? 3.3v would be fine and safer for the RP2350B, depite the "5v tolerant" verbiage. See https://forums.raspberrypi.com/viewtopic.php?t=375118 for background.
Please check back and see if what I did makes sense now.
As discussed in the weekly CircuitPython meeting, https://github.com/adafruit/adafruit-circuitpython-weekly-meeting/blob/main/2025/2025-02-03.md#2643-in-the-weeds, we will drop building 8.x bundles.
- This is on the checklist here: https://github.com/adafruit/circuitpython/issues/9001
The CIRCUITPY_PORT_SERIAL guard in serial_early_init() excluded too much causing a hangup for RP2 port builds with DEBUG=1 and CIRCUITPY_CONSOLE_UART defined.
Marking as draft pending #10036 being confirmed to work.
Add a chorus effect to the delay library. Chorus will have a small (100ms or less) buffer of what has played and add the current sample to the number of voices desired from within the delay buffer.
Example given a 50ms buffer:
- 1 voice - Just pass-thru
- 2 voices - Combine the current sample and the sample from 50ms ago
- 3 voices - Combine the current sample as well as 25 and 50 ms ago
- 4 voices - Combine the current sample a...
Yes upon further reflection, this is another variation of RP2350 E9 problem. The series resistor turns into a pull-down when the encoder pulse happens.
I really like your approach of adding multiple voices. It'd be nice to also have support for pitch shifting with a synthio.LFO on delay_ms to achieve the full "warble" effect, but I need to do some hw testing before making that call. As for testing, it may be better to run an audiocore.WaveFile through it (ie: StreetChicken.wav) instead of a constant note.
I'm not sure if BlockInput support is necessary for voices, especially since changes in this property are integer-based. I think it'd only need to be an integer >= 1.
Wouldn't synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(voices)) have a similar effect rather than calculating the average and then performing the mix down?
Though it doesn't make too much sense from a "chorus" perspective to have a delay length greater than 100ms, should we limit the user to that range? I think we should encourage the user to use certain settings to achieve the typically desired effect in the documentation but not rule out other possibilities.
The SYNTHIO_MIX_DOWN_SCALE value may also need to be pre-calculated in common_hal_audiodelays_chorus_set_voices to avoid unnecessary float calculations.
What if you always loop through the full size of the buffer, max_delay_ms, at a constant rate, but delay_ms only determines the offset from the current index? That should get an LFO (with some form of pitch shifting?) working on it more smoothly.
If chorus_buffer_pos == 0, c_pos could be -1. If the if (c_pos < 0) { ... check is moved to the top of the for loop below, it would avoid going out of the range of the buffer.
@jepler I've checked over your get_buffer loop, and the ticking implementation looks right to me!
Would there be any significant flash savings from removing the original Biquads (as well as synthio.low_pass_filter etc) in a future CPy release?
yeah, it would save code space for sure. I went ahead and added a deprecation notice to the docs. When we break ground on version 10 someone can remove the old versions.
note: actually, keeping the synthesizer methods but making them return BlockBiquads is going to cost hardly any code size but would be almost perfect for backwards compatibility. So maybe do that instead.
Here are some random ideas to make CircuitPython better standalone.
- Add hot key to switch between terminal display and program display.
- Add program suspend state that is stored in RAM so that switching between programs doesn't need to lose all state. For example, a code editor may want to save the open file(s) and line numbers. It wouldn't be stored in flash.
- Add program browser to "activate" or "install" programs into slots for F1-F12 keys. Serves as a quick way to switch between them....
I was able to recreate this (any excuse to use my thermal camera!) but I question whether this is specifically a CircuitPython issue, or if this more relates to the fact that Python is an interpreted language. I would theorize that you would see the same amount of heat if you created a program in C/C++/Arduino's language which was always running at 100%.
Nevertheless, here are the temps I found.
First with the factory image...
The 5v I did without thinking as I was just blinding following the data sheet forgetting the rp2350 is a 3.3V device primarily. In my attempt to debug the encoder not working I thought that the 5V might have been the problem so I cut the 5V line before the pull-ups and instead tied it to the 3.3V line (this was before I posted this issue). So it was 3.3V -> 10k ohm -> encoder pin -> 10k ohm -> 0.1uf cap -> pico gpio.
As you suggested I removed the series resistors but left the pullup resisto...
synthio_mix_down_sample works to remove peaks that would push close to/beyond the upper range of the int16. It won't actually perform and average at all, especially if you are dealing with quieter sounds.
E.G. say a range of -20 to +20 and you have 4 voice samples -5, 0, +5, +5 which results in +5/4 or 1.25. The mix down call would just pass +5 on.
The mix down call is required cause you could have 4 voice samples of +15, +15, +15, +15 giving you +60 in a +20 upper range.
That said...
I had it was BlockInput so the number of voices could be changed slowly from an LFO. It rounds at the moment. It may never be used but I'm not sure if there is a downside?
Very good point. I'll up the limit to match Echo. Who knows maybe something cool comes from it.
@blissful pollen question about the audio effects modules- is the plan that they only work with synthio? i was experimenting yesterday with passing an analogbufio buffer but got this error TypeError: 'array' object does not support 'protocol_audiosample'
The plan is general use, I have tested it with wave files, MP3 and raw audio. Let me take a quick look at analogbufio
okay cool. yeah basically my idea is to try to use it as a guitar pedal so i was using a 1/4" jack to an analog pin
I think Cooper was doing some work on an RP2350 audio input that could be a source.
From what I see BufferedIn just goes into an array. Would need a layer to present that buffer to the audio "system" as such. Probably not too complex.
@candid sun Crazy idea time:
ain = analogbufio.BufferedIn(board.GP26, sample_rate=22050)
raw = audiocore.RawSample(mybuf, sample_rate=22050)
ain.readinto(mybuf)
And then play the raw sample on repeat. I don't have anything handy to provide an audio single in to test this, but it may work?
So something like mixer.play(raw) and then a loop reading audio forever
@blissful pollen ohh okay, thanks! i can try it in a bit
Fine by me, but I think it needs testing to ensure that the output isn't too distorted during the voice changes.
In my experimentation, I've found that averaging reduces the perceived volume of the effect, and that the mix down call is appropriate enough to prevent peaking. This is the same paradigm used in other audio effects. For example, audiodelays.Echo adds echo and sample together without dividing by 2 before mixing down.
Another example is synthio which adds e...
so this does seem to be working, i'm having audio coming through. i need to improve my circuit setup but this is a good starting point. thanks!
@gamblor21 I've recently implemented your chorus algorithm into another project I'm working on, but modified it to use an independent size and delay offset. When modifying the offset with an LFO, I found that it would generate significant pops because of the rapid jumps to different buffer indexes. In order to help prevent this problem, I used a copy of the offset which incrementally follows the desired offset as well as an index bit shift (similar to audiodelays.Echo.freq_shift) to clean u...
Nice! Let me know how it goes. I was thinking through how to make an audio object that plays a buffer and realized we had one already.
CircuitPython version and board name
Attempting to install CircuitPython 9.2.4 on new Raspberry Pi Pico 2W
INFO_UF2.TXT contains
Bootloader v3.0
Model: Raspberry Pi RP2
Board-ID: RPI-RP2
Code/REPL
problem is in installation, so no relevant Code to share.
Behavior
- Board always seems to be in BOOTSEL mode.
- Board doesn't seem to recognize/respond to adafruit-circuitpython-raspberry_pi_pico2_w-en_US-9.2.?.uf2
-
- file appears in device's RPI-RP2...
- uf2 file appears when I do ls /Volumes/RPI-RP2
If the UF2 file name appears in RPI-RP2, that is an indication that the upload failed. Normally it would not. This could be for a variety of reasons, including:
- Operating system copying failure. What version of macOS are you running? I have seen one report of issues with 15.3. If you have another computer (Windows, Linux, RPi Linux SBC, etc.), try with one of those.
- UF2 file is corrupted. Re-download and try again.
Try loading the pl...
Are you sure you have a Pico 2W ? When I'm in boot select mode, the volume label is RP2350. The board should say Pico 2 W with the 2 in a bold white box. If you do have the 2W model then I'm guessing you have the wrong boot loader installed somehow.
Terribly embarrassed. Yes, in fact I'd misread the labels and pulled out a pair of Pico Ws instead of a pair of Pico 2Ws. Running the correct UF2 did the trick. Mortified.
Thank you for such quick responses.
@tulip sleet quick question for you. Been out for a bit, so don't know what's right. I have some updates I want to make to the SSL test example in the ConnectionManager library, but have seen a few comments about not having examples like that (since it causes unnecessary releases). What's the right way now?
It's fine, go ahead. I was trying to minimize having tons of examples added to certain libraries but was convinced otherwise. Some examples could be Playground notes
so you have one of these in your sysbuild config?
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/applications/ipc_radio/README.html#sysbuild_kconfig_options
They are responsible for pulling in the controller firmware sample for IPC or RPC based HCI.
You can also make sure that you have it setup by observing if both application and network core get flashed. They have separate flash banks and run independent from each other (though app core kicks off netcore with a signal). Zephyr generates a "merged_domains.hex" if its multi-image build.
Here's a gist which goes over some of the usage with analogbufio. https://gist.github.com/relic-se/77e48df1920b20d3e50762cbc06d1bb9 You could also use the new pio i2s library to do the same thing, but you'd need a separate i2s bus for output (if needed).
awesome, thank you!
If you're interested in the hardware I'm working on, let me know and I can give you more info.
Hi @wraetz-dev, have you made any additional progress at getting this board supported?
I'd like to help, and I'll plan to start from scratch, but if you already have some of the work done, let me know.
I realize that it's still extremely early days with the CP Zephyr port, but I have an nRF5340 Audio DK that I'm very excited to test.
I'm not sure that I can accommodate actually building CP yet, but can an expert share any advice on just loading the nRF5340 runtime as an experiment?
yeah actually I’m curious. I’m thinking of using an mcp6002 for the guitar input
I've heard that's a decent op-amp, but I'm using a standard tl972
CircuitPython version and board name
Adafruit CircuitPython 9.2.4-11-g9eeb5d93e7 on 2025-02-05; Adafruit QT Py ESP32C3 with ESP32-C3FN4
Adafruit CircuitPython 9.2.4 on 2025-01-29; Seeed Studio XIAO ESP32C3 with ESP32-C3FN4
Adafruit CircuitPython 9.0.0 on 2024-03-19; Seeed Studio XIAO ESP32C3 with ESP32-C3FN4
Code/REPL
import mdns
import wifi
mdnserv = mdns.Server(wifi.radio)
mdnserv.hostname = "test-name"
Behavior
When the mdns hostname is set jus...
Documented mosi_packet. Yes, that is the expectation and that is how we've run our tests, although I don't think anything would break if the memory was mutated mid-transfer, it would just make it difficult to predict whether the bytes actually transmitted are those placed into the bytearray before the function call or those placed after the function call.
I added an example in the spitarget/__init__.c file since that's the analog for where i2ctarget's example is placed, let me know if the example code looks alright.
I've added code to store the mosi_packet and miso_packet parameters within the spitarget object, but I don't see how that will actually affect the situation you've brought up. Is there something I need to do to turn the pointers in the struct definition into object references recognized by the garbage collector?
About "Fruit Jam" discussion on Function key in "Deep Dive".
This is what the Maximite Colour 2 family of BASIC computer use.
You start with a command-line (REPL but for BASIC).
From there the F1 key launch a file browser (text base) that let you edit file, run file and preview/run some format like image file and sound file (MOD). The usage of the file browser is also using function key to select what you want to do for the highlighted file.
You also have the command EDIT that go into a full screen editor, also with function key and a bottom line description of what each key is doing. You can RUN the program you are editing directly from the editor.
Some function keys in the REPL have pre-defined function such as F1=FILES, F2=RUN, F3=LIST, F4=EDIT.
Other are macro to quickly type some stuff such as F5=AUTOSAVE "", F6= XMODEM RECEIVE "", ...
Finally F11 and F12 are user customisable with custom text.
Maximite Colour 2 is very usable just with the keyboard and you don't need anything else to program and execute your code.
Don't have the 2350 board at the moment, can you try to replace your chord lines with a single tone note, like this:
synth.press(synthio.Note(frequency=440, amplitude=AMPLITUDE))
to narrow things down, as I've noticed in your sound example that stepping occurs approx. every 4.2s, exactly the period of your panning parameter LFO.
@crimson ferry I've been trying to get the https server here https://github.com/ide/circuitpython-https-server working to test https performance on RP2 without success. I've patched the missing SOL_SOCKET and SO_REUSEADDR CP8->CP9 issue in TLSServerSocketPool but I'm failing with a broken pipe (-32) error. I suspect the .pem files are bad. How have you been getting it to work? Maybe there's an alternative tool you can suggest?
@mortal kernel I haven't tried that one in a while, but the Adafruit library is updated for HTTPS https://github.com/adafruit/Adafruit_CircuitPython_HTTPServer, and there's an HTTPS example https://github.com/adafruit/Adafruit_CircuitPython_HTTPServer/blob/main/examples/httpserver_https.py
what if we partitioned the fruit jam so that it has a CIRCUITPY filesystem area (writable by host) plus a second area that is not on USB so it's always writable by code, and is automounted. /local or so.
@slender iron I'm looking without success for the way to "disable low priority interrupts", which is what I thought you were discribing for fixing the blank DVI display during flash writes problem on RP2350. I found how to set IRQ priority in the pico sdk, but I didn't finda way to mask/disable interrupts based on priority. I only found the cpu-wide IRQ enable flag that common_hal_mcu_disable_interrupts is already using.
hints welcome
there's something called PRIMASK but it's also a single enable/disable bit https://developer.arm.com/documentation/ddi0419/c/System-Level-Architecture/System-Level-Programmers--Model/Registers/The-special-purpose-mask-register--PRIMASK?lang=en
Maybe some classic computer emulation? Generic CP/M, Apple ][, perhaps a minicomputer like the PDP-8?
The ARM NVIC prioritizes presentation of concurrent enabled interrupts, i.e., which vector to invoke first. PRIMASK will boost the PE to execution priority 0, effectively masking interrupts at a level lower than 0. The Main Extension augments PRIMASK with FAULTMASK and BASEPRI adding more specificity to priority selection. The RP2350 implements the Main Extension. Aside from access to these registers via the processor core registers, I'm not finding any support in the Pico SDK.
OK, BASEPRI seems like what I'm looking for maybe
thanks!
are BASEPRI numbers the same as the irq_set_priority numbers?
Yeah, I think that what this inside Irq_set_priority does:
io_rw_32 *p = nvic_ipr0() + (num >> 2);
// note that only 32 bit writes are supported
*p = (*p & ~(0xffu << (8 * (num & 3u)))) | (((uint32_t) hardware_priority) << (8 * (num & 3u)));
(inserts the priority directly into the NVIC_IPRxx register corresponding to the interrupt number)
what if we partitioned the fruit jam so that it has a CIRCUITPY filesystem area (writable by host) plus a second area that is not on USB so it's always writable by code, and is automounted.
/localor so.
We could... or is /sd automounting enough?
Maybe some classic computer emulation? Generic CP/M, Apple ][, perhaps a minicomputer like the PDP-8?
I don't think we would from within CircuitPython. It could be another image/Learn guide but not CircuitPython based anyway.
Hi, I'm trying to burn a T-Display-S3R8 device with the firmware for the NerdQaxe+ following the steps below https://github.com/shufps/qaxe/tree/main?tab=readme-ov-file#installation-via-usb-bootloader-on-board-with-boot-button-qaxe-qaxe, but I can't get it. In the instructions it says: ‘now start the stm32 in DFU mode by pressing boot’, (I understand that the boot button is the one on the left if you have the buttons facing you) I have done it but it doesn't do anything. Also the AIs tell me I should have three binary .bin files:
esptool.py --chip esp32s3 --port /dev/ttyACM0 write_flash -z \ 0x1000 bootloader.bin 0x8000 partition-table.bin \ 0x10000 firmware.bin
However I only have one binary firmware.bin or qaxe.bin (depends on what I name it, but it's the same).
I need help from someone who has flashed a NerdQaxe+. Best regards and thanks in advance.
PD: Web related https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/index.html
Please talk to Waveshare about this. Maybe there is some pin state that needs to be set in CircuitPython.
@flint flare I'd encourage you to reach out to that project if the installation instructions aren't working for you. fwiw I wouldn't put much stock in an AI answer about how to use esptool, because the instructions vary depending on the project & which espressif mcu it is. This channel is for circuitpython development.
<@&356864093652516868> Sorry for the late notice. We have our weekly meeting now in this text channel and in the circuitpython voice channel. The notes doc is here: https://docs.google.com/document/d/1r4p9vARPphE1LlejdCZIOuOJ1eD_ZxGTvukjTnw3Ryg/edit?tab=t.0
CircuitPython Weekly Meeting for Monday, February 10, 2025 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you can’t make the meeting an...
@slender iron I can read core and/or blinka just to give you a rest during that section if you like.
[rp2350.dap.core0] clearing lockup after double fault
Thank you!
thank you scott!
thanks all, have a great week
Thanks for hosting Scott, have a great week everyone!
Extra points for the double fault! You usually need an MMU to get one of those.
0x10027cde in port_idle_until_interrupt () at supervisor/port.c:507
507 __WFI();
(gdb) where
#0 0x10027cde in port_idle_until_interrupt () at supervisor/port.c:507
#1 0x100264be in run_code_py (safe_mode=<optimized out>, simulate_reset=<optimized out>) at ../../main.c:741
#2 0x10026aec in main () at ../../main.c:1108
r0 0x0 0
r1 0x20006150 536895824
r2 0x3 3
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x0 0
r8 0x6b0 1712
r9 0x1 1
r10 0x190 400
r11 0x0 0
r12 0x1 1
sp 0x20080f58 0x20080f58
lr 0x20004dbb 536890811
pc 0x10027cde 0x10027cde <port_idle_until_interrupt+50>
xpsr 0x69000000 1761607680
fpscr 0x10 16
msp 0x20080f58 0x20080f58
psp 0x0 0x0
msp_ns 0x0 0x0
psp_ns 0xfffffffc 0xfffffffc
msp_s 0x20080f58 0x20080f58
psp_s 0x0 0x0
primask 0x0 0
basepri 0x60 96
faultmask 0x0 0
control 0x4 4
msplim_s 0x0 0x0
psplim_s 0x0 0x0
msplim_ns 0x0 0x0
psplim_ns 0x0 0x0
primask_s 0x0 0
basepri_s 0x60 96
faultmask_s 0x0 0
control_s 0x4 4
primask_ns 0x0 0
basepri_ns 0x0 0
faultmask_ns 0x0 0
control_ns 0x4 4
#include "src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include/RP2350.h"
@onyx hinge You might be faulting on a bad mrs destination. The RP2350 has the security extension, so there is a basepri_ns (non-secure) that you may want to try.
The double fault was when trying to set the NVIC interrupt enable bits, which is not the approach I'm going for. On voice call, scott & I figured out what was going wrong with the BASEPRI code, and I think I'll have a PR soon. Appreciate the educated guesswork though!
Apologies for jumping in half-baked, it's just that I find stuff at this level too tempting to ignore.
doing so causes the picodvi display on rp2350 to blank, because this irq is handed by cpu0.
Instead, use the BASEPRI register so that common_hal_mcu_disable_interrupts masks interrupts with lower priority (higher priority values) than PICO_ELEVATED_IRQ_PRIORITY. This has the effect of masking "regular" interrupts while still letting this priority interrupt occur.
port_idle_until_interrupt now needs to directly manipulate the interrupt enable state, because an interrupt masked via BASEPR...
@slender iron ```$ make TRANSLATION=ja
Only first 256 glyphs can be displayed, font subset has 520 glyphs
make: *** [../../supervisor/supervisor.mk:270: build-adafruit_feather_rp2350/autogen_display_resources-ja.c] Error 1
@onyx hinge is the PioMatter() constructor more strict on the framebuffer size than the prior ones like AdafruitMatrixBonnetRGB888Packed() were?
I am finding that
matrix_framebuffer = np.zeros(shape=(geometry.height, geometry.width, 3), dtype=np.uint8)
used to work with the old constructor, but with the new one throws
RuntimeError: Framebuffer size must be 16384 bytes (8192 elements of 2 bytes each), got a buffer of 49152 bytes
The 3rd dimension of the array shape seems to be the culprit, if I remove it then it initializes, but further on the copying breaks.
@lone axle that looks like some kind of mistake on my part, 16384 bytes doesn't seem right.
it's with --colorspace RGB565 if that factors in.
oh, from what you said I thought the message you were seeing was from an 888Packed situation
RGB565 should have 2 bytes per pixel. The array should maybe be something like np.zeros(shape=(geometry.height, geometry.width), dtype=uint16)
is 8192 the right number of pixels? that'd be 64x128 or something?
the root problem I'm trying to solve is these two lines https://github.com/adafruit/Adafruit_Blinka_Raspberry_Pi5_Piomatter/blob/dd77450f156d8617f6cef01f6fe33aa519950adb/examples/fbmirror_scaled.py#L77-L78 successfully initilize with the old style constructor, but the cooresponding ones under the new way raise an exception.
Correct, I have 128x64 total currently (4x 64x32 panels).
matrix = adafruit_raspberry_pi5_piomatter.AdafruitMatrixBonnetRGB888Packed(matrix_framebuffer, geometry)``` That is correct for RGB888Packed, it makes 3 "uint8" elements for each pixel, 3 bytes each. But it's not appropriate for RGB565
The 3rd dimension of the shape is important for the way the fbmirror_scaled works currently because the array that results from np.asarray(img) has a shape with that 3rd dimension.
Right, sorry. The switch to 565 was one attempt at resolving the issue
since "the thing you want to display" is a PIL imagein RGB888Packed format, I don't think --colorspace RGB565 can be expected to work.
the same issue is present with 888 as well (which I've gone back to). it just changes the numbers in the exception.
this is a difference between the unscaled and scaled demos: In the scaled demo, I have to convert the image data into something PIL can handle, so I can use the PIL scaling routine. But that means the data being displayed is in a different format between the two programs.
@slender iron The duplicate application of the secondary host changes to Adafruit's lwIP repo is happening because of the --force I'm forced to use because of the weird state of the CIRCUITPYTHON9 branch. What I thinks needs to be done is to delete the CIRCUITPYTHON9 branch, make a new main branch that tracks the upstream master, re-sync the new main branch, create a new CIRCUITPYTHON9 branch from main at tag STABLE-2_2_1_RELEASE, and then I can PR the re-based local updates cleanly on top of that.
without --colorspace RGB565 the exception is
RuntimeError: Framebuffer size must be 32768 bytes (8192 elements of 4 bytes each), got a buffer of 49152 bytes
@lone axle can you send me what you have?
thanks, I'll run downstairs and load it up and see what I can understand..
at least 1 problem with my current code is the wrong dtype value passed to np.zeros() when creating matrix_framebuffer I mistakenly used the var dtype instead of the proper value dtype=np.uint8
@lone axle I think I'm close to having it working. Maybe it's a total mistake to have --colorspace even be a commandline argument. I'll give a better explanation once I can actually get a good display
@mortal kernel I usually start a new branch for every change I make. That may simplify it for you
I suspect most of the time it's up to the code what color depth it's written for, while it has a greater chance of adapting to differing width/height/etc
@lone axle try with these changes: https://gist.github.com/jepler/7ae5df5c3877b4c97edbf5f6681c430d
Me too. Let me run through my steps again and I'll let you know where things go off the rails.
by sending colorspace=None it removes the ability to customize the colorspace via the commandline (since any other value will not work).
the "matrix" is created with dtype uint8 which you already figured out
and I left a stray debug print in, just so you have something to do 🙂
that also makes it easy to force push to that branch to update the PR
if you contemplate whether ANY of the demos still work when the user specifies a different --colorspace than the intended one, we can decide whether to change the default so that --colorspace is not added as a commandline argument at all
What would be considered the intended colorspace of fbmirror.py the non-scaled one? In order for that one to run for me currently I have to pass --colorspace RGB565 without it I get
RuntimeError: Framebuffer size must be 32768 bytes (8192 elements of 4 bytes each), got a buffer of 16384 bytes
Yeah, RGB565 is what it uses now.
but the default default with the argument parser is --colorspace RGB888
... colorspace=piomatter.Colorspace.RGB888, ...):
Here is the notes document for next Tuesday's CircuitPython Weekly Meeting. It is at the normal time of 11am Pacific / 2pm US Eastern BUT 24 hours later than normal 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/1oM_x1t2iD_iStf4riPa5j_naS-yqZAR-Y8_qKyVpa7s/edit?usp=sharing
CircuitPython Weekly Meeting for February 18th, 2025 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you can’t make the meeting and w...
I can add support for the audio kit
@slender iron I've re-synched my fork of the Adafruit repo which automatically killed PR #3. Cloned repo to my local machine. Created a new branch off circuitpython9. Now I'd like to cherry-pick the two upstream commits that officially update to v2.2.1. but the commits are not in my repo because they've not been synched to the Adafruit repo. I've tried git fetch upstream, but no help.
rabeles at debian12 in ~/D/c/i/lwip-repo
↪ git cherry-pick b6c60989645be22b9e91bcc7a81c07fff4dabaa1
fatal: bad object b6c60989645be22b9e91bcc7a81c07fff4dabaa1
rabeles at debian12 in ~/D/c/i/lwip-repo
↪ git remote -v
origin ssh://git@github.com/eightycc/lwip.git (fetch)
origin ssh://git@github.com/eightycc/lwip.git (push)
upstream ssh://git@github.com/adafruit/lwip.git (fetch)
upstream ssh://git@github.com/adafruit/lwip.git (push)
rabeles at debian12 in ~/D/c/i/lwip-repo
↪ git fetch upstream
rabeles at debian12 in ~/D/c/i/lwip-repo
↪ git cherry-pick b6c60989645be22b9e91bcc7a81c07fff4dabaa1
fatal: bad object b6c60989645be22b9e91bcc7a81c07fff4dabaa1
Do you have lwip as a remote? git remote -v
see above
I'd add another remote for lwip
try git fetch origin b6c60989645be22b9e91bcc7a81c07fff4dabaa1
you can tell it to just fetch a given sha1 directly
I name my remotes by the person, not origin and upstream
bingo. did that and then the cherry-pick worked.
abeles at debian12 in ~/D/c/i/lwip-repo
↪ git fetch origin b6c60989645be22b9e91bcc7a81c07fff4dabaa1
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 2 (delta 1), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 1.62 KiB | 332.00 KiB/s, done.
From ssh://github.com/eightycc/lwip
* branch b6c60989645be22b9e91bcc7a81c07fff4dabaa1 -> FETCH_HEAD
rabeles at debian12 in ~/D/c/i/lwip-repo
↪ git status
On branch issue-9837
nothing to commit, working tree clean
rabeles at debian12 in ~/D/c/i/lwip-repo
↪ git cherry-pick b6c60989645be22b9e91bcc7a81c07fff4dabaa1
[issue-9837 f89bdfda] Update CHANGELOG in preparation for 2.2.1 release
Author: Simon Goldschmidt <goldsimon@gmx.de>
Date: Wed Feb 5 20:25:11 2025 +0100
1 file changed, 47 insertions(+)
ah, earlier you did a fetch from upstream (aka adafruit)
but the cmd i gave, does a fetch from origin (aka eightycc)
that might also play a role
Now I've got the two commits I wanted on my branch. But, the SHA hashes differ from the upstream repo. Could that cause trouble down the line?
you want to merge rather than cherry pick
I'll give it a try. Here's my current log:
↪ git log
commit 2978c5b176f608e6779271fdf4c1fd021f73ba02 (HEAD -> issue-9837)
Author: Simon Goldschmidt <goldsimon@gmx.de>
Date: Wed Feb 5 20:38:17 2025 +0100
Prepare 2.2.1 release
commit f89bdfda57220490e1ec771fd2bd53280a8413d7
Author: Simon Goldschmidt <goldsimon@gmx.de>
Date: Wed Feb 5 20:25:11 2025 +0100
Update CHANGELOG in preparation for 2.2.1 release
commit 4097a0709b70343e6bef6d129537ba4eb474ce10 (upstream/circuitpython9, origin/circuitpython9, origin/HEAD, circuitpython9)
Merge: 239918cc 2396f85f
Author: Scott Shawcroft <scott@tannewt.org>
Date: Wed Feb 5 12:14:38 2025 -0800
Merge pull request #1 from eightycc/circuitpython9
Update to almost version 2.2.1
cherry pick and rebase are things you only want to do on your own commits since it changes the commit itself (and therefore its hash)
yeah
Ouch!
ive had trouble before, because commit X contains a fix i need
and commit X isnt in my branch at all, because it was cherry-picked
so i spent a while trying to make sense of why i didnt have the fix
It's all clear to me now. I think. I'll go through my steps again from scratch just to be sure...
Thanks a million!
OMG that is SO true!
once you get good enough, you become the guy they call 😛
i'm now rebasing several branches on a daily basis at work
and fixing botched merge conflicts that got commited, making a mess of the history
Is this ready now? Would love to add it to the metro and fruit jam too.
I tested this artifact on a Solderparty rp2350 stamp xl and it did eliminate the screen going black during writes to flash.
I love git, I think I'm good at it, but helping somebody through git troubles via online chat makes me want to cry.
So close, but using merge still yields a different SHA:
↪ git status
On branch issue-9837
nothing to commit, working tree clean
rabeles at debian12 in ~/D/c/i/lwip-repo
↪ git fetch origin b6c60989645be22b9e91bcc7a81c07fff4dabaa1
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 2 (delta 1), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 1.62 KiB | 416.00 KiB/s, done.
From ssh://github.com/eightycc/lwip
* branch b6c60989645be22b9e91bcc7a81c07fff4dabaa1 -> FETCH_HEAD
rabeles at debian12 in ~/D/c/i/lwip-repo
↪ git fetch origin 77dcd25a72509eb83f72b033d219b1d40cd8eb95
remote: Enumerating objects: 13, done.
remote: Counting objects: 100% (13/13), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 13 (delta 9), reused 12 (delta 9), pack-reused 0 (from 0)
Unpacking objects: 100% (13/13), 2.40 KiB | 613.00 KiB/s, done.
From ssh://github.com/eightycc/lwip
* branch 77dcd25a72509eb83f72b033d219b1d40cd8eb95 -> FETCH_HEAD
rabeles at debian12 in ~/D/c/i/lwip-repo
↪ git merge b6c60989645be22b9e91bcc7a81c07fff4dabaa1
Merge made by the 'ort' strategy.
CHANGELOG | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
rabeles at debian12 in ~/D/c/i/lwip-repo
↪ git log
commit abf8c210045b6bfac7a7913e2607bb82b749dfec (HEAD -> issue-9837)
Merge: 4097a070 b6c60989
Author: eightycc <eightycc@gmail.com>
Date: Mon Feb 10 14:47:11 2025 -0800
Merge commit 'b6c60989645be22b9e91bcc7a81c07fff4dabaa1' into issue-9837
commit 4097a0709b70343e6bef6d129537ba4eb474ce10 (upstream/circuitpython9, origin/circuitpython9, origin/HEAD, circuitpython9)
Merge: 239918cc 2396f85f
Author: Scott Shawcroft <scott@tannewt.org>
Date: Wed Feb 5 12:14:38 2025 -0800
Merge pull request #1 from eightycc/circuitpython9
Update to almost version 2.2.1
😭
I noticed that the DVI pins for the RP2350 are the same pins used on the DVI Sock but the D0/D1/D2 pins are in a different order. Does that make sense or should the order be standardized?
It is ok that the merge commit has a different sha
the two new commits should have preserved commits
I think we debated this and though it didn't matter since the software can change it
I believe I'm flashing both. Two flashes happen. maybe it is the 7002 instead though?
ah hm, I have not worked with the 7002 yet but it does seem to have an externally residing firmware patch flash. Could be that in a dev setting that this gets always written.
In nrfjprog log you should see it explicitly logging the flash process to the app and network core
-- runners.nrfjprog: Flashing file: /home/tannewt/repos/circuitpython/ports/zephyr-cp/build-nordic_nrf7002dk/zephyr-cp/zephyr/zephyr.hex
[ #################### ] 31.237s | Erase file - Done erasing
[ #################### ] 6.547s | Program file - Done programming
[ #################### ] 6.677s | Verify file - Done verifying
Applying pin reset.
-- runners.nrfjprog: Board with serial number 1050728232 flashed successfully.
-- west flash: using runner nrfjprog
-- runners.nrfjprog: reset after flashing requested
-- runners.nrfjprog: Flashing file: /home/tannewt/repos/circuitpython/ports/zephyr-cp/build-nordic_nrf7002dk/hci_ipc/zephyr/zephyr.hex
[ #################### ] 12.714s | Erase file - Done erasing
[ #################### ] 1.573s | Program file - Done programming
[ #################### ] 1.604s | Verify file - Done verifying
Applying pin reset.
-- runners.nrfjprog: Board with serial number 1050728232 flashed successfully.
flashing both
ok nice
maybe I need to call bt_enable()
is there really no way to get a random number
if that doesn't do it then maybe try a very simple BLE sample that can makes it easier to trace down
without ble?
oh you want a random number? Yea that should be possible, it has a RNG peripheral, would be suprised if that relies on the BLE radio
wifi is getting a random value for the nonce
could you point me to the code/sample that suggests using BLE for the random number?
my final zephyr.dts has zephyr,entropy = &rng_hci;
not sure where it is coming from
oh okay
ah okay, it looks like its not actually connected with BLE. Just that the RNG peripheral is connected to the radio core and the radio core needs to forward the data to the app core
that is not directly related, bt_enable is for starting the actual BLE radio.
The network core is just a normal CPU but has exclusive access to some peripherals, so if you want to get something from those peripherals on the app core you need communicate it to the appcore via some mechanism. In their sample they use their RPC implementation for that, it can be used for BLE but is not strictly for that.
though looking at the datasheet there also seems to be an RNG on the app core side
so I don't know if thats truly necessary to use the network core one
the sample is for nordic's sdk
yea for a lot of things you won't find a sample in vanilla Zephyr, you can pull in individual libraries like that without using their whole fork
but not relevant for this particular issue I would say
checking what the app core rng peripheral is called in the DK
&psa_rng
maybe try that
looks like bt_enable makes it work
nice
even though the call fails 🤦
this seems to be the appcore side rng if you don't want to rely on the network core being up for this functionality
ah only for the non secure context, in secure context its then probably "cryptocell"
https://github.com/zephyrproject-rtos/zephyr/blob/main/dts/arm/nordic/nrf5340_cpuapp.dtsi#L101
which should work with this sample, might be down to just removing that entropy user override
CONFIG_PSA_CRYPTO_DRIVER_CC3XX=y
explicitly enables the app core rng driver, normally CONFIG_CRYPTO should pull it in thoug
sure thing
@onyx hinge think it'd be ok to define these based on implementation values: https://github.com/adafruit/circuitpython/blob/main/shared-bindings/socketpool/enum.h#L12 Zephyr uses different values than what we have so I'd have to map them all
I hit a static assert about it that you added
sadly, no. In order to make wiznet (and other non-core socket implementations) work with core ssl, I had to promise circuitpython userspace the numeric value of those constants
wiznet can't import socketpool to get the integer values, it exists on systems that don't have it at all
actually I'm less sure why I added the assert THERE, it seems to have to do with adding AF_INET6, not adding ssl support for wiznet sockets. so I might be wrong.
"""WIZNET5K SocketPool library"""
# These must match circuitpython "socketpool" values. However, we cannot
# depend on socketpool being importable, so hard-code them here.
SOCK_STREAM = 1
SOCK_DGRAM = 2
SOL_SOCKET = 0xFFF
SO_REUSEADDR = 0x0004
```these are the ones that I commented had to match the core. But I think the static asserts you were talking about were about `AF_` values
```oh AF_INET is one of them
@d1ffeq-diy Thank you for the review. While setting up an updated example to simplify the demonstration, I think I've come across the problem, and it's much simpler than I expected.
As per the current documentation on synthio.LFO (https://docs.circuitpython.org/en/latest/shared-bindings/synthio/index.html#synthio.LFO), it states "If waveform is None, a triangle waveform is used." When I specify the waveform directly (such as a sine wave in the example below), the program works as intende...
If I replace time.sleep(2.0) in the loop with the following:
tick = 40
while tick:
print(effect_delay.delay_ms.value)
time.sleep(0.05)
tick -= 1
I can generate the graph below (in LibreOffice Calc):
It looks as if the default waveform is functioning as intended, but it is somehow not affecting the effect parameter correctly unless a waveform is specified by the user.
@tulip sleet are you going to bring the updated certificate submodule into circuitpython?
Yes, I'll do that too after a little more testing. I'll open an issue -- thanks.
certificates was updated for NINA-FW. Update in CIrcuitPython too.
Let me know when you have a build. I'll do some tests
@slender iron I reviewed the state of things further and I think maybe it's almost-fine.
The ssl module actually only seems to check the socket.type against SOCK_STREAM. I can't see where it checks AF_ or uses SOCK_DGRAM. and it does call setsockopt but only with values passed down from a caller.
However, I still don't see a way around making SOCK_STREAM match. For a minute I thought we could effectively getattr() it from the socket object, but it's not a property of the socket object, it's a property of the socket module/socketpool and we don't have an effective way to pluck out that information: There's not a link back from a socket object to its socketpool type that I could see.
I'm not sure what the consequences are of trying to create an SSL session on top of a SOCK_DGRAM besides that it's not expected to work. So we could also just ... remove the check?
we could add those constant to a socket module too
like cpython
There's definitely a bug. Looking closely at harmonic content in spectrogram of the latest audio snippet, the modulation with WAVEFORM=False looks square-like:
and with WAVEFORM=True it looks exactly as it should:
also, the tiny slopes of the square-like transitions suggest that it once was a triangle wave....
tannewt, I figured out how to make a minimal Zephyr board definition for the Feather RP2350. It can do I2C and UART serial with the Zephyr shell sample app. Haven't tried it with anything else yet. Wrote up the board def in a Playground guide if you're curious. Not sure if the same technique will work for RP2350B, but I plan to try as soon as I can get my hands on a board.
@slender iron Big hug to you and @buoyant lagoon for your assistance with git. I've submitted a new pull request that should pass muster. There's a warning compiling one of the tests (unchanged from the upstream repo) that's causing one of the CI tests to fail, but I think we're good to go...
I've made the requested changes and gotten the CI tests to pass; let me know if there's any problems that introduced or anything else to fix that I've missed!
Thanks! We've started this repo for adafruit supported board defs: https://github.com/adafruit/adafruit-zephyr-support Mind making a PR?
sure. I may try to test it a little better first. my initial board def is a little rough. just got it working last night.
thanks!
for that repo, are you using adafruit-zephyr-support as a workspace directory with west init? Or, more specifically, I'm wondering about what the relative path is from the adafruit-zephyr-support/boards directory to the zephyr/boards directory. The way I did my board def is to include the rpi_pico2 dts file, then delete pinout related stuff I don't need, then add the proper pinctrl stuff. So, it depends on the relative path.
I feel like the relative path thing is a little fragile. But, it has the advantage of working without copying Apache-2.0 licensed code fragments into an MIT licensed repo. If you're cool with just using Apache-2.0, then I could make a board def that copied the devicetreee code without the relative path include.
ya, I think it is to have both marked with spdx
what if we partitioned the fruit jam so that it has a CIRCUITPY filesystem area (writable by host) plus a second area that is not on USB so it's always writable by code, and is automounted.
/localor so.
I couldn't sleep last night and thought maybe /saves would be a good name.
TLS over UDP... Maybe this is part of HTTP/3 and QUIC.
TCP is so old fashioned.
One question about a board change. Good otherwise thanks!
As long as this struct is on the VM heap, then its aligned pointers will also be collected and the memory preserved. As-is this will keep the bytearray buffer but not the bytearray object. I think that's fine because the user code won'd be able to get it back if it drops the object.
#include "src/rp2_common/cmsis/stub/CMSIS/Device/RP2040/Include/RP2040.h"
#include "src/rp2_common/cmsis/stub/CMSIS/Device/RP2040/Include/RP2040.h"
Support for an RM2 module on the new Fruit Jam would be so nice. Let me see what I can do to make that happen.
I'm having the same issue on Windows, setting the interface name doesn't appear to have any effect using a Raspberry Pi Pico 1. My boot.py code is straightforward:
import usb_hid
from joystick_xl.hid import create_joystick
usb_hid.enable((create_joystick(axes=8, buttons=128, hats=4),))
usb_hid.set_interface_name("My joystick")
The device shows as CircuitPython HID in the game controllers dialog:
. By just slightly decreasing the internal flash filesystem size I was able to increas...
CircuitPython version and board name
I have rewritten the displayio, vectorio and adafruit_imageload code as a seperate c++ codebase with tests. So if you think this "version" should be ignored you could just close this bug report.
Code/REPL
# Well my test could be reproduced with something similar.
# Images are from: https://entropymine.com/jason/bmpsuite/bmpsuite/html/bmpsuite.html
import displayio
import adafruit_imageload
# bmp image load test descript...
Updated, hopefully it's green now.
I have revised my tests and actually it seems now that the issue manifests on S2 and S3 too, as soon as you enter the REPL. I missed that previously as I relied on stopping the code without pressing a key to enter the REPL apparently. This happened without being related to timing.
Before code.py
{"web_api_version": 4, "version": "9.2.4-42-ge19ff435d2", "build_date": "2025-02-08", "board_name": "Adafruit QT Py ESP32S2", "mcu_name": "ESP32S2", "board_id": "adafruit_qtpy_esp32s2", "creator_id...
Support for the CYW43 increases the CP firmware image from 1020KB to 1532KB. Most of the additional 512KB accommodates the CYW43's firmware, with the remainder taken up by the CYW43 driver, the lwIP stack, and mbedtls. To avoid increasing the CP image size for all RP2 boards, some or all of the additional 512KB could be stored in and loaded from the filesystem when RM2 module support is desired.
@slender iron PR for the Feather RP2350 board def is up. I2C and UART serial work. SPI is probably busted. Tried a speculative devicetree config for the spi pins but I haven't tested it yet. Specifying the pins you want is weird and poorly documented. May be possible to use the PL022 driver with any GPIO for the CS line, or maybe not. If that doesn't work, there's also an spi-pio driver.
Probably not a big issue on 8MB flash or more, but a substantial trade-off for smaller flash boards (could wreak havoc with current partition maps though).
A generic ability to offload code into the user partition could potentially benefit many flash space issues.
Add a pitch shifting effect to the delay library. It uses a circular buffer "window" with a second, smaller circular buffer "overlap" to achieve the effect, so it fits nicely in the delay category.
This algorithm is relatively simple compared to others which rely on FFT or other computationally intensive processes and has been tested on both the RP2040 and RP2350 without any performance concerns. The only room I see for further optimization is in the recalculate_rate function which uses ...
The documentation says I picked octaves for pitch bend in synthio, though it says the range is +-12 which seems like a semitone-related number. And I can't make much sense of the implementation, it looks too clever to read late at night.
It's a pity if I made a bad choice for synthio, but it's also a pity if it doesn't match between synthio & this new functionality.
Is this using a published algorithm like PSOLA or a bespoke algorithm?
I put back the old code for2040s with Cortex M0, and without BASEPRI. At this point, if it doesn't interfere with review, I'd prefer to rebase it so that the git blame of the file isn't deceptive, showing that the rp2040 implementation of the routine was invented in this PR.
Loading the CYW43 firmware from a conventional binary file stored in the filesystem would be straightforward.
Executable code presents additional difficulties. Here are some initial thoughts:
The RP2 maps the entire flash memory into the 16MB XIP address space, so code can be executed directly from the FAT filesystem area of the flash.
It's unpredictable where a file will be stored in the filesystem, making it necessary to compile the executable code as position independent.
There would...
I observed entering into safe mode on nRF dongle with 9.2.4 when accidentally tried to establish a connection, even a connection already exists. Just use the codes below, hope it helps.
`### Dongle 2
import _bleio
from adafruit_ble import BLERadio
from adafruit_ble.services.nordic import UARTService
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
conn=[]
addresses=[]
def conNext(timeout):
device = 'de:4e:27:f0:bc:e6' # Enter your MAC address
print("L...
I retested the newest artifact in my target setup. Works great. This PR is a game-changer. It does not only change network performance, but with this PR there is also much more memory available. Until now I was stuck with 8.0.5 with the Pico-W, because all versions afterwards did not provide enough memory, but with this PR I can leave 8.0.5 behind.
Definitely the MVP (most-valuable PR) award from my side. Looking forward to see this in a release.
I did some testing where I decreased the delays in cyw43_spi_reset() to see if I could force the failure in #7112. I was not able to reproduce the failure. Without a sample of the Pico W there's nothing more I can suggest. It's a management call whether we reduce, remove, or do nothing with the 1 second delay.
It's a pity if I made a bad choice for synthio, but it's also a pity if it doesn't match between synthio & this new functionality.
I do think it's a smart idea to synchronize their implementation. However, I'm not sure if bend is an appropriate property name in this context. And I don't think you made a bad choice on that. The only difference in implementation is to remove the / 12.0 in recalculate_rate.
Is this using a published algorithm like PSOLA or a bespoke algorithm?
It's bespoke but based on well-documented principles. My initial inspiration came from this article, http://www.technoblogy.com/show?1L02, and dissecting the Reaper pitch shifter jsfx plugin.
I can explain it in more detail or make a diagram of the algorithm if needed.
Not exactly the same, but checking out https://tic80.com might give some more ideas 😊
We could make it a compile-time constant.
We could make it a compile-time constant.
Good idea. We'd could leave it set to 1000 ms by default. You'd need to build custom CP firmware with a lower setting. For RP2350 builds we can turn it off entirely as the #7112 applies only to early RP2040 based Pico W boards.
CircuitPython version and board name
Adafruit CircuitPython 9.2.1 on 2024-11-20; Adafruit Feather ESP32 V2 with ESP32
Code/REPL
import time
import board
import max3421e
import usb
spi = board.SPI()
cs = board.D33
irq = board.D15
host_chip = max3421e.Max3421E(spi, chip_select=cs, irq=irq)
while True:
print("Finding devices:")
for device in usb.core.find(find_all=True):
# pylint: disable=line-too-long
print(f"{device.idVendor:04x}:{d...
CircuitPython version and board name
Adafruit CircuitPython 9.2.4-44-g255eea9b9c on 2025-02-09; Seeed Studio XIAO ESP32C3 with ESP32-C3FN4
Adafruit CircuitPython 9.2.4-44-g255eea9b9c on 2025-02-09; Adafruit QT Py ESP32-S3 4MB Flash 2MB PSRAM with ESP32S3
Code/REPL
from microcontroller import watchdog as w
from watchdog import WatchDogMode
w.timeout = 30
w.mode = WatchDogMode.RESET
w.feed()
while True:
pass
Behavior
When a board is reset by the...
The RP2350 includes hardware acceleration for SHA-256 and RNG (random number generator). Support for these features for use by mbedtls is included in the Pico SDK but is not activated in CircuitPython. Impacts tls performance.
@onyx hinge did you try usb host yet? mine isn't working OOB
@slender iron no I didn't. you said something about needing to enable hubs.
I ended up over in arduino land working on hstx
kk. one should work already I think. I was gonna bump it to 2 so an external one would work too
I'm excited about 720x400
is #10028 close? looks like you updated it but it has conflicts
(the auto-configure display PR)
oops I'll look at it
Just a couple of things in addition to the build failing.
I don't think you want this changed. 1024 is the width afaict.
Maybe do 640x480 anyway? That way something will still show on the display.
I can do that but do you want the same or a different mode compred to default?
Sorry, I meant all of the selected lines. This is the only spot I saw.
OK, that's 320x240@16bpp. done.
I threw an artifact onto a pimoroni_pico_dv_base_w board using the CIRCUITPY_PICODVI_ENABLE="always" setting and the display didn't come up. A dir(board.DISPLAY) just returned ['__class__']
When the new artifacts come up I'll try again with the non-w version (and a feather-dvi just to be sure I know how it's supposed to work).
The code is only enabled on a few boards and it's not available at all on rp2040 at all right now. I updated the initial comment to explain this more. Do I need to clarify the docs? It lists the specific boards that are supported.
(I do like the idea that boards with defined video pins but no guaranteed i2c pull-ups could still take an "always" setting via settings.toml and I would like to support more boards .. but that's not part of this PR)
The way board.DISPLAY is available everywhere also means that with this PR you should be able to configure a display in boot.py and use it in code.py as board.DISPLAY.
Sorry, no, I just jumped the gun before looking close enough. Checking for the existence of board.DISPLAY was a way of determining whether a builtin display was available, but I guess I can check the type now as board.DISPLAY is a Nonetype on boards that the new code is not enabled on.
An interesting observation though is that if you create a picodvi instance to bring up a display on a board not supported the board.DISPLAY object type changes to FramebufferDisplay. That's a pretty cool fe...
I appreciate the comments, it's a chance to figure out if there's more to say in documenting this.
Yes, it's true that hasattr(board, "DISPLAY") will now return True on boards with no factory-configured display, as long as they have displayio enabled. I see that this is checked at least two places in our libraries and I'm going to file a few bugs about it.
libraries/helpers/bitmapsaver/adafruit_bitmapsaver.py: if not hasattr(board, "DISPLAY"):
libraries/helpers/displa...
if not getattr(board, 'DISPLAY', None): ... will work across versions of circuitpython, I think
Your opening comment is clear enough regarding the supported boards, I just got excited when I saw all the DISPLAY entries being dropped from pins.c on other boards, I thought there may have been a scope change. I should have looked closer and realized that none of the board.c files were updated so any existing display initializations would still be in effect.
The schematic shows pull ups are present on the pico dv base so it would be a candidate for enabling the auto-dvi code.
FYI the removal of console_uart_printf broke the ability to use the console_uart_printf for tinyusb debugging: https://github.com/adafruit/circuitpython/blob/main/supervisor/shared/usb/tusb_config.h#L61
@tannewt Yes, I missed that case. Change console_uart_printf to CIRCUITPY_CONSOLE_UART_PRINTF to fix it. I'm normalizing debug macros into something less unwieldy with the RamLog facility. Would you like a PR to fix it now, or shall we wait a week or two for the RamLog PR?
@mortal kernel I tried to change it and it didn't work. I added the function back and am unblocked
Not what I expected. What went wrong?
don't remember. that memory was overwritten by usb debugging
Hah! I know how that goes. As long as CIRCUITPY_CONSOLE_UART_RX/TX are set it should have worked. I'll clone a new repo and see what's up.
Which port/board are you targeting?
I was relying on getting a build-time error for unused static symbols, which may be why I missed this one.
@mortal kernel fruit_jam on the rp2350. trying to print out tinyusb host debugging
Thanks! Hope you're enjoying your jam!
@slender iron using the metro uf2 my i2c scans ... I assume that's the i2s amp's i2c personality. Yesterday it detected a monitor at 0x80 0x50 when it was plugged in. ```Adafruit CircuitPython 9.2.3-27-g8be1681493-dirty on 2025-02-11; Adafruit Metro RP2350 with rp2350b
import board
i = board.I2C()
i.try_lock()
True
i.scan()
[24]
(this is on the fruit jam proto)
turns out they were the same
Please talk to Waveshare about this. Maybe there is some pin state that needs to be set in CircuitPython.
Yes I will, thank you sir.
@slender iron I tried to look into the serial debug problem, but with CIRCUITPY_DEBUG_TUSB set the build fails because __ZEPHYR__ is undefined.
Tried it on RP2350 works as expected. Easier to understand it all by hearing it versus trying to visualize it.
Omnimo (https://www.crowdsupply.com/eafaq/omnimo-nrf52840) is a new series of compact, all-in-one, and easy-to-use development boards that support several types of add-on modules. Thanks to its innovative pin and port positioning, Omnimo integrates various module sockets, including mikroBUS, Feather, Pmod, and Qwiic/Stemma QT, making it the most compact board capable of hosting over 2,000 different modules already available on the market.
Change it to ifdef
@slender iron Did that. The problem is that TinyUSB assumes it won't have a prototype for whatever CFG_TUSB_DEBUG_PRINTF is defined to, so it tires to make one in tusb_debug.h.
Since we're now sending in a macro, that doesn't go well. This method might be used elsewhere, so I'll submit a PR to add the function console_uart_printf back in.
Any preferences? I would use CIRCUITPY_CYW43_INIT_DELAY and update the PR accordingly.
with usb.core.Device.read https://docs.circuitpython.org/en/latest/shared-bindings/usb/core/index.html#usb.core.Device.read is it "allowed" for user code to use a buffer that is smaller than the amount of data sent by the USB device? And if that is allowed, is it expected that the count returned could be larger than 8 which is the size hardcoded for the buffer?
I have this basic script to print incoming data, and I'm finding that count is 27 even though my buffer size is 8
device = None
while device is None:
for d in usb.core.find(find_all=True):
device = d
time.sleep(0.1)
device.set_configuration()
buf = array.array("B", [0] * 8)
# ...
while True:
try:
count = device.read(0x81, buf)
print(count)
except usb.core.USBTimeoutError:
continue
And I'm also getting Hard fault: memory access or instruction error. somewhat regularly, albeit changing seemingly randomly depending on the rest of the code.
So I am hypothesizing that device.read() is reading 27 bytes, but only 8 of them goto the buffer and the rest clobber some unlucky bits in memory.
Restores console_uart_printf and fixes usage of __ZEPHYR__.
@slender iron Submitted the PR for console_uart_printf. I ran some tests with TinyUSB debugging activated. Due to the volume of messages and the slowdown induced by logging to the serial UART, it looks like an ideal candidate for RamLog. Let me know if you've got any interest in trying it out. I could use some feedback. I'll be AWK most of today.
Nice cleanup, one place I noticed.
@slender iron I thinkhttps://github.com/adafruit/circuitpython/pull/10028 is ready to go in if you can take a quick look
If a board has a HSTX or DVI connector, and it has I2C pull-ups built in, it's possible to auto-configure the display.
This is implemented for 2 boards: feather rp2350 & metro rp235...
and #10040 if you feel like it, but that one's not blocking anything
ok, will look now
just getting to the office
I suspect my i2c problem was my hdmi cable
@jepler I don't think board.DISPLAY should exist on everything because it is on "board". board should only have board specific things in it. I think it is valid to check hasattr.
Instead I'd like to move to supervisor.runtime.display: https://github.com/adafruit/circuitpython/issues/8675
One small thing plus changing board.DISPLAY presence on some boards.
Please write out these three options so they are searchable.
@slender iron just checking, do you want me to fully revert the board.DISPLAY part of the changes?
I didn't understand that it'd be available on all boards then
The first time you reviewed it, it wasn't.
we don't have any defines that say if a board has a display do we
since board_init sets it up
nope, we don't.
Maybe it'd be better to add one that has the display type? so we can factor out the auto-init in the future?
What specifically would you like me to do for right now, so that board.DISPLAY is available on these rp2350 boards that may or may not initialize a HDMI display at boot time? I think getting this PR unblocked is more important than realizing an ideal long range plan right now.
(I'm a bit sad, I felt like using this new technique made board.DISPLAY work strictly better than before, with very little code. Because you could for instance configure a display that you've permanently attached inside of boot.py and use it in code.py as though it was always part of the board. It's true that it's a bit "impure" since strictly speaking it makes displays that are not "part of the board" appear as board.DISPLAY too, but then by that logic NO DVI display could appear as board.DISPLAY because it's on the wrong side of a connector and is strictly optional)
I don't care that it is board.DISPLAY on rp2350. I mainly want the console to auto appear. Maybe add supervisor.runtime.display now?
and make it work like your board.DISPLAY does now
.. across bindings & shared-bindings. This is more modern usage preferred in micropython.
the goal of that work is to not need release_displays anymore
only the supervisor's display lives longer
and can be referenced across VMs
other displays could be init but would be stopped at the end of code execution
@onyx hinge is that ok or am I being too much of a purist?
having to change libraries for the new behavior was a red flag for me
@slender iron It's fine.
I think the existing library code was kinda wrong already, because it didn't check whether board.DISPLAY had been released via displayio.release_displays() either. As I'm sure some bug or other has discussed, in that case board.DISPLAY becomes a none-like object that is not None....
My guess is that the audio_dma changes increased code size just a little. Try it with the latest changes. Jeff just saved some space that may make this work.
I definitely don't want to change the filesystem size because that will break all upgrades.
@slender iron in your ideal conception, would the first created display become supervisor.runtime.display or does it require explicit action? Would auto dvi on rp2350 be an exception? With the "easy to do right now" code, the first created display would always become supervisor.runtime.display
my intent is that it does require explicit action for user inited displays
instead of assuming that's where folks want the console
so board.DISPLAYS and auto dvi would be auto-init and set
(because CP does it)
explicit action means that release_displays isn't needed in examples
//| True when `raw_value` > `threshold`."""
One rogue vim-put? Looks great otherwise. @Randall-Scharpf this may get you the space you need.
oops! I wasn't checking closely enough.
Requesting review. No hurry, I see everyone is super busy.
One small documentation thing. Good otherwise! Please file a 10.0.0 issue to remove the old way. 9.2.4+ can be the transition versions.
Thank you for the thorough issue. Would you mind filing a pull request with this change? I bet the other conversions to RGB888 have the same issue. (RP2350 HSTX has this issue too.)
Support for an RM2 module on the new Fruit Jam would be so nice. Let me see what I can do to make that happen.
Don't spend too much time on this. We're more likely to use an ESP32-CX for a wifi coprocessor. RM2 aren't very available yet from what I can tell.
Please ensure the automatic tests pass.
Please don't use the Adafruit USB VID.
Using circuitpython 9.2.4 on an M5stack Atom S3 lite.
installed libs:
- neopixel
- adafruit_requests
- adafruit_connection_manager
- bluepad32
- adafruit_esp32spi
- adafruit_bus_device
- adafruit_ble
I'm trying to connect to Lego WEDO brick to send commands (haven't got there yet).
Also first version of code (with a more generalized approach: start_scan(Advertisement)) worked for scanning, but returned too little information - no device names (usually use it to find the device to connect)...
I transferred this to the CircuitPython repo since it is a hard crash.
@slender iron https://github.com/adafruit/circuitpython/pull/10028 updated again.
supervisor.runtime.displaywill be set to a display set by Cboard_init()but not automatically set to a display set by a python script- but the property is settable, so boot or code files can init a display and then assign it to
supervisor.runtime.displayfor use in future runs - the stage is set for
reset_displaysto only reset other displays than thesupervisor.runtime.displaybut this isn't turned on yet.
Hopefully it builds OK.
If this is still not passing muster maybe we should get on a voice or video call to iron it out, because this is somewhat blocking both of us right now and I'd like to get it sorted.
In #9804 we deprecated the original synthio biquads in favor of the new BlockBiquads. For version 10, make the incompatible change of actually removing the old biquads.
@slender iron once again the history there has become a mess. but it might be better to merge the messy history than have me spend time rebasing it. If you don't feel strongly.
either way is fine with me
@slender iron let me see how it looks after rebasing
A couple small things. Otherwise this looks right! Thank you.
//| """The primary configured displayio display, if any.
I think this is what you want.
if (keep_primary && i == primary_display_number) {
That's originally what I had, but I changed it. Here's my logic: If !keep_primary, then primary_display_number was updated just above and will always be -1 here. -1 will never be equal to the loop counter.
This partially implements #8675. Releasing non-primary displays is left for a 10.0 incompatible change. The allocation of I2C and SPI bus objects is unchanged, rather than allocating them outside the GC heap as suggested in that PR.
This can be enabled on additional boards provided the board:
- has a HSTX or DVI connector built in
- connects the primary I2C bus to this connector
- has pull-ups on this connector
- for RP2040, a
preflightfunction needs to be written to check the r...
@slender iron the rebased version is now at https://github.com/adafruit/circuitpython/pull/10062 so that old reviews are still useful.
This partially implements #8675. Releasing non-primary displays is left for a 10.0 incompatible change. The allocation of I2C and SPI bus objects is unchanged, rather than allocating them outside t...
CI still waiting to build #10062 😢
Since #10062 we have supervisor.runtime.display which can be set from code or by the C board init function, and then accessed across multiple invocations of code.py.
As an incompatible change in CircuitPython 10, release non-primary displays when shutting down the interpreter. This is the next step towards fully implementing #8675. (Changing how i2c and spi objects used by display buses are allocated is the final, and hardest, part)
@slender iron it might be interesting to set the max display count to 2 on the fruit jam, since it has both a HSTX connector and an EyeSpi connector.
One small documentation thing. Good otherwise! Please file a 10.0.0 issue to remove the old way. 9.2.4+ can be the transition versions.
Reverted the filesystem size back to 64KB and merged in the latest changes from main and it fits in the allocated space now.
I'm getting an error when circup attempts to get the 9.x bundle:
There was a problem downloading that platform bundle. Skipping and using existing download if available.
Not really a critical issue, as I assume I can just go out and manually get the files I need....
with --verbose, it looks like circup is trying to get the 8.x bundles and getting a 404.
specifically:
02/13/2025 21:58:38 WARNING: Unable to connect to https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/download/20250214/adafruit-circuitpython-bundle-8.x-mpy-20250214.zip
There was a problem downloading that platform bundle. Skipping and using existing download if available.
02/13/2025 21:58:38 ERROR: 404 Client Error: Not Found for url: https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/download/20250214/adafruit-circuitpython-bundle-8.x-mpy-20250214.zip
Traceback (most recent call last):
File "/opt/homebrew/lib/python3.13/site-packages/circup/command_utils.py", line 137, in ensure_latest_bundle
Ah, I think there was talk of discontinuing the 8.x bundles so it's probably related....
and there hasn't been a release of circup yet, the change was made yesterday (in circup)
these shouldn't be defined or used. Please remove.
btw it looks quite likley there are other "stragglers" like this, which is my fault. But let's not add more.
I have no idea about the performance of the algorithm, and didn't test it on HW.
I do have some notes about the code structure that I'd like to see addressed.
it's newly necessary to call audiosample_mark_deinit(&self->base) here.
It looks like I missed this in several cases in the recent conversion, which is my fault. But let's not make more mistakes.
[note to self: everywhere we divide bits per sample by 8. it might be a savings overall to store bytes per sample instead]
setting these fields should remain, because it allows GC to release the related storage for object allocation.
- consistently use audiosample_mark_deinit
- remove unused functions and their prototypes, such as
common_hal_audioio_rawsample_get_sample_rate(audioio_rawsample_obj_t *self);
These notes stem from my review of https://github.com/adafruit/circuitpython/pull/10052
The missing use of mark_deinit is probably going to be causing some bugs, like the ability to use a sample after it was deinitialized, in some contexts.
I've made a new release for circup just now that should resolve that issue. Thanks for mentioning it here, and thanks to Neradoc and todbot for checking into it.
I've been excitedly watching the CP Zephyr port advance, and I'm eager to test what's working on my nRF53 Audio DK, but not sure how. @slender iron previously mentioned adding support, but where do I look?
Do I need to build the entire project in NCS/Zephyr and flash it that way, or is there a prebuilt .hex available that I can flash via J-Link? Any suggestions?
I can build you a hex
I don't want to distract you from FruitJam!
Well, if you need a momentary distraction, I'd love to experiment. Let me know...
building it now while I eat breakfast. no promises it works
Thanks very much. Looking forward to this afternoon's Deep Dive.
for audio dk
Awesome. TYVM.
doesn't look like it has any external flash
Hi
I'm having the same issue when using a RP2350 based board, and on different GPIOs than above, not used by anything else in my case. Strangely, a full hardware reset does not help, so it indicates that the L1 pwmio object creation does not allow the creation of R2. Note that I'm using on purpose GPIOs corresponding to the same PWM slice for L1/R1 (slice #1) and L2/R2 (slice #5), as I do need them to share the clock frequency, but not the duty cycle later.
import board, pwmio
PWML1...
(so no circuitpy drive. just repl)
Understood.
I'm still working my way up to dev, but maybe the SD card is a possibility.
west build --sysbuild -b nrf5340_audio_dk/nrf5340/cpuapp
have you done zephyr before?
Yes, though by force as it's the only way to program the ADK.
You may know better than me how to change the internal flash partition. If you add a circuitpy_partition then it should use it.
I'm still intermediate, but looking forward to playing with this all weekend!
great! it should be familiar to you if you've done zephyr
do west init within ports/zephyr-cp and then west update
Got it. Thanks again for your help, and especially for CP, which is a joy.
np!
Thanks for the board definition. Espressif gives out unique PIDs so please request one.
This is a generic Espressif PID. Please request a unique one here: https://github.com/espressif/usb-pids
Thanks for the board definition! Looks like there is some white space to trim. Setting up pre-commit locally can have this done automatically.
CircuitPython version
Adafruit CircuitPython 9.2.4 on 2025-01-29
Code
can = canio.CAN(rx = board.D15, tx = board.D33, baudrate = some_custom_value)
When the some_custom_value is not in the list of a few predefined values (250000, 125000, etc.), it fails to configure. The same behaviour confirmed with ESP32-S2, ESP32-S3.
Sometimes an experienced user may want a baudrate value outside the list. And unfortunatelly there's no option to pass raw timings there. Even memorymap.Addr...
This updates the board to hopefully now offer full installation along with bootloader only options in the installer
Is it possible for circup to error gracefully if it can't find a bundle and say it's using the last one of got? I can imagine people struggling to find out why it's not working and not automatically upgrading...
it's also worth considering that different bundles might support different versions rather than all changing on the same day...
OK back with more info but not really helpful. I got the Adafruit AHT20 yesterday. I first upgraded my S2 back to 9.2.4 and verified again that
i2c = board.STEMMA_I2C()
displayio.release_displays()
display_bus = i2cdisplaybus.I2CDisplayBus(i2c, device_address=0x3C)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64)
ali_sensor = adafruit_ahtx0.AHTx0(i2c) # WeAct AHT20-F T&H Sensor
ada_sensor = adafruit_sht4x.SHT4x(i2c) # Adafruit 5776 Sensor
work...
Do you think you could give this logic-analyzer a try: https://github.com/gusmanb/logicanalyzer
It is very simple to use, you basically need a Pico for it (the logic-analyzer is on top, the DUT with the AHT20 below):
You will see something like this in the analysis software:
As you can see, this is with version...
I think this can be closed as #10027 is merged now.
Thanks! This looks like it implements what we discussed over the course of the PR.
@Timeline8 Could you try adding some delays around the initialization of each I2C device? Something like 0.5 seconds should be more than adequate.
@bablokb, that is pretty neat. I will have to try it out when I get a chance. Is the project compiled strictly for Pico boards (for their onboard hardware and more specifically their pinouts) or can it be adapted to any RP2040 board?
@dhalbert, I will try adding some delays perhaps later today and see if I come up with any different behavior. And now that I think about it, I can also try change the order in which those devices are initiated to see if that does anything different.
@bablokb, that is pretty neat. I will have to try it out when I get a chance. Is the project compiled strictly for Pico boards (for their onboard hardware and more specifically their pinouts) or can it be adapted to any RP2040 board?
I think they support Pico, Pico-W and Pico2 plus a Zero-variant, I think from Waveshare. The firmware for the logic-analyzer is not written in Python, so probably portable but not configurable.
I'm seeing the same issue using a Feather ESP32-S2 and a Feather ESP32-S3 4m/2m. I think I got the Arduino simple example to detect occasionally but it only seemed to happen when I picked up the feather double so I think perhaps some signal noise may have been involved.
I did get a back to back QtPy ESP32-S2/USB host BFF working properly, however using jumper leads to connect the BFF to the Feather boards did not work. I also tried a QtPy ESP32-C3 and that had more serious problems (Circuit...
I can hookup a Feather S2/S3 to confirm the behavior.
I think they support Pico, Pico-W and Pico2 plus a Zero-variant, I think from Waveshare. The firmware for the logic-analyzer is not written in Python, so probably portable but not configurable.
Darn. I do have one Pico W board but it is currently in use in my basement. I have a Seeed XIAO RP2040 (bought by accident) not in use so thought maybe that would work. But if not, since I have been meaning to make some changes to that basement Pico setup anyway, might be a good opportunity to switc...
Feather ESP32-S2 Rev TFT
CircuitPython 9.2.4
It felt slow and unstable, but this controller did see the connected microSD card (briefly). Notice the Finding devices initially didn't pick it up over the first few passes, but then it did discover it.
Adafruit CircuitPython 9.2.4 on 2025-01-29; Adafruit Feather ESP32-S2 Reverse TFT with ESP32S2
>>>
soft reboot
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Finding devices:
Finding devic...
Or just crack open the wallet and spend another whopping (/s) $6 to get a second Pico W (or $4 for the non-W).
I would really recommend the Pico-W, since the analyzer software can control the device via wlan and this greatly simplifies the mechanical setup. I also use a small LiPo and thus I can just place the whole package next to the DUT and connect it with a few cables. See https://github.com/bablokb/3D-pico-lipo-shim
Corrected height value which had been incorrectly set at 640 not 480.
Recent #10062 added support for the supervisor.runtime.display property, which holds a reference to a designated primary display.
For deep sleep, displays are released. For fake deep sleep, the C function board_init() is called so as to simulate the board reset sequence. However, boot.py is not re-run in the case of fake deep sleep.
A consequence of this is that supervisor.runtime.display will be cleared for fake deep sleep, and the display will not be available when fake deep slee...
This PR allows a one-line code.py to be specified in a port's mpconfigboard.mk so a product's full firmware can be built in CI.
The intended use is something like this in mpconfigboard.mk:
FROZEN_MPY_DIRS += $(TOP)/ports/raspberrypi/boards/raspberry_pi_pico_todbot
CIRCUITPY_CODEPY_CONTENTS="import some_awesome_code\n"
and then some_awesome_code.py containing what would normally be code.py is located in the port's directory.
Recently in Discord, @tannewt encountered that zephyr uses different numeric values for some socket-related constants (vs lwip)
For core ssl support to work with pure Python socket implementations, such as wiznet, we had to promise that socket constants used by the ssl implementation would be the same numeric constants always, regardless of the internal implementation of sockets.
I think that the sole constant we depend on is is SOCK_STREAM = 1. This is because SSL can work on STREAM type...
This PR allows a one-line code.py to be specified in a port's mpconfigboard.mk so a product's full firmware can be built in CI. The intended use is something like the following in mpconfigboard.mk:
FROZEN_MPY_DIRS += $(TOP)/ports/raspberrypi/boards/raspberry_pi_pico_todbot
CIRCUITPY_CODEPY_CONTENTS="import some_awesome_code\n"
and then some_awesome_code.py located in the port's directory contains what would normally be code.py.
(I would rather we have the ability to...
CircuitPython is old enough now that people (including myself) are selling products using it.
But installing the firmware for these products is pretty onerous for the end user:
- Trigger UF2 bootloader
- Install CircuitPython
- Wait for CircuitPython to present CIRCUITPY drive
- Copy over needed libraries to CIRCUITPY
- Copy over
settings.tomlandcode.py - Reset
- Be sure to watch REPL in case you didn't copy the library files correctly!
In the case of RP2040/RP2350, we can at least u...
esptool.py also has dump/load options that can do all of flash. So you could use it like you use picotool.
I purchased the Adafruit Trinket M0, not realizing it didn't have support for pulseio, my mistake, I should've checked.
I was just wondering if there will be any possibility for current or future implementation of the pulseio module for the Trinket M0?
There is an implementation but it doesn't fit in the 192kB of firmware space available on the Trinket M0. It's on other SAMD21 boards and also many other more capable boards of similar size, such the as QT Py RP2040.
There is an implementation but it doesn't fit in the 192kB of firmware space available on the Trinket M0. It's on other SAMD21 boards and also many other more capable boards of similar size, such the as QT Py RP2040.
Gotcha, appreciate the response!
Check https://docs.circuitpython.org/en/latest/shared-bindings/support_matrix.html and type pulseio in the search box to see which boards support it.
Agreed, but requiring the user to install esptool.py for product updates is also asking a lot.
Agreed, but requiring the user to install esptool.py for product updates is also asking a lot.
You can point the user to https://adafruit.github.io/Adafruit_WebSerial_ESPTool/ or similar browser tools. Especially on Espressif chips, since the UF2 bootloader is not protected, they may need to be familiar with it anyway.
I get
"git.exe push --set-upstream --progress "origin" fix-displayio_colorconverter_555-main
remote: Permission to adafruit/circuitpython.git denied to qutefox.
fatal: unable to access 'https://github.com/adafruit/circuitpython/': The requested URL returned error: 403"
when I try to push my changes into a new branch started from main. I don't know what I am doing wrong.
Here is the patch file:
[0001-fix-displayio-ColorConverter-was-inaccurate-when-con.patch](https://github.com/user-attach...
That's because you must work in your fork and PR from there:
https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/grab-your-fork
…orspace to rgb888. For details look at: https://stackoverflow.com/questions/71106056/what-is-the-correct-way-to-convert-rgb555-to-rgb888. I only tested rgb555 and not the bgr555 code path!
heya <@&356864093652516868> just a quick reminder that due to a US holiday the meeting is on TUESDAY this week. See you tomorrow! As always you can add your notes in advance to the notes doc: https://docs.google.com/document/d/1oM_x1t2iD_iStf4riPa5j_naS-yqZAR-Y8_qKyVpa7s/edit?usp=sharing
CircuitPython Weekly Meeting for February 18th, 2025 THIS MEETING IS ON TUESDAY! 24 hours later than normal. Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go thr...
I've removed these unnecessary function declarations from the following: RawSample, WaveFile, Echo, PitchShift, Distortion, Filter, Mixer, MP3Decoder, MidiTrack, and Synthesizer.
I've added audiosample_mark_deinit(...) to the following: Echo, PitchShift, Distortion, Filter, and Mixer.
I am a little confused as to how you'd like me to implement this. I'll use audiofilters.Filter as an example.
check_for_deinit is implemented within shared-bindings/audiofilters/Filter.c as a static method:
Yet, the original common_hal_audiofilters_filter_deinited(...) method still exists and is used within `shared-module/audiofilters/Filter....
Although bits per sample makes more sense semantically for audio applications, I haven't found a single location where it is necessary to measure this value in bits rather than bytes after thumbing through the repository. I'm not sure the change would bring a significant savings in memory or performance, but I'm for the change.
The various functions mean:
- "check_for_deinit" -> throw an exception if deinitialized (no return value). Will call "deinited" and branch on the result.
- "deinited" -> return true if deinitialized, false otherwise
- "deinit", "mark_deinit" -> change object fields so as to release resources & allow "deinited" function to work.
The goal of audiosample_deinited is to provide one consistent way for all audio sample types to recognize they are deinited while reducing the flash size ...
by now cooper knows how much of an amateur I am at coding 🤣 🙊
Thank you for the explanation. That makes sense for the most part. I'll make adjustments to this new effect as well as elsewhere I see fit.
I'm definitely happy that we're unifying the implementation of audiosample objects even if there are some growing pains.
Maybe there's potential for an additional layer to be added to audio effects to handle some of the shared functionality of those objects:
- double-buffering
- sample word conversion (8-bit & unsigned 16-bit to signed 16-bit and ...
I definitely want to get to get rid of the "single_channel_output" handling in every get_buffer function and move it to a common spot, allowing the logic to be removed entirely if it is not needed on the HW. This is https://github.com/adafruit/circuitpython/issues/9877
For the rest, the goals sound good but I don't know how to chart a path to them. Fresh issue(s) are probably a better place for this (more visibility) but either way I don't think I'll be contributing much in this area right...
I've had similar thoughts on a few items that seem common across all audio, or are based on older MCUs that will never run audio effects (or potentially a lot of audio). 8 vs 16 bit, signed vs unsigned, etc.
Maybe an issue about audio improvements to collect the ideas and then details issues per makes sense. Just my 2 cents.
Hey dude, we all miss stuff here and there. And I am by no means an expert!
@FK-sauve Some messages in French have a leading space before the comma, and some don't. What is your rule about this? I found some discussion here.
Would it be possible / desirable to have a board.SD_SPI() on something like the Metro RP2350 where it has a built-in SDCard reader which is connected to one of the two available SPI busses? It has board.SPI() for the other available bus, and it has the pins which can be used with busio, but it could be convenient to have a shorthand for the SDCard bus perhaps.
personally i think that would be really useful
The tutorials for how to use the sd card still couldn't use it, because not all boards have it, and you don't want to share the spi connected to the sd card with other devices, because the card doesn't start in spi mode and would interfere with communication, so making it a singleton doesn't help in this particular case much. So the only benefit would be not specifying the pins explicitly. But explicit is better than implicit...
That's fine with me! My hope is to add SD card automounting though
That may remove the need for it at all
howdy folks and especially <@&356864093652516868>, I'll step on host @lone axle's toes a tiny bit to announce that our weekly meeting is happening in about 70 minutes in the CircuitPython voice channel, meaning it's a good time to add your notes if you haven't already. The google doc is at https://docs.google.com/document/d/1oM_x1t2iD_iStf4riPa5j_naS-yqZAR-Y8_qKyVpa7s/edit?usp=sharing and I'm going to go add mine right now!
CircuitPython Weekly Meeting for February 18th, 2025 THIS MEETING IS ON TUESDAY! 24 hours later than normal. Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go thr...
@lone axle if you select the pasted in report stuff in the notes doc, copy it, and then right-click "Paste from markdown" on top of the selection, it will reformat as styled Google Docs text. Then, when you "Download as Markdown", it will get converted back to Markdown.
Paste from markdown does require a chrome extension to work I believe
It's built in to Google docs now, but you might have to enable markdown support.
"Paste from Markdown" is also in the Edit menu
@lone axle I am especially thinking of the bullet lists
I do see it in my context menu after enabling the checkbox in preferences. Thank you
🙁
I switched to chrome to do it
they allow you to enable it, but not actually use it.
oh google, you've come so far from the scrappy little company that wanted to do no evil. </sarcasm>
Sorry to gank the last ones, chrome works for me as well. I'll try to remember to copy them that way next time.
and I also set the headings to the right levels with the paragraph style menu in the toolbar at the top
@lone axle I can read core or blinka if you like. just let me know.
Thank you, I'll pass to you for Blinka.
@slender iron will you be around able to read for the core section?
yup
Agreed, but requiring the user to install esptool.py for product updates is also asking a lot.
Do we really need CircuitPython to support this? Would it be enough to have a folder -> fat filesystem -> uf2 converter? This would be orthogonal to CircuitPython except for placing the filesystem in the same place.
I don't really want to bundle with CP itself because it'll overwrite the user's file system.
Also, I think many other UF2 bootloaders besides the RP2 version have a current.uf2 file that images the whole filesystem.
Somehow the board descriptions of these two boards are swapped.
This would be ok with me but I'm not sure it is actually what you want. These are really default contents that are stored forever in the firmware. Instead, I suspect you want an easy way to provide a CIRCUITPY image to install alongside a version of CircuitPython. #10074 is a better place to discuss options.
I suspect this will crash the Zephyr ports because they don't use make and won't have the new define. We should test that if we want to actually merge this.
Want the latest on @oshwassociation.bsky.social's open source hardware certification program?
Got 18 minutes and 28 seconds to spare?
My FOSDEM talk on lessons learned from 10 years of certifying open source hardware is now live ftp.belnet.be/mirror/FOSDE...
If you’re a fan of open-source technology, Gustavo Salvador Reynaga Aguilar is a name to know. An experienced educator with a passion for technology, Reynaga has spent nearly three decades teaching and inspiring students at CECATI 132 in Mexico. He’s worked with platforms like Arduino, Raspberry Pi, and BeagleBone, and is renowned for projects s...
the link is https://adafruit-playground.com/playground/pages.atom but I may have spoken too soon, my feed reader (newsblur) doesn't seem to like the content there
I sent an email internally to the team in charge of playground so with any luck that'll get resolved soon.
720x400 is an aspect ratio of 1.8 (9/5), vs 1.7778 (16/9), so just a few percent un-square
dvhstx has a dedicated text mode with "RGB111" color (foreground colors only, always on black background, I think?). It'd be much higher performance than doing everything via bitmaps.... but it wouldn't "be displayio".
[I was writing in the notes about the history of why CAMERA is disabled on a bunch of espressif 4MB boards in the notes doc...]
thanks all! 🦷 dentist time for me
thanks Tim!
Thanks everyone. Have a great week!
Thanks!
This is the most usefull and frustrating feature of Adafruit shop... now I know I have one, but I need to find it:
hold an empty box in your hand, pretend you just received it, and go put it away — it will be there
I am checking the other item in the same order... my expectation is that once I see one of those, the other should not be too far. 😉
I've been searching for a bag of connectors I'm sure I have for the last three months, yesterday I gave up and reordered them, I expect to find them any minute now
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/1nJs-ZrRGrey76S8DlqTuS4wzoIXLvEyXdewi0lbNx3o/edit?usp=sharing
CircuitPython Weekly Meeting for February 24, 2025 Welcome to the CircuitPython Weekly meeting notes! Feel free to add your Hug Reports and Status Updates before the meeting, alphabetically by your username. During the meeting, we go through them in order. If you can’t make the meeting and would...
[...] I suspect you want an easy way to provide a CIRCUITPY image to install alongside a version of CircuitPython. #10074 is a better place to discuss options.
Yep, as mentioned in #10074 having a CIRCUITPY image maker is really what's wanted. This PR was a stop-gap to solve the problem I've seen people ask for (and I've been using) for several years.
Do we really need CircuitPython to support this? Would it be enough to have a folder -> fat filesystem -> uf2 converter? This would be orthogonal to CircuitPython except for placing the filesystem in the same place.
This would be ideal. Is there a way to pull out of a CircuitPython UF2 all the information needed to append the CIRCUITPY filesystem? It seemed to me this hypothetical tool would need to know some internals of particular CircuitPython builds in order to do that. And/or would ...
Is there a good place to look to understand, for a given port and board, how specifically are the bootloader, CircuitPython firmware image, NVM, and CIRCUITPY drive assigned to addresses in flash. Like, what goes where in internal flash and external flash (not where things get loaded into RAM)? I see that ports/$FOO/mpconfigport.h has stuff like CIRCUITPY_FIRMWARE_SIZE, CIRCUITPY_INTERNAL_NVM_SIZE, and CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR which look relevant. I also see address space layout info in .ld files, but I'm not sure how that relates to addresses in RAM vs. where things get stored in flash.
Context for my question is, to define flash partition layouts for Zephyr board definitions, it would be nice to avoid stomping on the CircuitPython bootloader, CIRCUITPY drive contents, etc.
I can see why it wouldn't fit in builtins (although rotaryio made the cut), but is there a way to have it as a loadable mpy that could fit on local storage? Is there code that I could cross-compile, or is that not for ordinary mortals?
thanks!
Is there a current plan in motion to kill all the secrets in guides and libs and examples?
If not and wanted, I can start down this path...
I don't know of one
It varies port to port unfortunately. Very related to @devout jolt's question on issue #10074
circuitpython doesn't vary the CIRCUITPY location build to build except some major version changes. we want to preserve the CIRCUITPY contents on upgrades.
so maybe it would make sense to just try matching whatever address range is in the firmware .uf2 file for a given port/board?
the linker scripts are probably the "ground truth" since linking fails when the firmware is too large
I don't think that'd be reliable because the firmware may be much smaller than the space we've set aside
oh, right, I follow
hmm... guess I'm gonna have to spend some more time reading code and pondering this
thanks
My current quest is writing guides on display/sensors/CLUE-nrf52840-BLE
I was using the Feather RP2350 as an intro-to-writing-a-board-def practice
but now my order showed up with the CLUE board, so I'd been thinking of switching more of my attention to that
yeah. lots of partition excitement there
Also, if you see the potential for me to plug into something with rp2 in a way that would help things along for you, and pt likes it, that works too
nrf uses the C preprocessor to get info about the size of things unfortunately
nrf is more interesting than rp2 I think
for my zephyr stuff because the newer nordic boards will be some of the first on zephyr
we don't need to be partition compatible for those though
yeah, I'm expecting it to be tricky, but should make for some good writeups
(we don't need to be partition compatible because they are new)