cancel
Showing results for 
Search instead for 
Did you mean: 

QSPI flag 'QSPI_FLAG_BUSY' sometimes stays set

Peter Olsson
Associate III
Posted on October 30, 2017 at 08:47

Hello,

We'rehaving an issue on STM32F765IGT - when trying to use flash on QSPI, configured in 'Indirect mode', using HAL v1.8.0, and DMA enabled.

It's quite hard to replicate, but it seems to occur whenthere are lots of DMA and interrupts going on. The result is that QSPI_FLAG_BUSY stays set, and it stays that way forever.

As a workaround I've used the following code, right before sending HAL_QSPI_Command(). Before executing this, I check my internal state to make sure that QSPI is in fact not busy. In 'stm32f7xx_hal_qspi.c' I've found some ifdef'sfor 'QSPI_V1_0', which kind of gave me the idea to use the abort command like this. However, it was not possible to just enable the compiler directive, since we must also make sure to set 'State' to 'HAL_QSPI_STATE_BUSY', or the abort function won't do anything at all.

if ((FlagStatus)(__HAL_QSPI_GET_FLAG(&qspiHandle, QSPI_FLAG_BUSY)) == SET)
{
 qspiHandle.State = HAL_QSPI_STATE_BUSY;
 HAL_QSPI_Abort(&qspiHandle);
}�?�?�?�?�?

Has anyone else seen any similar issues?

Regards,

Peter Olsson

#stm32f7-hal #quadspi #qspi
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on April 19, 2018 at 15:19

Hi Amel,

Thanks for your reply.

It seems this change solves the issue!

I added the following code, and after that things seems stable - at least so far.

MPU_InitStruct.Enable = MPU_REGION_ENABLE;

MPU_InitStruct.Number = MPU_REGION_NUMBER1;

MPU_InitStruct.BaseAddress = 0x90000000;

MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;

MPU_InitStruct.SubRegionDisable = 0x0;

MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;

MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;

MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;

MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;

MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

View solution in original post

11 REPLIES 11
Daniel Blanchard
Associate
Posted on November 20, 2017 at 09:40

Hello, Peter.

We also encounter the same kind of problem with an STM32F756NG (without DMA).

Under unknown circumstances, we notice that the 'BUSY' flag becomes active again. In our case :

- Reading of the Quad Spi flash in indirect mode : All goes right, the BUSY flag is cleared at the end of the reading (In addition, an ABORT is requested at the end of the read).

 - Some time later, the software wants to make an other access to the Quad Spi flash... but the BUSY flag is set again ?

Right now, we implemented the same workaround than you did : Addition of an ABORT before any request (even if there is already an ABORT after all requests).

Syncerly yours,

Daniel Blanchard

Amel NASRI
ST Employee

Posted on November 20, 2017 at 14:07

 Hi peter.olsson‌ & Daniel.Blanchard‌,

Here you are reporting 'the same' problem' for 2 different products.

I would like to get more details on both configurations. Would it be possible for you to share the code you are using, that may help to reproduce the issue, even if it is not systematically faced?

In the case of STM32F756NG, there is already a limitation described in the errata sheet of the product 'Extra data written in the FIFO at the end of a read transfer'.  

This limitation should be already implemented in the 'stm32f7xx_hal_qspi.c'. Are you using last version of STM32CubeF7 package Daniel.Blanchard‌? Are you in the same conditions as the limitation?

In STM32F765IGT, this limitation was fixed, so you don't find it in related erratasheet..

peter.olsson‌, please make sure that really transferred data is aligned with DMA configuration.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Daniel Blanchard
Associate
Posted on November 20, 2017 at 15:45

HI Amel.

I already read the errata you mentioned.

Although I am not completely in the errata conditions (Simple Data Rate is used), I can tell :

- At the end of the reading (Indirect mode), the BUSY flag becomes inactive,

- Despite we are not in the errata condition, my software performs an ABORT at the end of the reading (one of the preconised workarounds),

- I do not use Stm32CubeF7 (neither the last version, nor any one else). I self-developped a QSPI driver (constraint : no dead or inactive code).

- And sorry, I can not 'share' the code I developped. I tried unsuccessfully to reproduce the phenomena on an evaluation board (even on our custom board, it is not obvious to determine which conditions make the issue appearing or not).

BR

Daniel

Posted on November 22, 2017 at 08:42

Amel,

Thanks for the reply. I will try to rip out some code that can be used to reproduce the issue. However, I'm quite busy for the moment, so it might take some time before I report back.

I've looked through my code several times, and I can't find any issues in there. The error seems impossible to trigger when running in debug mode. When running in release mode it is triggered after a couple of minutes (LCD contents updated at 10Hz, loading all bmp/font data from QSPI flash). DMA buffers are aligned at 32 byte boundaries, to make sure that D-cache can be cleaned/invalidated safely.

