← index #17863Issue #16248
Off-topic · high · value 1.781
QUERY · ISSUE

RP2 hangs when using I2S and bitstream

openby robtinkersopened 2025-08-07updated 2026-03-19
bugport-rp2

Port, board and/or hardware

rp2

MicroPython version

MicroPython v1.25.0 on 2025-04-15; Raspberry Pi Pico with RP2040

Reproduction

Running the following code in Thonny.

I have run it on an official Pico 2 W, and an RP2040-zero board from AliExpress.

I have run it on stock firmware (1.25.0), the stock ulab firmware (based on 1.24.0), and my own build (1.26.0-preview + ulab).

I have run it with both the external peripherals attached (8x8 WS2812B matrix and an INMP441 clone from AliExpress), and nothing attached to the board other than USB power.

All exhibit the same problem.

import machine, sys
from machine import Pin, I2S
from neopixel import NeoPixel

MTX_DIN = const(14)

MIC_ID  = const(0)
MIC_SCK = const(6)
MIC_WS  = const(7)
MIC_SD  = const(8)

SAMPLE_RATE = const(22050) # Hz
SAMPLE_BITS = const(16)
SAMPLE_COUNT = const(512)

if sys.platform == 'rp2':
    assert MIC_WS == MIC_SCK + 1

mtx = NeoPixel(Pin(MTX_DIN), 64)

