Skip to content

Commit 2a810a9

Browse files
committed
Fix unreliable writes to cyw43.
We use a pio and dma to write to the cyw43 chip using spi. Normally you write an address and then read the data from that address, so the pio program does does a write then read. If you just want to write data in the case of uploading firmware we use the fdebug_tx_stall flag to work out if the pio has stalled waiting to read data which will never arrive. The theory is that this flag will also get set if the bus is busy. So we mistakenly think a write to cyw43 has completed. Add a check for the dma irq as well. Fixes #2206
1 parent c54475d commit 2a810a9

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
231231
return CYW43_FAIL_FAST_CHECK(-CYW43_EINVAL);
232232
}
233233

234-
bus_data_t *bus_data = (bus_data_t *)self->bus_data;
234+
volatile bus_data_t *bus_data = (bus_data_t *)self->bus_data;
235235
start_spi_comms(self);
236236
if (rx != NULL) {
237237
if (tx == NULL) {
@@ -306,6 +306,7 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
306306
channel_config_set_bswap(&out_config, true);
307307
channel_config_set_dreq(&out_config, pio_get_dreq(bus_data->pio, bus_data->pio_sm, true));
308308

309+
dma_hw->ints0 = 1u << bus_data->dma_out;
309310
dma_channel_configure(bus_data->dma_out, &out_config, &bus_data->pio->txf[bus_data->pio_sm], tx, tx_length / 4, true);
310311

311312
uint32_t fdebug_tx_stall = 1u << (PIO_FDEBUG_TXSTALL_LSB + bus_data->pio_sm);
@@ -315,6 +316,12 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
315316
tight_loop_contents(); // todo timeout
316317
}
317318
__compiler_memory_barrier();
319+
320+
while (!(dma_hw->intr & 1u << bus_data->dma_out)) {
321+
tight_loop_contents();
322+
}
323+
dma_hw->ints0 = 1u << bus_data->dma_out;
324+
318325
pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, false);
319326
pio_sm_set_consecutive_pindirs(bus_data->pio, bus_data->pio_sm, CYW43_PIN_WL_DATA_IN, 1, false);
320327
} else if (rx != NULL) { /* currently do one at a time */

0 commit comments

Comments
 (0)