arch/arm/src/stm32h7/stm32_spi.c: Correct cache flush
When starting dma transfer, the dcache for the TX buffer should be cleaned. "flush" performs also invalidate, which is unnecessary. The TX buffer can be unaligned to the cahche line in some(most) cases, whereas RX buffer can never be. The cache for the receive buffer can be dirty and valid before call to exchange. Thus another memory access (hitting the same cache line) may corrupt receive data while waiting for transfer to complete. So the receive buffer should be invalidated before the transfer Signed-off-by: Jukka Laitinen <jukka.laitinen@intel.com>
This commit is contained in:
parent
ace63ef74a
commit
d1c406d65d
@ -1813,7 +1813,6 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
FAR void * xbuffer = rxbuffer;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
@ -1928,7 +1927,13 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
|
||||
if (txbuffer)
|
||||
{
|
||||
up_flush_dcache((uintptr_t)txbuffer, (uintptr_t)txbuffer + nbytes);
|
||||
up_clean_dcache((uintptr_t)txbuffer, (uintptr_t)txbuffer + nbytes);
|
||||
}
|
||||
|
||||
if (rxbuffer)
|
||||
{
|
||||
up_invalidate_dcache((uintptr_t)rxbuffer,
|
||||
(uintptr_t)rxbuffer + nbytes);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPI_TRIGGER
|
||||
@ -1980,19 +1985,6 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
#ifdef CONFIG_SPI_TRIGGER
|
||||
priv->trigarmed = false;
|
||||
#endif
|
||||
|
||||
/* Force RAM re-read */
|
||||
|
||||
if (rxbuffer != NULL)
|
||||
{
|
||||
up_invalidate_dcache((uintptr_t)rxbuffer,
|
||||
(uintptr_t)rxbuffer + nbytes);
|
||||
|
||||
if (priv->rxbuf)
|
||||
{
|
||||
memcpy(xbuffer, priv->rxbuf, nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_STM32H7_SPI_DMA */
|
||||
|
Loading…
Reference in New Issue
Block a user