raw = bytearray(SAMPLE_COUNT * SAMPLE_BITS // 8)

mic = None
try:
    mic = I2S(MIC_ID,
              sck=Pin(MIC_SCK), ws=Pin(MIC_WS), sd=Pin(MIC_SD),
              rate=SAMPLE_RATE, bits=SAMPLE_BITS,
              mode=I2S.RX, format=I2S.MONO,
              ibuf=len(raw)*2)
    
    loop = 0
    while True:
        print(loop, 'loop begins')
        
        num_bytes_read = mic.readinto(raw)
        assert (num_bytes_read == len(raw))
        print(loop, 'microphone read')
        
        mtx.write() # hangs
#        machine.bitstream(mtx.pin, 0, mtx.timing, mtx.buf) # hangs, equivalent to mtx.write()
#        machine.bitstream(mtx.pin, 0, mtx.timing, mtx.buf[:144]) # hangs
#        machine.bitstream(mtx.pin, 0, mtx.timing, mtx.buf[:72]) # usually works
        print(loop, 'bitstream() done')
        
        loop = loop + 1
        print('next', loop)

except Exception as e:
    sys.print_exception(e)

finally:
    try: mic.deinit()
    except: pass

Expected behaviour

The loop runs indefinitely.

Observed behaviour

0 loop begins
0 microphone read
0 bitstream() done
next 1

(and nothing else, it doesn't actually start the next loop, and the device must be power-cycled)

If I replace mtx.write() with one of the alternatives, it either hangs (for larger numbers of bytes) or runs fine (smaller number of bytes).

Additional Information

Slightly different versions of the code were sometimes printing unexpected strings instead of "next" (for example "enable_irq" and "bin")

Code of Conduct

Yes, I agree

CANDIDATE · ISSUE

USB (tested with midi) not working on pico 2 (rp2350 in ARM mode only)

openby ghostopened 2024-11-15updated 2024-11-15
bug

Port, board and/or hardware

rp2 port, pico 2 board

MicroPython version

MicroPython v1.24.0 on 2024-10-25; Raspberry Pi Pico2 with RP2350

Reproduction

This is the script I used:

# MicroPython USB MIDI example
#
# This example demonstrates creating a custom MIDI device.
#
# To run this example:
#
# 1. Make sure `usb-device-midi` is installed via: mpremote mip install usb-device-midi
#
# 2. Run the example via: mpremote run midi_example.py
#
# 3. mpremote will exit with an error after the previous step, because when the
#    example runs the existing USB device disconnects and then re-enumerates with
#    the MIDI interface present. At this point, the example is running.
#
# 4. To see output from the example, re-connect: mpremote connect PORTNAME
#
#
# MIT license; Copyright (c) 2023-2024 Angus Gratton
import usb.device
from usb.device.midi import MIDIInterface
import time


class MIDIExample(MIDIInterface):
    # Very simple example event handler functions, showing how to receive note
    # and control change messages sent from the host to the device.
    #
    # If you need to send MIDI data to the host, then it's fine to instantiate
    # MIDIInterface class directly.

    def on_open(self):
        super().on_open()
        print("Device opened by host")

    def on_note_on(self, channel, pitch, vel):
        print(f"RX Note On channel {channel} pitch {pitch} velocity {vel}")

    def on_note_off(self, channel, pitch, vel):
        print(f"RX Note Off channel {channel} pitch {pitch} velocity {vel}")

    def on_control_change(self, channel, controller, value):
        print(f"RX Control channel {channel} controller {controller} value {value}")


m = MIDIExample()
# Remove builtin_driver=True if you don't want the MicroPython serial REPL available.
usb.device.get().init(m, builtin_driver=True)

print("Waiting for USB host to configure the interface...")

while not m.is_open():
    time.sleep_ms(100)

print("Starting MIDI loop...")

# TX constants
CHANNEL = 0
PITCH = 60
CONTROLLER = 64

control_val = 0

while m.is_open():
    time.sleep(1)
    print(f"TX Note On channel {CHANNEL} pitch {PITCH}")
    m.note_on(CHANNEL, PITCH)  # Velocity is an optional third argument
    time.sleep(0.5)
    print(f"TX Note Off channel {CHANNEL} pitch {PITCH}")
    m.note_off(CHANNEL, PITCH)
    time.sleep(1)
    print(f"TX Control channel {CHANNEL} controller {CONTROLLER} value {control_val}")
    m.control_change(CHANNEL, CONTROLLER, control_val)
    control_val += 1
    if control_val == 0x7F:
        control_val = 0
    time.sleep(1)

print("USB host has reset device, example done.")

Expected behaviour

This example code works on a pico 1, here is the output:

MicroPython v1.24.0 on 2024-10-25; Raspberry Pi Pico with RP2040
Type "help()" for more information.
>>> import midi_example
Waiting for USB host to configure the interface...
device disconnected

then mpremote disconnects. I can reconnect and it displays the log output from the example.

kernel log display:

 6041.587646] usb 7-1.1: new full-speed USB device number 9 using xhci_hcd
[ 6041.722135] usb 7-1.1: New USB device found, idVendor=2e8a, idProduct=0005, bcdDevice= 1.00
[ 6041.722144] usb 7-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 6041.722149] usb 7-1.1: Product: Board in FS mode
[ 6041.722153] usb 7-1.1: Manufacturer: MicroPython
[ 6041.722156] usb 7-1.1: SerialNumber: e6613008e343372e
[ 6041.787350] cdc_acm 7-1.1:1.0: ttyACM0: USB ACM device
[ 6259.833061] usb 7-1.1: USB disconnect, device number 9
[ 6260.104404] usb 7-1.1: new full-speed USB device number 10 using xhci_hcd
[ 6260.239359] usb 7-1.1: New USB device found, idVendor=2e8a, idProduct=0005, bcdDevice= 1.00
[ 6260.239362] usb 7-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 6260.239364] usb 7-1.1: Product: Board in FS mode
[ 6260.239365] usb 7-1.1: Manufacturer: MicroPython
[ 6260.239366] usb 7-1.1: SerialNumber: e6613008e343372e
[ 6260.285551] cdc_acm 7-1.1:1.0: ttyACM0: USB ACM device
[ 6260.334768] mc: Linux media interface: v0.10
[ 6260.411764] usbcore: registered new interface driver snd-usb-audio

Observed behaviour

This is the output on the rp2 REPL:

>>> import midi_example
Waiting for USB host to configure the interface...

and it hangs, control characters have no effect.

Meanwhile here is the kernel log:

[ 5138.193121] usb 7-1.1: new full-speed USB device number 4 using xhci_hcd
[ 5138.327835] usb 7-1.1: New USB device found, idVendor=2e8a, idProduct=0005, bcdDevice= 1.00
[ 5138.327845] usb 7-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 5138.327850] usb 7-1.1: Product: Board in FS mode
[ 5138.327855] usb 7-1.1: Manufacturer: MicroPython
[ 5138.327858] usb 7-1.1: SerialNumber: 1c59c033388f3e4e
[ 5138.437887] cdc_acm 7-1.1:1.0: ttyACM0: USB ACM device
[ 5138.437924] usbcore: registered new interface driver cdc_acm
[ 5138.437927] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters

Nothing else is printed.

Additional Information

This is probably a core issue with customizable USB on this new port.

Thank you very much for your work on micropython and also for providing this template.

Code of Conduct

Yes, I agree

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied