cancel
Showing results for 
Search instead for 
Did you mean: 

QSPI+Flash with DMA not working properly.

KMaen
Associate III

Hi, I am struggling to make QSPI+Ext Flash and DMA to work for several days, but having issues.

I was using BSP library for both external SDRAM (with FMC) and Flash with QSPI.

However, BSP library had DMA read/write for FMC SDRAM, but not for QSPI Flash (why?).

BSP_QSPI_Read worked nicely, but it was slow, so I wanted to make DMA work.

My board is stm32f7508-DK.

Below is what I tried:

  1. Using STM32CubeMX, I enabled DMA for QSPI. Proper code was generated under HAL_QSPI_MspInit and it was using DMA2_Stream7. I will not paste the code for brevity.
    1. However, weirdly, the generated code did not contain code to enable the DMA, e.g., HAL_NVIC_SetPriority() or HAL_NVIC_EnableIRQ(). Why is this the case? Anyways, I tried manually adding those calls as well, which did not work - though the mode of error changed.
  2. I naively changed the HAL_QSPI_Receive() call in BSP_QSPI_Read to HAL_QSPI_Receive_DMA().
  3. I added a handler for DMA2_Stream7 in stm32f7xx_it.c/h.

I will try to write down different mode of errors that I have seen by tweaking the code.

  1. Without adding HAL_NVIC_SetPriority() / HAL_NVIC_EnableIRQ() code: I was able to do DMA the first time, but from the second time it did not work (no fault, but the data was not moving). It did not go into QSPI_DMARxCplt() callback function or DMA2_Stream7_IRQHandler() that I added in step 3 above.
  2. With adding HAL_NVIC_SetPriority() / HAL_NVIC_EnableIRQ() code: It now goes into QSPI_DMARxCplt() and DMA2_Stream7_IRQHandler(). However, it is stuck inside the handler and faults.
  3. I looked inside QSPI_DMARxCplt(), and thought it was weird it was not clearing the interrupt flag. So I added __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC). It worked the first time, but from the second time it was not working (no fault, but no data was copied, and did not go into QSPI_DMARxCplt() or DMA2_Stream7_IRQHandler() anymore).

I am not sure why my code is not working.

  1. Do I have to call HAL_NVIC_SetPriority() / HAL_NVIC_EnableIRQ() for DMA2_Stream7? This was some other example code was doing. If so, why is the STM32CubeMX-generated code not containing it?
  2. Why is my code getting stuck inside the handler, if I call those? Why am I only getting data copied if I don't call those? It seems like the DMA is getting disabled after the first copy...
  3. (Unimportant rant) Why is BSP lib supporting DMA for SDRAM but not for QSPI?

Any help would be highly appreciated. Thank you.

3 REPLIES 3

Ok, so I suspect there are different concepts here.

The SDRAM DMA is accessing Mapped Memory in the 0xC0000000 (or 0xD0000000) region.

The HAL_QSPI_Receive_DMA is doing DMA with the peripheral in direct mode, like you might with a USART.

The SDRAM equivalent would be for you to MEMORY MAP the QSPI space, and then DMA from that MEMORY in the 0x90000000 region to wherever you want that data transferred.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thank you for the answer! Then, would it be as simple as putting the QSPI in memory-mapped mode and copy-pasting the code structure for SDRAM DMA? Are there any performance different between direct mode vs. memory-mapped indirect mode?

Also, if I were to use memory mapped mode + DMA, is my current setting (e.g., using initialization code from STM32CubeMX) correct? Are there any example using memory mappend mode +DMA for QSPI Flash? Thank you!