2025-05-06 6:16 AM
MCU | STM32U575 (OctoSPI1) |
Flash | Winbond W25Q128JV – Quad‑SPI NOR flash |
IDE / FW | STM32CubeIDE 1.18.1, STM32 HAL |
Clocking | OSPI clock = 50 MHz, Dummy cycles = 8 |
Supply | VDDL = 3V3, Flash = 3V3 |
Indirect Read/Write via HAL_OSPI_Command() + HAL_OSPI_TransmitReceive() is fine.
External loader built; CubeProgrammer can erase, program, verify and read the entire flash (see screenshot).
Constant data is programmed successfully:
const char string2[30] __attribute__((section(".ext_flash"))) __attribute__((aligned(4))) = "Hello Word";
CubeProgrammer shows the text correctly.
As soon as I switch to Memory‑Mapped mode every word read is 0x00000000.
No hard faults—just empty data.
MPU region
Base = 0x9000 0000, Size = 8 MB, Attributes = Normal, WT, Shareable, Execute‑Never.
Cache
I‑ and D‑cache invalidated before/after enabling MM.
Also tried with caches fully disabled → still 0x00.
OctoSPI config
Quad‑SPI, SDR, DQS disabled.
Dummy = 8 (datasheet value @ ≤ 50 MHz).
InstructionLine, DataLine, AlternateByteLine all set to 4‑line.
Command sequencer
READ (0x6B) + 4‑byte addressing; identical timing to the external loader.
Linear address offset
0x0000 0000 (same as loader).
Also tried 0x9000 0000 → no difference.
HAL_StatusTypeDef OFlash_EnableMemoryMappedMode( void )
{
OSPI_RegularCmdTypeDef sCommand = {0};
OSPI_MemoryMappedTypeDef sMemMappedCfg = {0};
// Set reading command
OFlash_DefaultCmd(&sCommand);
// OPTION 1: Quad Output Fast Read (0x6B) - Only data is quad
sCommand.Instruction = 0x6B;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
sCommand.DummyCycles = 8;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_4_LINES;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
// Write configuration
if (HAL_OSPI_Command(&FLASH_OSPI_PORT, &sCommand, QFLASH_DEF_TIMEOUT) != HAL_OK)
{
return HAL_ERROR;
}
// Set memory-mapped mode configuration
sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
// Enable memory-mapped mode
if (HAL_OSPI_MemoryMapped(&FLASH_OSPI_PORT, &sMemMappedCfg) != HAL_OK)
{
return HAL_ERROR;
}
return HAL_OK;
}
MPU is setup like:
/** Initializes and configures the Region 2 and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x90000000; /* External flash base address */
MPU_InitStruct.LimitAddress = 0x90000000 + (8 * 1024 * 1024) - 1; /* Base + 8MB - 1 */
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER0; /* Use the attributes we defined */
MPU_InitStruct.AccessPermission = MPU_REGION_ALL_RW; /* Read/write permission */
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; /* Enable instruction access */
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
With STM32CubeProgrammer and the external loader I could read the data:
Is there a special OSPI or MPU setting required to make Memory‑Mapped mode work on the U5?
Does the flash need to be explicitly put into “Continuous Read” before MM is enabled?
Any known STM32U5 OctoSPI issues in Quad‑SPI MM?
Common cache / DQS pitfalls when switching from Indirect to MM that I might have missed?
I’m running out of ideas any hint?