cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H735G-DK OCTOSPI2 HyperRAM 1st Read PASS, next Read FAIL

JKim.2
Associate III

Hello,

 

I created the STM32H735G-DK project with the board selector in STM32CubeIDE.

The OSPI_HyperRAM_MemoryMapped project was created by the example selector. Its HyperRAM test codes were added to the STM32H735G-DK project as below. The reading sequence was repeated twice on the same address w/o increasing the memory pointer. However, the 2nd reading was always failing while the 1st reading was fine as below. Please help me to solve this issue. The MX_OCTOSPI2_Init function is also pasted below.

 

Thanks.

 

SUCCESS1: mem_addr = 0x70000000 pattern = 2a2a2a20 output = 2a2a2a20
FAILURE2: mem_addr = 0x70000000 pattern = 2a2a2a20 output = 5655d557
SUCCESS1: mem_addr = 0x70000004 pattern = 6d654d2a output = 6d654d2a
FAILURE2: mem_addr = 0x70000004 pattern = 6d654d2a output = 55155146
SUCCESS1: mem_addr = 0x70000008 pattern = 2d79726f output = 2d79726f
FAILURE2: mem_addr = 0x70000008 pattern = 2d79726f output = 55555551
SUCCESS1: mem_addr = 0x7000000c pattern = 7070616d output = 7070616d
FAILURE2: mem_addr = 0x7000000c pattern = 7070616d output = 11113f51

 

uint32_t address = 0, outdex=0;
uint16_t index;
__IO uint32_t *mem_addr;
 
    mem_addr = (__IO uint32_t *)(OCTOSPI2_BASE + address);
 
for (index = 0; index < 16; (index += 4))
{
  /* Writing Sequence --------------------------------------------------- */
  *mem_addr = *(uint32_t *)&aTxBuffer[index];
  /* Reading Sequence --------------------------------------------------- */
  if (*mem_addr != *(uint32_t *)&aTxBuffer[index])
  {
  if (outdex==0) printf("FAILURE1: mem_addr = %p pattern = %08lx output = %08lx\r\n",
  mem_addr, *(uint32_t *)&aTxBuffer[index], *mem_addr);
  } else { //Read Pass
  if (outdex==0) printf("SUCCESS1: mem_addr = %p pattern = %08lx output = %08lx\r\n",
  mem_addr, *(uint32_t *)&aTxBuffer[index], *mem_addr);
  }
 
  if (*mem_addr != *(uint32_t *)&aTxBuffer[index])
  {
  if (outdex==0) printf("FAILURE2: mem_addr = %p pattern = %08lx output = %08lx\r\n",
  mem_addr, *(uint32_t *)&aTxBuffer[index], *mem_addr);
  } else { //Read Pass
  if (outdex==0) printf("SUCCESS2: mem_addr = %p pattern = %08lx output = %08lx\r\n",
  mem_addr, *(uint32_t *)&aTxBuffer[index], *mem_addr);
  }
 
  mem_addr++;
}
 
//HAL_Delay(100);
address += OSPI_HYPERRAM_INCR_SIZE;
if(address >= OSPI_HYPERRAM_END_ADDR)
{
  address = 0;
}
 

