Setting up HyperRAM S70KL1282 with STM32H735 issues
Hi,
I'm trying to setup this new RAM chips on STM32H735 in OSPI/HyperRAM mode. The HW connection is the same as on ST STM32H735 devkit. I found a driver for similar chip S70KL1281 but there are some differences, e.g. in latencies, but generally S70KL1282 is faster. The used driver file identification from header:
******************************************************************************
* @file s70kl1281.c
* @modify MCD Application Team
* @brief This file provides the S70KL1281 OSPI drivers.
...
* Copyright (c) 2020 STMicroelectronics.
******************************************************************************
I configured the Hyperbus in STM32CubeMX but there are no hints how to setup all the options for this memory. So after some messing and trial-error I ended with this partially working init code:
static void MX_OCTOSPI2_Init(void)
{
OSPIM_CfgTypeDef sOspiManagerCfg = {0};
OSPI_HyperbusCfgTypeDef sHyperBusCfg = {0};
/* OCTOSPI2 parameter configuration*/
hospi2.Instance = OCTOSPI2;
hospi2.Init.FifoThreshold = 1;
hospi2.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi2.Init.MemoryType = HAL_OSPI_MEMTYPE_HYPERBUS;
hospi2.Init.DeviceSize = 24;
hospi2.Init.ChipSelectHighTime = 1;
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 = 2; // for testing use prescaler 2 at 133MHz, prescaler 1 gets garbage
hospi2.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
hospi2.Init.ChipSelectBoundary = 0;
hospi2.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED;
hospi2.Init.MaxTran = 0;
hospi2.Init.Refresh = 500;
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 = 3;
sHyperBusCfg.AccessTime = 7;
sHyperBusCfg.WriteZeroLatency = HAL_OSPI_NO_LATENCY_ON_WRITE; // someone suggested HAL_OSPI_LATENCY_ON_WRITE but doesn't have effect
sHyperBusCfg.LatencyMode = HAL_OSPI_FIXED_LATENCY;
if (HAL_OSPI_HyperbusCfg(&hospi2, &sHyperBusCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
}
First time I had a problem that reading from memory was unrealiable and I sometimes getting a different results on every run. Enabling the magic option hospi2.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED; solved it but still not at the full clock speed I configured - I have both OSPI clocked at 133MHz. The FlashROM at OSPI1 works fine at 133MHz but for this HyperRAM I have to set prescaler 2. Then I got some consistent result.
But there's another problem that test data pattern I wrote into memory are readed by 8 Bytes shifted further than it should be. Currently for testing I don't use mapping yet but I use driver functions S70KL1281_Write and S70KL1281_Read. A simple piece of code for test write and readbeck:
{
uint8_t buff[64]={0};
int i;
buff[0]=0xab; buff[1]=0xcd; buff[2]=0xef; buff[3]=0xaa;
if (S70KL1281_Write(&XRAM, buff, 0, 16)!=S70KL1281_OK)
printf("Failed to write to HyperRAM\n");
for (i=0; i<32; i++)
printf("%02X ", buff[i]);
printf("\n");
if (S70KL1281_Read(&XRAM, buff, 0, 32)!=S70KL1281_OK)
printf("Failed to read from HyperRAM\n");
for (i=0; i<32; i++)
printf("%02X ", buff[i]);
printf("\n");
if (S70KL1281_Read(&XRAM, buff, 0, 32)!=S70KL1281_OK)
printf("Failed to read from HyperRAM\n");
for (i=0; i<32; i++)
printf("%02X ", buff[i]);
printf("\n");
}
The memory address is 0 but I get this:
Ext. OctoSPI HyperRAM ID: 0C81 0001
Manufacturer: Infineon, HyperRAM 2.0, rowbits: 13, colbits: 9
AB CD EF AA 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
57 47 57 5D D5 D7 8C 15 AB CD EF AA 00 00 00 00 00 00 00 00 00 00 00 00 D5 D5 57 5F D5 D5 5F 75
57 47 57 5D D5 D7 8C 15 AB CD EF AA 00 00 00 00 00 00 00 00 00 00 00 00 D5 D5 57 5F D5 D5 5F 75
There's some garbage in first 8 Bytes (57 47 57 5D D5 D7 CC 15 - uninitialized memory?) followed by correct pattern AB CD EF AA and trailing zeros from buffer
