← index #1650Issue #17064
Related · medium · value 0.583
QUERY · ISSUE

stm32: Implement Asynchronous SPI Slave

openby ryannathansopened 2015-11-26updated 2017-10-24
enhancementport-stm32

This issue is to implement asynchronous sending and receiving on the SPI when configured as a slave - instead of blocking and waiting for whenever a clock is provided from the master. SPI (read and write) should probably have a configurable buffer like uart rx currently does. When the master clocks, the contents of the send buffer should be clocked out and whatever the master is sending should be clocked in to the read buffer (if exists). The user should probably be able to choose between blocking and non-blocking modes as mentioned in #1533.

Related: #1642 (async uart tx)

Bug with existing implementation:
Currently when reading SPI as a slave, the function blocks until the specified number of bytes is received or the timeout occurs. If the timeout occurs an exception is raised (OS: 116) #1414 . An exception shouldn't be raised. Whatever data was read should be returned, just as the uart read currently does.

As a result of not having asynchronous read/writes and with the existing quirky behaviors, spi slave mode seems rather unusable.

CANDIDATE · ISSUE

STM32H735 SPI6 works only on sigle byte transfers because of not implemented BDMA

openby balazssarkozy94opened 2025-04-01updated 2026-03-12
bugport-stm32

Port, board and/or hardware

STM32H735 custom hw

MicroPython version

MicroPython v1.23.0-preview.420.gb7506f8fe.dirty on 2025-04-01; PCFJ1-H735IGT6 with STM32H735

Reproduction

I think this would happen on any other STM32H7 with SPI6. Init SPI6 with any parameters, and send 1 byte, this will work, send 2 or more, and it will throw timeout exception.
There is already some condition checking on the transmit / receive functions (for only 1 byte, it will send blocking, according to some comments in the code DMA for 1 byte didn't work). If you extend this condition to:
if (len == 1 || query_irq() == IRQ_STATE_DISABLED || self->spi->Instance == SPI6) {
status = HAL_SPI_Transmit(self->spi, (uint8_t *)src, len, timeout);
And also do the same for the other transfer modes, SPI6 will work in blocking mode.
Another solution would be to implement the BDMA in "ports/stm32/dma.c" around line 1769. It is written there, that BDMA is currently not supported, my solution at least gives blocking functionality to SPI6.

Expected behaviour

To be able to send multiple bytes on SPI6

Observed behaviour

Thrown exception upon trying SPI6 multiple byte transfer: ETIMEDOUT

Additional Information

No, I've provided everything above.

Code of Conduct

Yes, I agree

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied