sekigon-gonnoc / Pico-PIO-USB

USB host/device implementation using PIO of raspberry pi pico (RP2040).

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

🪲[BUG] Pico W CYW43 and Pico-PIO-USB host code conflict

rppicomidi opened this issue · comments

I am running a MSC Host Demo with Pico-PIO-USB host a Pico W board. Right now, my code uses the CYW43 module just to blink an LED. The code works just fine on a regular Pico board with Pico-PIO-USB. The code also works fine on Pico W board if I use the native USB hardware for the USB host. However, if I build the program to run on a Pico W board with a Pico-PIO-USB host, the program fails to work properly in various ways.
...

I expected the LED on the Pico W board to blink periodically to show the main loop is running and I expected the Pioc-PIO-USB host to properly enumerate a connected flash drive.

...

What I saw instead was: The CYW43 blinks the LED fine until I plug in a USB flash drive. Then the console spits error messages related to CYW43 initialization.

I have found one issue that prevents the stream of error messages, but does not completely fix the problem.

...

Additional information
My program initializes the CYW43 module in core 0. The Pico-PIO-USB host code runs in core 1. The pico-sdk file src/rp2_common/pico_cyw43_driver.c uses a PIO program that uses one state machine and 6 instructions to communicate between the RP2040 and the CYW43 module. I am using the default configuration of Pico-PIO-USB, so the pio_usb_tx program is loaded into PIO 0 and uses state machine 0 and the receiver programs run in PIO 1. By default, the CYW43 module runs in PIO 1, but there are no available instructions there, so I set CYW43_SPI_PIO_PREFERRED_PIO=0 to force that driver to run in PIO 0.

I noticed in pio_usb.c that there are no calls to pio_sm_claim() when state machines are assigned. That means that the call to pio_claim_unused_sm() in src/rp2_common/pico_cyw43_driver.c cannot work properly. I thought that was the only issue, so I added the following code to the end of apply_config()

  pio_sm_claim(pp->pio_usb_tx, pp->sm_tx);
  pio_sm_claim(pp->pio_usb_rx, pp->sm_rx);
  pio_sm_claim(pp->pio_usb_rx, pp->sm_eop);

Also, my code now waits until core 1 initialization is complete before it attempts to initialize the CYW43 hardware on core 1 so that the pio_sm_claim() calls have time to execute. Now instead of seeing a stream of error messages, I see the program lock up as soon as I plug in a USB drive. After some time, I see on the console

[CYW43] do_ioctl(2, 263, 16): timeout                                           
[CYW43] got unexpected packet 0

and then the LEDs start flashing again, but the flash drive does not enumerate. There must be some other conflict(s) too.

If I comment out the code that initializes the CYW43 and blinks the LED, then flash drive enumerates properly, so I can say my USB hardware works OK.

Are there any PIO operations in the Pico-PIO-USB USB TX code that might conflict with another state machine running in the same PIO?


How about DMA settings?

@sekigon-gonnoc Yep, claiming the DMA channel fixes the problem. I will format a pull request to fix it.

Thanks