-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
I've been chasing an issue with wireless in our MicroPython builds, and after confirming that it's related to our DMA/PIO drivers for LED matrix displays came up with a reproduction: micropython/micropython#16627
This reproduction reliably shows that setting up chained DMA (yes it's in MicroPython but my original code was a C module) upsets the cyw43 driver. This only happens on Pico 2 W/RP2350 (possibly related to DMA errata E5?) and the same (original C) code has worked on RP2040 since the original Pico W launched.
@MichaelBell rolled with this and found that adding asm volatile (" nop\n nop\n nop " ); after calls to dma_channel_abort in cyw43_bus_pio_spi.c would somehow fix this, coming up with the following patch:
diff --git a/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c b/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c
index bcc7284..1c6bd84 100644
--- a/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c
+++ b/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c
@@ -260,6 +260,7 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
pio_sm_exec(bus_data->pio, bus_data->pio_sm, pio_encode_jmp(bus_data->pio_offset));
dma_channel_abort(bus_data->dma_out);
dma_channel_abort(bus_data->dma_in);
+ asm volatile (" nop\n nop\n nop " );
dma_channel_config out_config = dma_channel_get_default_config(bus_data->dma_out);
channel_config_set_bswap(&out_config, true);
@@ -301,6 +302,7 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
pio_sm_exec(bus_data->pio, bus_data->pio_sm, pio_encode_out(pio_y, 32));
pio_sm_exec(bus_data->pio, bus_data->pio_sm, pio_encode_jmp(bus_data->pio_offset));
dma_channel_abort(bus_data->dma_out);
+ asm volatile (" nop\n nop\n nop " );
dma_channel_config out_config = dma_channel_get_default_config(bus_data->dma_out);
channel_config_set_bswap(&out_config, true);We don't have a good sense for exactly what is happening, and it seems to vary between compilers (breaks as expected with GCC 14.2.1), but it's clear that it's a uniquely RP2350 problem and that a mitigation should be possible in Pico SDK.