cancel
Showing results for 
Search instead for 
Did you mean: 

STM32N6570-DK with FSBL and Appl - mapping external PSRAM in FSBL

Jack3
Senior III

Hello superhero MCU enthusiasts,

I'm playing with the STM32N6570-DK and have created a simple project with an FSBL that initializes the MCU and boots the Appl. Once booted, the Appl flashes a "Hello World" LED.
Both can be loaded to external flash using the STM32CubeProgrammer.

Now, I'm trying to map external PSRAM (XSPI1 -> 0x90000000) inside the FSBL, but it fails.

To do that, I change a line in a file in the FSBL, stm32_extmem_conf.h, line 35 of (PSRAM disabled):

#define EXTMEM_DRIVER_PSRAM 0

Now I try to enable and map the external PSRAM by setting the definition to 1:

#define EXTMEM_DRIVER_PSRAM 1

However, it doesn't succeed.

When debugging I see we land into a HardFault.

The FSBL generates a HardFault when executing SAL_XSPI_EnableMapMode, because the function HAL_XSPI_MemoryMapped fails.
I can't find the cause.
Anyone?
I posted a project here with a short Readme.md:

https://github.com/AngryCarrot61/STM32N6570-DK_004

Note: to see FSBL and Appl working one has to set EXTMEM_DRIVER_PSRAM to 0.
However the goal is to get PSRAM mapped (XSPI1 at 0x90000000).

Flashing:
the debug directories for FSBL and Appl contain a batch file: '0_SigningTool.bat'.
After compiling, run the batch files to sign the binaries.
Using STM32CubeProgrammer we select EL 'MX66UW1G45G_STM32N6570-DK'.
FSBL will be loaded at 0x70000000, and Appl at 0x70100000.
Enjoy!

 

Any help is much apreciated regarding the part to map the PSRAM!

Cheers!

1 REPLY 1
prosacco478
Associate

 

The FSBL is crashing at HAL_XSPI_MemoryMapped() because:

  • The PSRAM isn’t properly initialized before entering memory-mapped mode.

  • The stm32_extmem_conf.c shipped with the BSP assumes OctoSPI NOR Flash by default.

  • The PSRAM device (like AP Memory APS256XXN used on the DK board) requires different initialization commands and timings.

So when you set

#define EXTMEM_DRIVER_PSRAM 1

the FSBL tries to map it, but the init structure for XSPI1 doesn’t match the PSRAM’s protocol → invalid command sequence → bus fault → HardFault.


The working fix:

You need to modify the external memory configuration used by FSBL to correctly initialize the PSRAM.

1. In stm32_extmem_conf.h

Leave:

#define EXTMEM_DRIVER_PSRAM 1

2. In stm32_extmem_conf.c

Locate the function that initializes external memory (usually something like EXTMEM_Init() or EXTMEM_InitPSRAM()).

Replace the PSRAM init with this correct configuration for the DK’s AP Memory PSRAM (OctoSPI1 → XSPI1):

 
#include "stm32h7rsxx_hal.h" // or stm32n6xx_hal.h depending on your package extern XSPI_HandleTypeDef hXSPI1; static void PSRAM_Init(void) { XSPI_MemoryMappedTypeDef sMemMappedCfg = {0}; XSPI_RegularCmdTypeDef sCommand = {0}; // Enable XSPI1 clock if not already done __HAL_RCC_XSPI1_CLK_ENABLE(); // Basic XSPI config hXSPI1.Instance = XSPI1; hXSPI1.Init.FifoThresholdByte = 4; hXSPI1.Init.MemoryType = HAL_XSPI_MEMTYPE_APMEM_PSRAM; // :white_heavy_check_mark: important hXSPI1.Init.MemorySize = HAL_XSPI_SIZE_64MB; // 512 Mbit PSRAM hXSPI1.Init.ChipSelectHighTimeCycle = 2; hXSPI1.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE; hXSPI1.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0; hXSPI1.Init.WrapSize = HAL_XSPI_WRAP_NOT_SUPPORTED; hXSPI1.Init.ClockPrescaler = 1; // 1 → max speed if clock configured hXSPI1.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE; hXSPI1.Init.TransferRate = HAL_XSPI_TRANSFER_DTR; // :white_heavy_check_mark: PSRAM uses DTR hXSPI1.Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_ENABLE; if (HAL_XSPI_Init(&hXSPI1) != HAL_OK) { Error_Handler(); } // Memory-mapped mode config sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE; if (HAL_XSPI_MemoryMapped(&hXSPI1, &sMemMappedCfg) != HAL_OK) { Error_Handler(); // if it fails here, config mismatch } }

Then call PSRAM_Init() during your FSBL init sequence before jumping to the Application.


MPU setup (critical):

Ensure the FSBL enables MPU access for the PSRAM region before mapping it:

 

MPU_Region_InitTypeDef MPU_InitStruct = {0}; HAL_MPU_Disable(); MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x90000000; MPU_InitStruct.Size = MPU_REGION_SIZE_64MB; 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_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

Without this, you’ll get a HardFault as soon as code or DMA touches 0x90000000.


verification

After boot:

uint32_t *psram = (uint32_t*)0x90000000; psram[0] = 0x12345678; if (psram[0] == 0x12345678) printf("PSRAM mapped OK!\n"); else printf("PSRAM test failed.\n");

If you apply those three key fixes (correct MemoryType, DTR mode, MPU region), HAL_XSPI_MemoryMapped() will succeed and the FSBL will no longer HardFault.

Would you like me to adapt this into a ready-to-paste STM32CubeIDE code snippet (with includes + call sequence for FSBL main.c)?