diff options
author | Damien George <damien.p.george@gmail.com> | 2015-09-15 20:45:37 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2015-09-15 20:45:37 +0100 |
commit | d80174d7c3fe36f139c639d6a820cc4cbb88ddf9 (patch) | |
tree | df1612f2c01a48440eb376e3fde50366e9aa6a92 | |
parent | e2bfa471fa84db2a2d740d256ac4cca8cd4fd031 (diff) | |
download | micropython-d80174d7c3fe36f139c639d6a820cc4cbb88ddf9.tar.gz micropython-d80174d7c3fe36f139c639d6a820cc4cbb88ddf9.zip |
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 #1456.
-rw-r--r-- | stmhal/spi.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/stmhal/spi.c b/stmhal/spi.c index b1aacfd0b7..864463df2d 100644 --- a/stmhal/spi.c +++ b/stmhal/spi.c @@ -476,8 +476,11 @@ STATIC mp_obj_t pyb_spi_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_ pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data); // send the data + // Note: there seems to be a problem sending 1 byte using DMA the first + // time directly after the SPI/DMA is initialised. The cause of this is + // unknown but we sidestep the issue by using polling for 1 byte transfer. HAL_StatusTypeDef status; - if (query_irq() == IRQ_STATE_DISABLED) { + if (bufinfo.len == 1 || query_irq() == IRQ_STATE_DISABLED) { status = HAL_SPI_Transmit(self->spi, bufinfo.buf, bufinfo.len, args[1].u_int); } else { 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_ // receive the data HAL_StatusTypeDef status; - if (query_irq() == IRQ_STATE_DISABLED) { + if (vstr.len == 1 || query_irq() == IRQ_STATE_DISABLED) { status = HAL_SPI_Receive(self->spi, (uint8_t*)vstr.buf, vstr.len, args[1].u_int); } else { 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 // send and receive the data HAL_StatusTypeDef status; - if (query_irq() == IRQ_STATE_DISABLED) { + if (bufinfo_send.len == 1 || query_irq() == IRQ_STATE_DISABLED) { status = HAL_SPI_TransmitReceive(self->spi, bufinfo_send.buf, bufinfo_recv.buf, bufinfo_send.len, args[2].u_int); } else { DMA_HandleTypeDef tx_dma, rx_dma; |