Skip to content

Commit d80174d

Browse files
committed
stmhal: Use polling, not DMA, for 1 byte SPI transfers.
There is an issue sending 1 byte on the SPI bus using DMA, but it only occurs when the transmit is done for the first time after initialising the SPI and DMA peripherals. All other cases (sending 2 or more bytes, doing send_recv, doing recv first) work okay. We sidestep this issue by using polling (not DMA) for all 1 byte transfers. This is fine because a 1 byte transfer can't be interrupted and doesn't need the benefits of DMA (and using polling for this case is more efficient). Resolves adafruit#1456.
1 parent e2bfa47 commit d80174d

1 file changed

Lines changed: 6 additions & 3 deletions

File tree

stmhal/spi.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,11 @@ STATIC mp_obj_t pyb_spi_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
476476
pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data);
477477

478478
// send the data
479+
// Note: there seems to be a problem sending 1 byte using DMA the first
480+
// time directly after the SPI/DMA is initialised. The cause of this is
481+
// unknown but we sidestep the issue by using polling for 1 byte transfer.
479482
HAL_StatusTypeDef status;
480-
if (query_irq() == IRQ_STATE_DISABLED) {
483+
if (bufinfo.len == 1 || query_irq() == IRQ_STATE_DISABLED) {
481484
status = HAL_SPI_Transmit(self->spi, bufinfo.buf, bufinfo.len, args[1].u_int);
482485
} else {
483486
DMA_HandleTypeDef tx_dma;
@@ -528,7 +531,7 @@ STATIC mp_obj_t pyb_spi_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
528531

529532
// receive the data
530533
HAL_StatusTypeDef status;
531-
if (query_irq() == IRQ_STATE_DISABLED) {
534+
if (vstr.len == 1 || query_irq() == IRQ_STATE_DISABLED) {
532535
status = HAL_SPI_Receive(self->spi, (uint8_t*)vstr.buf, vstr.len, args[1].u_int);
533536
} else {
534537
DMA_HandleTypeDef tx_dma, rx_dma;
@@ -625,7 +628,7 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp
625628

626629
// send and receive the data
627630
HAL_StatusTypeDef status;
628-
if (query_irq() == IRQ_STATE_DISABLED) {
631+
if (bufinfo_send.len == 1 || query_irq() == IRQ_STATE_DISABLED) {
629632
status = HAL_SPI_TransmitReceive(self->spi, bufinfo_send.buf, bufinfo_recv.buf, bufinfo_send.len, args[2].u_int);
630633
} else {
631634
DMA_HandleTypeDef tx_dma, rx_dma;

0 commit comments

Comments
 (0)