Skip to main content
Visitor II
October 18, 2021
Question

My STM32 locks up when I try to access a memory mapped external RAM. Cannot be reprogrammed.

  • October 18, 2021
  • 3 replies
  • 2994 views

I have a custom PCB with a STM32H7A3ZI MCU, and a S27KL0642S27KS0642 Hyperbus RAM.

My code, as well as the app note (AN5050) I'm following sets up the RAM for memory mapped access.

I've checked and rechecked the pinout and configuration, but every time I try to access the memory address of the ram, the chip locks up completely. The debugger looses connection, and the chip won't program, the ST-LINK V2 gives the error message DEV_TARGET_NOT_HALTED.

I was eventually able to reprogram the board by power cycling it while simultainiously forcing the boot pin high with a probe.

The trace lengths are between 0.62in and 0.97in, except for CS which I (perhaps naively) allowed to be 1.3in.

Here's my current setup code:

OSPIM_CfgTypeDef sOspiManagerCfg = {0};
 OSPI_HyperbusCfgTypeDef sHyperBusCfg = {0};
 
 hospi1.Instance = OCTOSPI1;
 hospi1.Init.FifoThreshold = 4; 
 hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
 hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_HYPERBUS;
 hospi1.Init.DeviceSize = 23; 
 hospi1.Init.ChipSelectHighTime = 1; 
 hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
 hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
 hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
 hospi1.Init.ClockPrescaler = 2; /* My OCTOSPI1 module is clocked at 200 MHz ==> 100 MHz HyperRAM clock. */
 hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
 hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
 hospi1.Init.ChipSelectBoundary = 0;
 hospi1.Init.ClkChipSelectHighTime = 0;
 hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
 hospi1.Init.MaxTran = 0;
 hospi1.Init.Refresh = 100; 
 if (HAL_OSPI_Init(&hospi1) != HAL_OK)
 {
 Error_Handler();
 }
 
 sOspiManagerCfg.ClkPort = 2;
 sOspiManagerCfg.DQSPort = 1;
 sOspiManagerCfg.NCSPort = 2;
 sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_2_LOW;
 sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_1_LOW;
 
 sOspiManagerCfg.Req2AckTime = 1;
 
 if (HAL_OSPIM_Config(&hospi1, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 Error_Handler();
 }
 sHyperBusCfg.RWRecoveryTime = 4; 
 sHyperBusCfg.AccessTime = 6; 
 sHyperBusCfg.WriteZeroLatency = HAL_OSPI_LATENCY_ON_WRITE;
 sHyperBusCfg.LatencyMode = HAL_OSPI_FIXED_LATENCY;
 if (HAL_OSPI_HyperbusCfg(&hospi1, &sHyperBusCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 Error_Handler();
 }
 
 /* Memory-mapped mode setup */
 {
 
 OSPI_HyperbusCmdTypeDef sCommand = { 0 };
 
 OSPI_MemoryMappedTypeDef sMemMappedCfg = { 0 };
 
 
 /* Memory-mapped mode configuration --------------------------------------- */
 sCommand.AddressSpace = HAL_OSPI_MEMORY_ADDRESS_SPACE;
 sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
 sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;
 sCommand.Address = 0;
 sCommand.NbData = 1;
 
 if( HAL_OSPI_HyperbusCmd( &hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE ) != HAL_OK )
 {
 
 Error_Handler();
 
 }
 
 
 sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
 
 if( HAL_OSPI_MemoryMapped( &hospi1, &sMemMappedCfg ) != HAL_OK )
 {
 
 Error_Handler();
 
 }
 
 }

And my code to test it:

uint32_t testbuffer[200];
__IO uint32_t *OCTOSPI1_MEMMAPPED_ADD = (__IO uint32_t *)(OCTOSPI1_BASE);
 
uint16_t index;
 for (index = 0; index < 200; index++){ //verify that the chip and debugger are working correctly
	 testbuffer[index] = index*12;
 }
 for (index = 0; index < 200; index++){
	 testbuffer[index] = OCTOSPI1_MEMMAPPED_ADD[index]; //try to read from the external ram, execution freezes here
 }
 for (index = 0; index < 200; index++){
	 OCTOSPI1_MEMMAPPED_ADD[index] = index*11;
 }
 for (index = 0; index < 200; index++){
	 testbuffer[index] = OCTOSPI1_MEMMAPPED_ADD[index];
 }

Does anyone know how to solve this, or even debug it? I get no errors, just the lock up.

The only thing I haven't tried is slowing the bus down to 10MHz and painstakingly soldering leads onto the signals for a logic analyzer.

I have noticed that if I upload this code to the older board that lacks the RAM chip, it does not lock up, it just reads some random value when accessing the memory location.

Thanks!

Edit:

Well I've found one mistake. In the fine print of the datasheet I noticed: "Tie the CK# input pin to either VccQ or VssQ if not connected to the host controller, but do not leave it floating." ..but I have left it floating. I wonder if this is the issue? Unfortunately it is difficult to fix.

    This topic has been closed for replies.

    3 replies

    Visitor II
    October 18, 2021

    A quick info for debugging: If you break after execution of the HAL_OSPI_MemoryMapped Function, you should see the memory mapped space in the memory-window of the debugger at 0x90000000, It should display 0xffs up to the end of your mem-size 2^23. Before that function it should have been 0x00. In my case (AP Memory and Hyperflash) I also needed the delay block.

    JDoe.7Author
    Visitor II
    October 18, 2021

    Whenever I try to check the memory location with the debugger it crashes the same way as if I executed the read in code.

    I will try to implement the delay block and see if that helps, but I've been shooting in the dark for a long time, so I'm hoping to find a more systematic approach.

    Thank you for the help!

    ST Employee
    October 18, 2021

    Hello

    Not sure but maybe it is needed to have the memory area declared as Device or Strongly ordered in the Memory Protection Unit.

    see AN4838 chapter 3.4 "Cortex-M7 constraint speculative prefetch".

    JDoe.7Author
    Visitor II
    October 18, 2021

    Thank you for the suggestion, but how do you think that would help? Right now I can't access the memory mapped region at all. I'm not familiar with the MPU, but it seems tailored to controlling *what* can access certain memory regions. I have not explicitly enabled the MPU, as far as I am aware. I'm using the basic cubeMX generated code, besides the snippet I posted.

    Visitor II
    October 19, 2021

    The configuration of the delay block is a bit difficult, but it should not affect the device crashing (in my case I just had nonsense chars in between).

    Your config itself looks ok, to me. If the clocks are also done by cubemx it should at least not crash. You said, you checked the layout, still I would think it must be something in that way. 1,8V and differential clock? Otherwise I'm out of ideas.