My STM32 locks up when I try to access a memory mapped external RAM. Cannot be reprogrammed.
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.
