STM32H7 SPI RX DMA not working - bug in HAL?
This project uses STM32Cube_FW_H7_V1.3.2.
On STM32H7 I'm using DMA for SPI transfer. I use SPI1 and SPI4, both in D2 domain, together with RAM_D2.
In the linker file I added:
.dma_buffer :
{
. = ALIGN(4);
*(.dma_buffer)
} >RAM_D2The buffer is declared like:
uint8_t buf[2048] __attribute__ ((section(".dma_buffer"))) __attribute__ ((aligned (32)));Transmitting using DMA works:
/* Mem-to-Peri */
SCB_CleanDCache_by_Addr((uint32_t*)(((uint32_t)buf) & ~(uint32_t)0x1F), len + 32);
errorcode = HAL_SPI_Transmit_DMA(interface->hspi, (uint8_t*) buf, len);Receiving data from SPI without using DMA also works, I get valid data in.
But if I use DMA, the buffer gets filled with 0's after cache invalidation:
/* Peri-to-Mem */
errorcode = HAL_SPI_Receive_DMA(interface->hspi, (uint8_t*) buf, len);
/* Some code to wait for the transfer to be finished */
wait_dma_rx_ended(interface);
SCB_InvalidateDCache_by_Addr((uint32_t*)(((uint32_t)buf) & ~(uint32_t)0x1F), ((len+31)/32)*32);I also configured the MPU, but I think it is not needed when using the cache maintenance functions.
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = { 0 };
/* Disable the MPU */
HAL_MPU_Disable();
/* Initialize and configure the Region and the memory to be protected */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x30001000;
MPU_InitStruct.Size = MPU_REGION_SIZE_8KB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}My SPI and DMA in initialized like this:
So the problem is I do not receive valid data when using DMA, but I do get valid data when not using DMA. So I think the SPI is configured correctly for the device.
Using DMA, if I don't invalidate the cache, I see the same data in the buffer as before calling HAL_SPI_Receive_DMA, which is expected. But after cache invalidation (calling SCB_InvalidateDCache_by_Addr), I do read all 0's, instead of valid data, which is not expected.
Using DMA transmit SPI works just fine, as does SPI receive without DMA.
What can I do to troubleshoot the problem further?
Has anybody seen this behavior on STM32H7 MCU's?
Once the problem is solved, I can explain which change worked, and provide the updated code on github to help others:
https://github.com/bkht/KSZ8851SNL_no_LwIP
Thank in advance for help!
