cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743 FMC send only part of the data

snkparty1
Associate II

I am using an STM32H743 FMC to connect to the FPGA to do data transfer. (SRAM type with 16-bit data. I tried this on an STM32F429 and the test was successful) 

 

The test is to send some amount of data to the FPGA through FMC.

snkparty1_0-1758736871511.png

snkparty1_1-1758737054591.png

The code is quite simple. Write some data to 0x6000 0000 and check if the FPGA can get the data correctly.

My discovery is that if only a small amount of data has been sent and  chip select signal FMC_NE1 will remain high and no waveform can be observed...

snkparty1_2-1758737708330.png

Send 100 data and FMC_NE1 remains high

 

If I send lots of data(for example, 10000 data) then FPGA can receive data correctly, but the data FPGA receives starts from 2020(this number is also random, some time 1820 some time 3020, etc)

snkparty1_3-1758737921392.png

This phenomenon does not happen on F429... If I send 10 data and the FPGA can receive 10 data correctly...

 

2 REPLIES 2
BGeor.1
Associate II

I wonder whether it is related to some sort of cache coherency problem since 0x6000_0000 address is marked as "Normal" and "Write back, write allocate cache attribute". You can try adding an MPU entry for this address range and mark this range as non-cached. If you want this region cached, you can also use the SCB_CleanDCache_by_Addr() to flush the data you wrote from the cache. Size argument to this API which is in bytes should be multiples of cache line size, like multiples of 32 bytes.

Double check the FMC clock configuration, if you are using two different CubeMX configuration files(.ioc) for STM32F and STM32H. You can also compare the FMC and RCC register setup to make sure both STM32F and STM32H are configured similarly.

mƎALLEm
ST Employee

Hello @snkparty1 ,

If you need to communicate with a FPGA over FMC you need to configure the region at that address (in your case 0x6xxx xxxx) as Device or Strongly-ordred using the MPU.

Try this MPU config, just put the size of the FPGA region:

static void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct;

  /* Disable the MPU */
  HAL_MPU_Disable();

  /* Configure the MPU as Strongly ordered for not defined regions */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.BaseAddress = 0x00;
  MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
  MPU_InitStruct.AccessPermission = MPU_REGION_NO_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 = 0x87;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /* Enable the access to 0x60000000 address keeping the Strongly ordered config */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.BaseAddress = 0x60000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_<Size Region>;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.Number = MPU_REGION_NUMBER1;
  MPU_InitStruct.SubRegionDisable = 0x0;
  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.