cancel
Showing results for 
Search instead for 
Did you mean: 

Adjusting XSPI RAM Clock at runtime

exarian
Associate II

Good day folks, I trust you are well.

I am interfacing with a APMemory 256Mbit RAM (APS256XXN-OBR) via the 16 way XSPI.

The RAM registers can be configured correctly at 100MHz, as well as the whole 256 Mbits can be accessed via Mmap.

For Configuration I am using the `APS256_ReadReg()` and `APS256_WriteReg()` functions as provided by the

XSPI_PSRAM_MemoryMapped example.

By default the RAM supports a maximum of 133MHz, which is why I am using 100MHz on powerup.

exarian_0-1739428461225.png

The registers are being configured and verified as follows:

MR0 = 0x11 (200MHz, 50R interface)

MR4 = 0x20 (200MHz, 4X refresh)

MR8 = 0x4F (X16, Row crossing enabled, 2KB word wrap)

After the configuration I am trying to Reinit the XSPI clock using:

/**
  * @brief  Re-initializes the XSPI1 peripheral clock with a new clock divider.
  * @PAram  newDivider: New clock divider value. (e.g., 8 for 200MHz if PLL1 frequency is 1.6GHz)
  * @retval None. Calls Error_Handler() on failure.
  */
void XSPI1_ReInitClock(XSPI_HandleTypeDef* hxspi, uint32_t newDivider)
{
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

  __HAL_RCC_XSPIM_CLK_DISABLE();
  __HAL_RCC_XSPI1_CLK_DISABLE();

  /* Configure the peripheral clock for XSPI1 */
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_XSPI1;
  PeriphClkInitStruct.Xspi1ClockSelection   = RCC_XSPI1CLKSOURCE_IC4;
  PeriphClkInitStruct.ICSelection[RCC_IC4].ClockSelection = RCC_ICCLKSOURCE_PLL1;
  PeriphClkInitStruct.ICSelection[RCC_IC4].ClockDivider   = newDivider;

  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /* Peripheral clock enable */
  __HAL_RCC_XSPIM_CLK_ENABLE();
  __HAL_RCC_XSPI1_CLK_ENABLE();

  HAL_Delay(10);
}

 On powerup the divider is 16, to provide 100MHz, I am trying to adjust it to 8 to bump it to 200MHz.

The CPU is currently running a clock of 400MHz.

What procedure is required to "reset" the XSPI interface to use the higher clock speed?

3 REPLIES 3
TDK
Guru

I'd modify the PRESCALER field in XSPI->DCR2 directly. Set the prescaler so that 100 MHz is generated during initialization then cut it in half after switching to high speed mode.

TDK_0-1739454868117.png

 

If you feel a post has answered your question, please click "Accept as Solution".

Thank you @TDK ,

Would the XSPI need to be reinitialized once that is done? I.e.

At what point will the clock actually be changed?

 

I am busy doing this which is working, however it's not optimal:

void XSPI1_ReInitClock(XSPI_HandleTypeDef* hxspi)
{
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

  if (HAL_XSPI_DeInit(hxspi) != HAL_OK)
  {
    Error_Handler();
  }

  HAL_XSPI_higher_clock(true);

  HAL_Delay(10);

  MX_XSPI1_Init();

  HAL_Delay(10);
}
static bool gb_higher_clock = false;

void HAL_XSPI_higher_clock(bool b_higher)
{
  gb_higher_clock = b_higher;
}
void HAL_XSPI_MspInit(XSPI_HandleTypeDef* hxspi)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  if(hxspi->Instance==XSPI1)
  {
  /* USER CODE BEGIN XSPI1_MspInit 0 */

  /* USER CODE END XSPI1_MspInit 0 */

  /** Initializes the peripherals clock
  */
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_XSPI1;
    PeriphClkInitStruct.Xspi1ClockSelection = RCC_XSPI1CLKSOURCE_IC4;
    PeriphClkInitStruct.ICSelection[RCC_IC4].ClockSelection = RCC_ICCLKSOURCE_PLL1;

    /** Adjustment of the clock using variable */
    PeriphClkInitStruct.ICSelection[RCC_IC4].ClockDivider = gb_higher_clock ? 12 : 16; 
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
      Error_Handler();
    }

With this I am able to  go from a Clock of 100MHz (16), to 133MHz (12).

The RAM is responding at the higher clock, although at 200MHz (8) it is not responding and `APS256_ReadReg()` fails.

I am testing through different RAM Mode Register configurations to get 200MHz working.

Just setting the field should work.

Haven't used the XSPI on the H5, but that's how similar peripherals work on other chips. Perhaps change in this manner from 1 MHz to 2 MHz and verify on a scope or logic analyzer that everything is copasetic.

If you feel a post has answered your question, please click "Accept as Solution".