Skip to content

Commit fe20f37

Browse files
committed
- For sufficiently large cyw43 PIO SPI transfers, sleep via async_context before entering busy wait.
1 parent b1676c1 commit fe20f37

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ void cyw43_set_pio_clkdiv_int_frac8(uint32_t clock_div_int, uint8_t clock_div_fr
5454
}
5555
#endif
5656

57+
#if CYW43_PIO_SLEEP_MIN_US
58+
static uint32_t bit_rate_khz;
59+
static void sleep_if_long_transfer(uint32_t xfr_length)
60+
{
61+
// Estimate transfer delay & sleep for about that long if it's long enough
62+
unsigned xfr_us = (xfr_length * 8 * 1000) / bit_rate_khz;
63+
if (xfr_us > CYW43_PIO_SLEEP_MIN_US)
64+
cyw43_delay_us(xfr_us);
65+
}
66+
#endif
67+
5768
#define PADS_DRIVE_STRENGTH PADS_BANK0_GPIO0_DRIVE_VALUE_12MA
5869

5970
#if !CYW43_USE_SPI
@@ -122,6 +133,10 @@ int cyw43_spi_init(cyw43_int_t *self) {
122133
}
123134
pio_sm_config config = SPI_PROGRAM_GET_DEFAULT_CONFIG_FUNC(bus_data->pio_offset);
124135

136+
#if CYW43_PIO_SLEEP_MIN_US
137+
// 2 PIO cycles per bit, PIO clock scaled
138+
bit_rate_khz = clock_get_hz(clk_sys) / (cyw43_pio_clock_div_int * 2 * 1000);
139+
#endif
125140
sm_config_set_clkdiv_int_frac8(&config, cyw43_pio_clock_div_int, cyw43_pio_clock_div_frac8);
126141
hw_write_masked(&pads_bank0_hw->io[CYW43_PIN_WL_CLOCK],
127142
(uint)PADS_DRIVE_STRENGTH << PADS_BANK0_GPIO0_DRIVE_LSB,
@@ -277,6 +292,9 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
277292
pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, true);
278293
__compiler_memory_barrier();
279294

295+
#if CYW43_PIO_SLEEP_MIN_US
296+
sleep_if_long_transfer(MAX(tx_length, rx_length));
297+
#endif
280298
dma_channel_wait_for_finish_blocking(bus_data->dma_out);
281299
dma_channel_wait_for_finish_blocking(bus_data->dma_in);
282300

@@ -309,6 +327,9 @@ int cyw43_spi_transfer(cyw43_int_t *self, const uint8_t *tx, size_t tx_length, u
309327
dma_channel_configure(bus_data->dma_out, &out_config, &bus_data->pio->txf[bus_data->pio_sm], tx, tx_length / 4, true);
310328

311329
pio_sm_set_enabled(bus_data->pio, bus_data->pio_sm, true);
330+
#if CYW43_PIO_SLEEP_MIN_US
331+
sleep_if_long_transfer(tx_length);
332+
#endif
312333
dma_channel_wait_for_finish_blocking(bus_data->dma_out);
313334

314335
uint32_t fdebug_tx_stall = 1u << (PIO_FDEBUG_TXSTALL_LSB + bus_data->pio_sm);

0 commit comments

Comments
 (0)