static void MX_OCTOSPI2_Init(void)
{

/* USER CODE BEGIN OCTOSPI2_Init 0 */

/* USER CODE END OCTOSPI2_Init 0 */

OSPIM_CfgTypeDef sOspiManagerCfg = {0};
OSPI_HyperbusCfgTypeDef sHyperBusCfg = {0};

/* USER CODE BEGIN OCTOSPI2_Init 1 */

/* USER CODE END OCTOSPI2_Init 1 */
/* OCTOSPI2 parameter configuration*/
hospi2.Instance = OCTOSPI2;
HAL_OSPI_DeInit(&hospi2);
hospi2.Init.FifoThreshold = 4;
hospi2.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi2.Init.MemoryType = HAL_OSPI_MEMTYPE_HYPERBUS;
hospi2.Init.DeviceSize = OSPI_HYPERRAM_SIZE;
hospi2.Init.ChipSelectHighTime = 8;
hospi2.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi2.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi2.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
hospi2.Init.ClockPrescaler = 4;
hospi2.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
hospi2.Init.ChipSelectBoundary = 23;
hospi2.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED;
hospi2.Init.MaxTran = 0;
hospi2.Init.Refresh = 250;
if (HAL_OSPI_Init(&hospi2) != HAL_OK)
{
Error_Handler();
}

sOspiManagerCfg.ClkPort = 2;
sOspiManagerCfg.DQSPort = 2;
sOspiManagerCfg.NCSPort = 2;
sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_2_LOW;
sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_2_HIGH;
if (HAL_OSPIM_Config(&hospi2, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

sHyperBusCfg.RWRecoveryTime = OSPI_HYPERRAM_RW_REC_TIME;
sHyperBusCfg.AccessTime = OSPI_HYPERRAM_LATENCY;
sHyperBusCfg.WriteZeroLatency = HAL_OSPI_NO_LATENCY_ON_WRITE;
sHyperBusCfg.LatencyMode = HAL_OSPI_FIXED_LATENCY;
if (HAL_OSPI_HyperbusCfg(&hospi2, &sHyperBusCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN OCTOSPI2_Init 2 */
/* 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(&hospi2, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;

if (HAL_OSPI_MemoryMapped(&hospi2, &sMemMappedCfg) != HAL_OK)
{
Error_Handler();
}
/* USER CODE END OCTOSPI2_Init 2 */

}

 
1 ACCEPTED SOLUTION

Accepted Solutions

Hello Kaouthar,

 

The issue is solved with changing the write latency in OCTOSPI2_Init. No latency on write made the strange problem. Thanks.

 

Best Regards,

Jeff

 

sHyperBusCfg.WriteZeroLatency = HAL_OSPI_LATENCY_ON_WRITE; //HAL_OSPI_NO_LATENCY_ON_WRITE;

View solution in original post

7 REPLIES 7
KDJEM.1
ST Employee

Hello @JKim.2 ,

Could you please specify which STM32CubeMX version are you using? Please try with the latest version: STM32CubeMX 6.10.0

Do you have the same issue when you using only the example OSPI_HyperRAM_MemoryMapped and without generating the code with STM32CubeMx? 

Thank you.

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

SofLit
ST Employee

Hello @JKim.2 ,

Next time, please use this feature to insert the code to enhance the readability of your code:

SofLit_1-1703237920863.png

then:

SofLit_0-1703237868811.png

Thank you.

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hello Kaouthar,

 

My STM32CubeMX is Version 6.9.1. The OSPI_HyperRAM_MemoryMapped project generated by the example selector  doesn't show Src folder and many folders in the project explorer in the STM32CubeIDE. The .ioc file and UART are also not available in the OSPI_HyperRAM_MemoryMapped project. So, I preferred using the STM32H735G-DK project generated by the board selector. Could you help me to solve the problem?

 

Best Regards,

Jeff

 

Hello @JKim.2 

S27K1281 memory supported Double-Data Rate (DDR) - two data transfers per clock.

For that, please try to modify this line of code:

 

hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;

 

By:

 

hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;

 

Also, AN5050 can help you to configure your OCTOSPI interface. 

Please let me know if the issue is solved?

Thank you.

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hello Kaouthar,

 

Thank you for your finding. However, the DQHC enabling still can't solve the problem.

 

Best Regards,

Jeff

 

SUCCESS1: mem_addr = 0x70000000 pattern = 2a2a2a20 output = 2a2a2a20
FAILURE2: mem_addr = 0x70000000 pattern = 2a2a2a20 output = 55555555
SUCCESS1: mem_addr = 0x70000004 pattern = 6d654d2a output = 6d654d2a
FAILURE2: mem_addr = 0x70000004 pattern = 6d654d2a output = 55555555
SUCCESS1: mem_addr = 0x70000008 pattern = 2d79726f output = 2d79726f
FAILURE2: mem_addr = 0x70000008 pattern = 2d79726f output = 55550000
SUCCESS1: mem_addr = 0x7000000c pattern = 7070616d output = 7070616d
FAILURE2: mem_addr = 0x7000000c pattern = 7070616d output = 55555555

Hello Kaouthar,

 

I tried to clear SSHIFT in OCTOSPI_TCR as below for DTR mode according to the reference manual. However, the second read operations are still failing.

 

Best Regards,

Jeff

  • Reference Manual (RM0468)

When receiving data in DTR mode, the OCTOSPI assumes that the external devices also
send the data using both CLK rising and falling edges. When DDTR = 1 in OCTOSPI_CCR,
the software must clear SSHIFT in OCTOSPI_TCR. Thus, the signals are sampled one half
of a CLK cycle later (on the following, opposite edge).
In DTR mode, it is recommended to set DHQC of OCTOSPI_TCR, to shift the outputs by a
quarter of cycle and avoid to hold issues on the memory side.

  • STM32H735G-DK/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ospi.c

/* Configure sample shifting and delay hold quarter cycle */
//MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC),
// (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle));
MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_DHQC),
(hospi->Init.DelayHoldQuarterCycle));

 

Hello Kaouthar,

 

The issue is solved with changing the write latency in OCTOSPI2_Init. No latency on write made the strange problem. Thanks.

 

Best Regards,

Jeff

 

sHyperBusCfg.WriteZeroLatency = HAL_OSPI_LATENCY_ON_WRITE; //HAL_OSPI_NO_LATENCY_ON_WRITE;