raspberrypi / pico-extras

BSD 3-Clause "New" or "Revised" License
480 stars 120 forks source link

pico_audio_i2s incompatible with USB stdio #76

Open chrisgjohnson opened 4 months ago

chrisgjohnson commented 4 months ago

It seems that the pico_audio_i2s library intermittently breaks the standard USB stdio implementation, resulting in no communication either way between the pico and the USB host after a short time (a few seconds to a minute or so).

The host still reports the USB CDC connection (e.g. /dev/ttyACM0 continues to exist) but communication ceases.

For example, the pico-playground sine_wave example exhibits this problem, if USB communication is enabled through adding pico_enable_stdio_usb(sine_wave_i2s 1) to the i2s section of CMakeLists.txt. (In that example, the problem is evident as the terminal user interface initially works, then ceases to function).

Is this a known issue -- and is there a known workaround?

lurch commented 4 months ago

I'm afraid this is just a "random guess", but the USB protocol is timing-sensitive, so if the Pico doesn't respond to USB requests from the host "quickly enough", the USB channel might go awry. Do you see any USB-related errors in the dmesg log?

In an entirely-separate project I was working on recently, I was able to solve this problem by running the USB-related code (in my case I was using tinyusb to emulate a HID mouse) on core1, with the rest of my application running on core0. (and then using https://www.raspberrypi.com/documentation/pico-sdk/group__multicore__fifo.html to communicate between the two cores)

chrisgjohnson commented 4 months ago

I've just checked dmesg and this doesn't reveal anything.

I've also tried the suggested use of core1 in sine_wave_i2s, and am seeing same problems --- when commenting out the stdio use in the main thread, and adding multicore_launch_core1(other_thread); with the function

void other_thread()
{
    static int count=0;

    while (1)
    {
        busy_wait_ms(100);
        printf("%d\n",count++);
    }
}

Debug probe is arriving tomorrow, which should at least let me see if UART stdio suffers from the same problem.

kilograham commented 4 months ago

yeah UART is likely much better; the stdio_usb stuff has a bunch of IRQ stuff to deal with running TinyUSB in the background, which is likely the source of issues.

Note you are much better off running your code on core 1, as all the stdio_usb stuff has already been initialized on core 0