cancel
Showing results for 
Search instead for 
Did you mean: 

FMC Read Duplicates During Interrupt But Writes Seemingly Don't

geirlandunico
Associate III

I have a STM32H7 with it's FMC signals hooked up to an FPGA in order to allow the microcontroller to peak/poke into FPGA registers.  I had a FIFO in this address space that, if read, would automatically increment to the next value.  I was noticing on occasion having two read requests for what should be only a single read in the code (causing data loss on the FIFO).  I found this old post: https://community.st.com/t5/stm32-mcus-products/stm32f7-fmc-dummy-read/td-p/419015 in which someone saw the same issue and found out that interrupts were coming in causing the FMC to repeat the read once returning from the interrupt handler.  I tried disabling interrupts and saw my problem go away.

 

What's odd is that I saw this happening very frequently on reads (occurring anywhere from a couple hundred to a few thousand reads in) but when stressing the writes at the same level, I never saw this occur.  The difference in time to finish a read/write doesn't seem to be different enough to explain the disparity.  Is there something I'm missing internally that may explain this difference?

1 ACCEPTED SOLUTION

Accepted Solutions

Try to configure FPGA memory region as Strongly-Ordered.

Declare this function and call it first one in your main():

 

void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct;

  /* Disable the MPU */
  HAL_MPU_Disable();

  /* Configure the FPGA memory regionas Strongly ordered */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.BaseAddress = 0x60000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.SubRegionDisable = 0;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /* Enable the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
   
}

 

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.

View solution in original post

5 REPLIES 5
SofLit
ST Employee

Hello,

Did you set the memory region of your FPGA as Device or Strongly-Ordred using MPU?

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.

To be honest I'm still new with the STM32.  I don't believe I changed anything in regards to the MPU settings.  Doing some googling, it seems like the memory range that I'm using for it (0x60000000-0x6FFFFFFF) defaults to Normal instead of Device or Strongly-Ordered.

Try to configure FPGA memory region as Strongly-Ordered.

Declare this function and call it first one in your main():

 

void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct;

  /* Disable the MPU */
  HAL_MPU_Disable();

  /* Configure the FPGA memory regionas Strongly ordered */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.BaseAddress = 0x60000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.SubRegionDisable = 0;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /* Enable the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
   
}

 

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.
geirlandunico
Associate III

Just set this up and ran it and it also solved my problem (so that I don't have to disable IRQs).  Thank you!  Definitely a cleaner solution.

 

I'm still wondering though.  Do you know why, pre MPU change, I was seeing this issue on reads but not writes?

Due to complex Core pipelines, Cache + AXI transaction and its internal buffers and data/instruction fetches are not timely ordered in the sequence of the generated assembly when the memory region is set as Normal.

Configuring it as Strongly-Ordered forces all data/instructions to be fetched in order.

This applies also when a LCD is driven with FMC.

 

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.