cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L552ZE FMC throws Hard Fault only when accessing sub-banks 2-4

Zaher
Senior II

Hi,

I have configured the FMC for interfacing with a NOR flash on sub-banks 1 and 2 (NE1, and NE2). The FMC is configured for 16-bit data bus with 26 address lines.

What follows is the configuration for two sub-banks on NE1 and NE2:

/* FMC initialization function */
static void MX_FMC_Init(void)
{
 
  /* USER CODE BEGIN FMC_Init 0 */
 
  /* USER CODE END FMC_Init 0 */
 
  FMC_NORSRAM_TimingTypeDef Timing = {0};
  FMC_NORSRAM_TimingTypeDef ExtTiming = {0};
 
  /* USER CODE BEGIN FMC_Init 1 */
 
  /* USER CODE END FMC_Init 1 */
 
  /** Perform the SRAM1 memory initialization sequence
  */
  hsram1.Instance = FMC_NORSRAM_DEVICE;
  hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram1.Init */
  hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType = FMC_MEMORY_TYPE_PSRAM;
  hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_ENABLE;
  hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
  hsram1.Init.NBLSetupTime = 0;
  hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
  hsram1.Init.MaxChipSelectPulse = ENABLE;
  hsram1.Init.MaxChipSelectPulseTime = 10;
  /* Timing */
  Timing.AddressSetupTime = 12;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 6;
  Timing.DataHoldTime = 2;
  Timing.BusTurnAroundDuration = 15;
  Timing.CLKDivision = 16;
  Timing.DataLatency = 17;
  Timing.AccessMode = FMC_ACCESS_MODE_A;
  /* ExtTiming */
  ExtTiming.AddressSetupTime = 15;
  ExtTiming.AddressHoldTime = 15;
  ExtTiming.DataSetupTime = 6;
  ExtTiming.DataHoldTime = 1;
  ExtTiming.BusTurnAroundDuration = 15;
  ExtTiming.CLKDivision = 16;
  ExtTiming.DataLatency = 17;
  ExtTiming.AccessMode = FMC_ACCESS_MODE_A;
 
  if (HAL_SRAM_Init(&hsram1, &Timing, &ExtTiming) != HAL_OK)
  {
    Error_Handler( );
  }
 
  /** Perform the SRAM2 memory initialization sequence
  */
  hsram2.Instance = FMC_NORSRAM_DEVICE;
  hsram2.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram2.Init */
  hsram2.Init.NSBank = FMC_NORSRAM_BANK2;
  hsram2.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  hsram2.Init.MemoryType = FMC_MEMORY_TYPE_PSRAM;
  hsram2.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram2.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  hsram2.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram2.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hsram2.Init.WriteOperation = FMC_WRITE_OPERATION_DISABLE;
  hsram2.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hsram2.Init.ExtendedMode = FMC_EXTENDED_MODE_ENABLE;
  hsram2.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram2.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  hsram2.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hsram2.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
  hsram2.Init.NBLSetupTime = 0;
  hsram2.Init.PageSize = FMC_PAGE_SIZE_NONE;
  hsram2.Init.MaxChipSelectPulse = ENABLE;
  hsram2.Init.MaxChipSelectPulseTime = 10;
  /* Timing */
  Timing.AddressSetupTime = 15;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 6;
  Timing.DataHoldTime = 2;
  Timing.BusTurnAroundDuration = 15;
  Timing.CLKDivision = 16;
  Timing.DataLatency = 17;
  Timing.AccessMode = FMC_ACCESS_MODE_A;
  /* ExtTiming */
  ExtTiming.AddressSetupTime = 15;
  ExtTiming.AddressHoldTime = 15;
  ExtTiming.DataSetupTime = 6;
  ExtTiming.DataHoldTime = 1;
  ExtTiming.BusTurnAroundDuration = 15;
  ExtTiming.CLKDivision = 16;
  ExtTiming.DataLatency = 17;
  ExtTiming.AccessMode = FMC_ACCESS_MODE_A;
 
  if (HAL_SRAM_Init(&hsram2, &Timing, &ExtTiming) != HAL_OK)
  {
    Error_Handler( );
  }
 
  /* USER CODE BEGIN FMC_Init 2 */
 
  /* USER CODE END FMC_Init 2 */
}

At the moment, I can initialize the NOR flash, read info from CFI registers like e-signatures (MFG code, device ID, etc) without any issue. However, I noticed that any access to the address space beyond the first sub-bank causes a Hard Fault. Even when the STM32 board is not connected to anything, accessing the first bank works but trying to access any other bank generates a Hard Fault interrupt.

Aside from hardware connected to my NUCLEO144 board (NOR flash in this case) the problem seems to be into the code itself. As far as I know, Hard Faults generated because of FMC had to do with violations to memory space access. Otherwise, why it would work properly when accessing any address within the first sub-bank, even when the STM32 is not connected to any external memory?

I tried to disable the second bank (NE2) and continue testing with only one sub-bank enabled (0x60000000/NE1) but this also keeps generating the hard fault. Again, this is with the board alone without connection to any external memories. I just don't understand what causes the hard fault when the second NOR/PSRAM bank is disabled?

Zaher

2 REPLIES 2
Zaher
Senior II

OK, I believe I found the cause of Hard Fault. I made a small function to test bus operations (read/write/erase) on the NOR flash. The program crashes as soon as the access exceeds the 511 block. The device I'm working on has 1024 uniform blocks. Here's the memory map of the M29EW NOR Flash:

0693W00000Nrg93QAB.jpg 

Any attempt to read/write the bus beyond 0x1FFFFFF causes a Hard Fault. Block 512 @ 0x2000000 in device memory map, which is 0x62000000 in the STM32 device space. Although this is still within the safe boundaries of the first sub-bank of NOR/PSRAM (NE1), the program crashes.

To sum it up, the following problem posted by "connect" seems very similar to mine: https://community.st.com/s/question/0D50X00009XkiC7SAJ/stm32f417igt6-fsmc-a25-hardfault

According to Clive, in the 16-bit space, it's not possible to have A[25..0]. Well, could someone elaborate more on this for me?

Thank you again,

Zaher

Zaher
Senior II

Well, I think part of my problem has been solved. I have activated two sub-banks (NE3/NE4) and re-mapped NE1 and NE2 to GPIOs so I can control them at will. Now I can access the entire address space on the NOR Flash for blocks 0~1023 (0x0000000 ~ 0x7FFFFFF). However, still can't read any correct values at the CFI space.