Skip to main content
BHamm
Associate II
September 12, 2022
Solved

STM32U585 OSPI hard fault on memory-mapped write

  • September 12, 2022
  • 2 replies
  • 3756 views

I'm trying to follow the OSPI_NOR_MemoryMapped STM32CubeIDE example, but for a different device (W25Q128FV). Write Enable, Read Status, and Erase Sector commands behave as expected, as well as memory-mapped reads. This has been confirmed by monitoring the OSPI lines with a logic analyzer, and comparing against the W25Q128FV datasheet.

The one thing that does not work is memory-mapped writes. No activity occurs on the OSPI lines; a fault occurs on the instruction to write to the OSPI1 address. The Cortex-M33 registers show a precise bus fault at address OCTOSPI1_BASE (0x90000000).

Any suggestions are appreciated.

OSPI_HandleTypeDef ospiHandle = {
 .Instance = OCTOSPI1,
 .Init = {
 .FifoThreshold = 1,
 .DualQuad = HAL_OSPI_DUALQUAD_DISABLE,
 .MemoryType = HAL_OSPI_MEMTYPE_MACRONIX,
 .DeviceSize = 24,
 .ChipSelectHighTime = 2,
 .FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE,
 .ClockMode = HAL_OSPI_CLOCK_MODE_0,
 .WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED,
 .ClockPrescaler = 256,
 .SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE,
 .DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE,
 .ChipSelectBoundary = 0,
 .DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED,
 .MaxTran = 0,
 .Refresh = 0,
 },
 
Init(void) {
// Enable clock
_HAL_RCC_OSPI1_CLK_ENABLE();
// Enable pins (CS, CLK, QSPI Data 1-4) 
...
// Initialize
 if (HAL_OSPI_Init(&ospiHandle) != HAL_OK)
 {
 Error_Handler();
 }
 
// Manager config
 OSPIM_CfgTypeDef sOspiManagerCfg = {0};
 sOspiManagerCfg.ClkPort = 1;
 sOspiManagerCfg.DQSPort = 1;
 sOspiManagerCfg.NCSPort = 1;
 sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
 sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;
 if (HAL_OSPIM_Config(&ospiHandle, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 Error_Handler();
 }
 HAL_OSPI_DLYB_CfgTypeDef HAL_OSPI_DLYB_Cfg_Struct = {0};
 HAL_OSPI_DLYB_Cfg_Struct.Units = 0;
 HAL_OSPI_DLYB_Cfg_Struct.PhaseSel = 0;
 if (HAL_OSPI_DLYB_SetConfig(&ospiHandle, &HAL_OSPI_DLYB_Cfg_Struct) != HAL_OK)
 {
 Error_Handler();
 }
 
// Attempted with both Page Program (CMD_PP = 02h) and Quad Page Program (CMD_QPP = 32h); fault occurs with both
static bool EnableMemoryMappedMode(uint8_t readInstruction, uint8_t writeInstruction)
{
 // Details of Write Enable function excluded since confirmed to work
 SetWriteEnable(self);
 
 OSPI_RegularCmdTypeDef command = {0};
 command.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG;
 command.FlashId = HAL_OSPI_FLASH_ID_1;
 command.Instruction = writeInstruction;
 command.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
 command.NbData = 1;
 
 switch(writeInstruction)
 {
 case CMD_QPP:
 command.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
 command.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
 command.DataMode = HAL_OSPI_DATA_4_LINES;
 break;
 case CMD_PP:
 default:
 command.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
 command.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
 command.DataMode = HAL_OSPI_DATA_1_LINE;
 command.Instruction = DEFAULT_CMD_PP;
 break;
 }
 
 bool success = true;
 
 if (HAL_OSPI_Command(&ospiHandle, &command, OSPI_READY_TIMEOUT) != HAL_OK)
 {
 success = false;
 }
 
 command.OperationType = HAL_OSPI_OPTYPE_READ_CFG;
 command.Instruction = readInstruction;
 command.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
 
 switch(readInstruction)
 {
 case CMD_QREAD:
 command.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
 command.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
 command.DataMode = HAL_OSPI_DATA_4_LINES;
 command.DummyCycles = 8;
 break;
 case CMD_READ:
 default:
 command.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
 command.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
 command.DataMode = HAL_OSPI_DATA_1_LINE;
 command.DummyCycles = 0;
 break;
 }
 
 if (HAL_OSPI_Command(&ospiHandle, &command, OSPI_READY_TIMEOUT) != HAL_OK)
 {
 success = false;
 }
 
 OSPI_MemoryMappedTypeDef memMappedCfg = {0};
 memMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_ENABLE;
 memMappedCfg.TimeOutPeriod = 0xFFFF;
 if (HAL_OSPI_MemoryMapped(&ospiHandle, &memMappedCfg) != HAL_OK)
 {
 success = false;
 }
 
 return success;
}
 
test(void)
{
 EraseBlocks(self, 0, 0);
 
 static uint8_t commands[3] = { DEFAULT_CMD_QPP, DEFAULT_CMD_4PP, DEFAULT_CMD_PP };
 
 for(uint32_t i = 0, testW = 0; i < 3 && !found; i++)
 {
 // Tried PP and READ (not-quad commands) as well
 // EnableMemoryMappedMode(CMD_READ, CMD_PP);
 EnableMemoryMappedMode(CMD_QREAD, CMD_QPP);
 
 uint32_t testR = 0xFFFFFFFF;
 
 // Verify erase (overwites 0xAA with expected 0xFF)
 uint8_t value = 0xAA;
 uint8_t * mem_addr = (uint8_t *)(OCTOSPI1_BASE);
 value = *mem_addr;
 
 // Hard fault occurs here
 *mem_addr = 0xAA;
}

This topic has been closed for replies.
Best answer by BDoon.1

Hey BHamm! I am looking at this currently, and have seen the same issue you were seeing. It turns out this is an issue covered by the Errata, specifically item 2.6.1. "Memory-mapped write error response when DQS output is disabled"

Setting the DQSMode field to HAL_OSPI_DQS_ENABLE in the OSPI_RegularCmdTypeDef for the HAL_OSPI_OPTYPE_WRITE_CFG command fixes the issue. ie:

command.DQSMode = HAL_OSPI_DQS_ENABLE;

2 replies

Tesla DeLorean
Guru
September 12, 2022

Not clear how well this responds to, and propagates errors, rather than just ploughing forward.

If the memory mapping fails, it will fault.

Suggest unpacking and reviewing OSPI peripheral content.

Enable asserts() and check error/status reporting.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
BHamm
BHammAuthor
Associate II
September 12, 2022

Asserts are enabled, and all functions return the HAL_OK status.

BDoon.1
BDoon.1Best answer
Associate III
January 31, 2023

Hey BHamm! I am looking at this currently, and have seen the same issue you were seeing. It turns out this is an issue covered by the Errata, specifically item 2.6.1. "Memory-mapped write error response when DQS output is disabled"

Setting the DQSMode field to HAL_OSPI_DQS_ENABLE in the OSPI_RegularCmdTypeDef for the HAL_OSPI_OPTYPE_WRITE_CFG command fixes the issue. ie:

command.DQSMode = HAL_OSPI_DQS_ENABLE;