cancel
Showing results for 
Search instead for 
Did you mean: 

How To Using FMC Write?

Dlak
Associate II

I encountered a problem when trying to send more than 5 bytes of data using the FMC.

// impossible example --

#define SD_DATA       (*(volatile unsigned char *)0x60000001)

SD_DATA = 0x01;
SD_DATA = 0x02;
SD_DATA = 0x03;
 
Using this method, data is not transmitted to the same address without a delay.
However, it is possible to write data to the FMC if I change the address each time I transmit or use a delay.
 
// possible example -- 1

#define SD_DATA       (*(volatile unsigned char *)0x60000001)

SD_DATA = 0x01;
HAL_Delay(1);
SD_DATA = 0x02;
HAL_Delay(1);
SD_DATA = 0x03;
// possible example -- 2

#define SD_DATA1      (*(volatile unsigned char *)0x60000001)
#define SD_DATA2       (*(volatile unsigned char *)0x60000002)
#define SD_DATA3       (*(volatile unsigned char *)0x60000003)
SD_DATA1 = 0x01;
SD_DATA2 = 0x02;
SD_DATA3 = 0x03;
 
What could be the problem?
 
We used the STM32F756, and the following is the FMC initialization.
static void MX_FMC_Init(void)
{
  FMC_NORSRAM_TimingTypeDef Timing;


  /** Perform the NOR1 memory initialization sequence
  */
  hnor1.Instance = FMC_NORSRAM_DEVICE;
  hnor1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
  /* hnor1.Init */
  hnor1.Init.NSBank = FMC_NORSRAM_BANK1;
  hnor1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  hnor1.Init.MemoryType = FMC_MEMORY_TYPE_NOR;
  hnor1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;
  hnor1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  hnor1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hnor1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hnor1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  hnor1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hnor1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
  hnor1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hnor1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  hnor1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hnor1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
  hnor1.Init.PageSize = FMC_PAGE_SIZE_NONE;

/* Timing */
  Timing.AddressSetupTime = 15;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 31;
  Timing.BusTurnAroundDuration = 8;
  Timing.CLKDivision = 16;
  Timing.DataLatency = 17;
  Timing.AccessMode = FMC_ACCESS_MODE_A;
  /* ExtTiming */

  if (HAL_NOR_Init(&hnor1, &Timing, NULL) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}
1 ACCEPTED SOLUTION

Accepted Solutions
Dlak
Associate II

Due to repeated swap errors, I resolved the issue by clearing the cache.

View solution in original post

13 REPLIES 13
SofLit
ST Employee

Hello and welcome to the community.

Please use the button </> to insert your code.

Please read these recommendations on how to post a thread: https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

Thank you for your understanding

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.

In MPU, set given area to be Device (it's Normal by default, which implies that the processor can merge accesses as it sees fit).

Alternatively, you can use the remap using SYSCFG_MEMRMP.SWP_FMC, the memory area starting at 0xC000'0000 is in MPU set as Device by default.

JW

We used NE1 of the FMC to map the address in the hardware. Does this mean it needs to be remapped to 0xC0000000? What is the reason for mapping to 0xC0000000?

I used this code to swap 0x60000000 to 0xC0000000, but a hard fault occurs.

void FMC_MemoryRemap(void) {
	
    SYSCFG->MEMRMP |= SYSCFG_MEMRMP_SWP_FMC_0;
}

> What is the reason for mapping to 0xC0000000?

As I've said above, to have the SRAM in a MPU area tagged as Device. As I've said above, the alternative to remap is to set the SRAM area to Device in MPU.

> but a hard fault occurs

Where? Why? Do you still attempt to write to 0x6000'0000?

Else, debug the hardfault as usually.

JW

 

I wrote the following code and changed all instances of 0x60000000 to 0xC0000000. However, a HardFault is occurring.

ex)

#define ZD_DATA     (*(volatile unsigned char *)0xC0000000)

You have the FMC properly initialized and the swap performed?

> HardFault is occurring

Where? Single-step in disasm to find out the exact instruction.

JW

 

Upon running, a HardFault occurs immediately.

If I remove the line

SYSCFG->MEMRMP |= SYSCFG_MEMRMP_SWP_FMC_0;

the HardFault disappears.

Even without this code, attempting to access the address 0xC0000000 results in a HardFault.

I have noticed that using BANK1 in FMC_Init causes a hard fault at addresses starting from 0x6000.0000. This issue does not occur with BANK2. What could be the reason for this? Isn't the address for BANK2 starting from 0x7000.0000?