When reading data from flash, I do it like this (done from main loop):

  1. Reset flag 'rxCompleted' to 'false'
  2. Call HAL_QSPI_Command() to setup address, read length etc.
  3. Call HAL_QSPI_Receive_DMA() to start receiving data using DMA
  4. Wait for the flag 'rxCompleted' to be set to 'true'.
  5. In HAL_QSPI_RxCpltCallback() I set the 'rxCompleted' flag to 'true' (called from ISR)

This works just fine, but what happens once in a while in release mode, is that 

HAL_QSPI_Command() fails, since 'QSPI_FLAG_BUSY' is still set, so it eventually times out. I would assume that after HAL_QSPI_RxCpltCallback() has been called, the 'QSPI_FLAG_BUSY' should be reset. But somehow this isn't true all the time.

As I said, I will try to create some sample code that can recreate the issue, but it might take a couple of weeks before I get back to you.

Regards,

Peter Olsson

Posted on November 29, 2017 at 10:22

Hi

peter.olsson

‌,

Back to your case, we still wait for your sample code.

Meanwhile, could you please check if 'busy' flag is set in QSPI register when problem occurs. This should help us to understand either the problem is related to HAL state machine or QSPI peripheral.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on December 14, 2017 at 14:51

Hi Amel,

Yes, I know... I've been on vacation for a couple of weeks, and it seems I will be quite busy the following two weeks as well. I will try to create some sample code for you after that.

To answer your question, yes - the busy register flag is set on the peripheral. You can also see in my initial post, that it's this flag that I'm checking if I need to force an abort or not.

/Peter

Posted on February 14, 2018 at 11:33

Hi Amel,

I've been trying to create a sample project that can replicate the issue, but unfortunately it's very hard to replicate. However, while trying to solve the issue I've discovered some more details. I've also realized that the issue is much worse than I initially thought.

First of all, my initial assumption that the BUSY flag stays set after reading is wrong. The issue is exactly how Daniel describe it. After reading, the BUSY flag is NOT set. But a little bit later when I try to read again the flag might be set (and nothing has touched the QSPI peripheral during that time, that I'm 100% sure of). When investigating this a little bit further I can see that the reason the BUSY flag is set is because the QSPI peripheral believes it has unread data in the FIFO. So to reset the flag again I start reading from the DR register, and eventually the flag is reset.

My previous workaround to always call abort before trying to read is not really 100% perfect either. Because it still happens that the FIFO/BUSY flags gets set between the call to abort, and the QSPI command sequence. And sometimes I get bad data from the chip, which is probably caused by invalid data showing up in the FIFO instead of the real data (this never happens when I have a stable state). So it seems to me that in worst case it can happen while actually transferring real data!

The best workaround I've found so far is by disabling the D-cache. After doing that, everything works perfectly. However, I can't be 100% sure, since the issue seems to change depending on timing etc. Also, this shouldn't really have any effect at all, since all my data (static and dynamic allocations) is placed in the DTCM RAM (

0x20000000-0x2001FFFF)

, which is not cacheable anyway. The only thing that uses the cacheable area (0x20020000-0x2007FFFF) is the GUI handling, which uses it as a frame buffer.

I know for sure it isn't a cache coherence issue. The DMA buffers that are used are placed in DTCM RAM, and if they still would happen to be placed somewhere else I properly handle this as well (with properly aligned buffers etc.).

I've disabled most of my interrupts, with no difference at all. The only part that seems to make a difference is when I stop using the I2C1 peripheral (which I use in DMA mode). Even by changing some code inside the RX completed interrupt seems to make QSPI more stable, more specifically when I remove some float calculations. However, it seems to me that this just seems related to the real issue, it must be more of a timing thing I guess.

As you already said, my chip shouldn't have the QSPI/FIFO bug, and even if it had, it shouldn't show up in my case, since I'm not using DDR, and I have a larger divider than mentioned in the ERRATA. I've tried to lower the speed even more, but that doesn't affect anything at all.

I've spent a couple of weeks on this now, and I'm out of ideas how to move this forward. From my perspective this must be a bug in the CPU. However, I really need a workaround that I can trust to work in all situations. Right now I will disable the D-cache, and keep my eyes open if this really 'solves' all issues, or if it still can happen. As I said, since I'm currently not depending on the D-cache, I might be able to live without it.

About D-cache: When it's disabled I can remove the workaround with QSPI abort, and everything works perfectly anyway (at least so far...).

/Peter

Posted on February 14, 2018 at 11:36

Hi Daniel,

Have you had any more progress on this? As I mentioned in another comment, it seems my issue is identical to yours. Have you tried to disable the D-cache? For me it did wonders, at least it seems so (I've just been trying for a short period of time). After doing that I was able to remove the workaround with QSPI abort.

Posted on February 21, 2018 at 08:02

Yet another update on this.

I've now used my software with D-cache disabled, and so far it does seem to solve the issue completely, and I no longer need to manually abort QSPI to clear the BUSY flag. So it's definately related to this. I've also tried to keep D-cache enabled, but used the MPU to disable caching of all used areas (flash, SRAM etc.), when doing that QSPI still won't work, so I really need to disable the D-cache completely.

/Peter