@@ -273,6 +273,7 @@ static void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8
273273 bool use_dma = chan_rx >= 0 && chan_tx >= 0 ;
274274 // note src is guaranteed to be non-NULL
275275 bool write_only = dest == NULL ;
276+ bool success = true;
276277
277278 if (use_dma ) {
278279 uint8_t dev_null ;
@@ -297,8 +298,16 @@ static void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8
297298 false);
298299
299300 dma_start_channel_mask ((1u << chan_rx ) | (1u << chan_tx ));
300- dma_channel_wait_for_finish_blocking (chan_rx );
301301 dma_channel_wait_for_finish_blocking (chan_tx );
302+
303+ // Fix for #18471. Wait for SPI to finish then check for RX overrun
304+ while (spi_is_busy (self -> spi_inst ) || spi_is_readable (self -> spi_inst )) {
305+ }
306+ if (spi_get_const_hw (self -> spi_inst )-> ris & SPI_SSPRIS_RORRIS_BITS ) {
307+ // RX overrun occurred, RX DMA channel needs to be manually aborted
308+ success = false;
309+ dma_channel_abort (chan_rx );
310+ }
302311 }
303312
304313 // If we have claimed only one channel successfully, we should release immediately
@@ -317,6 +326,11 @@ static void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8
317326 spi_write_read_blocking (self -> spi_inst , src , dest , len );
318327 }
319328 }
329+
330+ // Raise OSError if something went wrong
331+ if (!success ) {
332+ mp_raise_OSError (MP_EIO );
333+ }
320334}
321335
322336// Buffer protocol implementation for SPI.
0 commit comments