STMicroelectronics / stm32h7xx-hal-driver

Provides the STM32Cube MCU Component "hal_driver" of the STM32H7 series.
BSD 3-Clause "New" or "Revised" License
97 stars 43 forks source link

Need for HAL_SPI_TransmitFollowedByReceive function #39

Closed escherstair closed 8 months ago

escherstair commented 1 year ago

When working with SPI slave devices, a quite common scenario is reading some data from the slave. This iks usually done by a single SPI transaction made by:

From the programmer side, I usually have:

With HAL SPI, if I want to use a HAL_SPI_Transmit() followed by a HAL_SPI_Receive() I must use NSS pin driven by software, otherwise it's deasserted at the end of HAL_SPI_Transmit() and re-asserted before HAL_SPI_Receive(). But this is not what the slave needs (NSS must stay asserted). Handling it by software (driving the GPIO pin high or low) works, but it requires time between tx and rx, and this decreases the "real" baud rate.

If I want to use HAL_SPI_TransmitReceive(), it requires two buffers (pTxData and pRxData) and both of them must have size tx_size + rx_size. Probably I can use a single buffer passing it to pTxData and pRxData input parameters, but it must have a size of tx_size + rx_size, and from the application side it's not so common. As I wrote above, there is one tx_buf of size tx_size and onther rx_buf of size rx_size.

I don't know if this is a good idea, but I think that a new function with the following prototype

HAL_StatusTypeDef HAL_SPI_TransmitFollowedByReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint16_t txSize,
                                          uint8_t *pRxData, uint16_t rxSize, uint32_t Timeout);

would be ok. And it would be responsible to assert NSS before starting tx and deasserting it after the end of rx, if NSS is driven by hardware.

Does this suggestion sound good? Or is there a simpler way to do this?

HBOSTM commented 1 year ago

Hello @escherstair,

Thank you for this contribution. I can't reproduce the problem from my side. So could you please give us more details about how you got this issue? And share the steps you have followed to reproduce this problem.

Best Regards,

ALABSTM commented 12 months ago

Hi @escherstair,

I hope you are fine. Any feedback please?

Thanks,

escherstair commented 12 months ago

Hi @ALABSTM, hi @HBOSTM

I try to describe the issue with different words:

As far as I understand, none of the existing functions (HAL_SPI_Transmit(), HAL_SPI_Transmit(), HAL_SPI_TransmitReceive()) can be used in this scenario- every of them for a different reason. Am I right? For this reason I suggested the addition of HAL_SPI_TransmitFollowedByReceive() or something like that.

If there is already available a HAL function to do what I describe, please point me to the relevant documentation. Thanks in advance.

huoxingdawang commented 9 months ago

In my project, we have a samilar requirement. We implement this by using

HAL_SPI_Transmit(&hspi1,val,num,2000);
HAL_SPI_Receive(&hspi1,val2,num2,2000);

and control NSS by software.

Actually, ours is probably a little more complicated like the following

NSS=0
HAL_SPI_Transmit
HAL_SPI_Receive
HAL_SPI_Transmit
HAL_SPI_Receive
HAL_SPI_Transmit
HAL_SPI_Receive
HAL_SPI_Transmit
HAL_SPI_Receive
NSS=1

But we recently found that HAL_SPI_Receive would cause a TIME_OUT and HAL_SPI_TransmitReceive would work properly, details are in the #47 .

KRASTM commented 8 months ago

Hello @escherstair,

Back to you about this point. Our development teams acknowledged your proposal and its relevance. However, they reported there is no plan to support such enhancement for the moment. For your case, I think you can use HAL_SPI_TransmitReceive() (with dummy Bytes).

Please allow me to close this ticket. Thank you for your comprehension.

With regards.