2021-10-07 05:35 PM
I am trying to use the OCTOSPI2 (connector MB1242) in dev kit STM32H7B3I-EVAL with the Hypebus PSRAM IS66WVH8M8ALL-100.
I successfully configured the memory to write and read in memory map mode, however this can only be done if the write is immediately followed by the read. For instance, if I add a 1ms delay after write an address, reading the same address will return wrong content.
HyperBus Configuration
__weak HAL_StatusTypeDef MX_OSPI_RAM_Init(OSPI_HandleTypeDef *hospi, MX_OSPI_InitTypeDef *Init) {
OSPI_HyperbusCfgTypeDef sHyperbusCfg;
HAL_StatusTypeDef status;
/* OctoSPI initialization */
hospi->Instance = OCTOSPI2;
HAL_OSPI_DeInit(hospi);
/*
* With Init->ClockPrescaler = 3, the RAM will run at 40 MHz
* ClockPrescaler = 3
* Refresh = 160
*/
hospi->Init.FifoThreshold = 4;
hospi->Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi->Init.MemoryType = HAL_OSPI_MEMTYPE_HYPERBUS;
hospi->Init.DeviceSize = Init->MemorySize;
hospi->Init.ChipSelectHighTime = 8;
hospi->Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi->Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi->Init.ClockPrescaler = Init->ClockPrescaler;
hospi->Init.SampleShifting = Init->SampleShifting;
hospi->Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
hospi->Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
hospi->Init.Refresh = 160;//373; /*4us @40MHz*/
hospi->Init.ChipSelectBoundary = 1;
hospi->Init.ClkChipSelectHighTime = 0;
hospi->Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
status = HAL_OSPI_Init(hospi);
if (status == HAL_OK) {
sHyperbusCfg.RWRecoveryTime = RW_RECOVERY_TIME;
sHyperbusCfg.AccessTime = DEFAULT_INITIAL_LATENCY;
sHyperbusCfg.WriteZeroLatency = HAL_OSPI_LATENCY_ON_WRITE;
sHyperbusCfg.LatencyMode = HAL_OSPI_FIXED_LATENCY;
status = HAL_OSPI_HyperbusCfg(&hospi_ram[0], &sHyperbusCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
}
return status;
}
int32_t BSP_OSPI_RAM_Init(uint32_t Instance, BSP_OSPI_RAM_Init_t *Init) {
int32_t ret;
MX_OSPI_InitTypeDef ospi_init;
/* Check if the instance is supported */
if (Instance >= OSPI_RAM_INSTANCES_NUMBER) {
ret = BSP_ERROR_WRONG_PARAM;
} else {
/* Check if the instance is already initialized */
if (Ospi_Ram_Ctx[Instance].IsInitialized == OSPI_ACCESS_NONE) {
#if (USE_HAL_OSPI_REGISTER_CALLBACKS == 0)
/* Msp OSPI initialization */
OSPI_RAM_MspInit(&hospi_ram[Instance]);
#else
/* Register the OSPI MSP Callbacks */
if(OspiRam_IsMspCbValid[Instance] == 0UL)
{
if(BSP_OSPI_RAM_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE)
{
return BSP_ERROR_PERIPH_FAILURE;
}
}
#endif /* USE_HAL_OSPI_REGISTER_CALLBACKS */
/* Fill config structure */
ospi_init.ClockPrescaler = 7; /* OctoSPI clock = 280MHz / ClockPrescaler = 40MHz */
ospi_init.MemorySize = (uint32_t)POSITION_VAL(ISS66WVH8M8_RAM_SIZE);
ospi_init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
/* STM32 OSPI interface initialization */
if (MX_OSPI_RAM_Init(&hospi_ram[Instance], &ospi_init) != HAL_OK) {
ret = BSP_ERROR_PERIPH_FAILURE;
}
/* Configure the memory */
else if (BSP_OSPI_RAM_ConfigHyperRAM(Instance,
Init->LatencyType,
Init->BurstType,
Init->BurstLength) != BSP_ERROR_NONE) {
ret = BSP_ERROR_COMPONENT_FAILURE;
}
else {
ret = BSP_ERROR_NONE;
}
} else {
ret = BSP_ERROR_NONE;
}
}
/* Return BSP status */
return ret;
}
Test code
BSP_OSPI_RAM_Init_t sOSPI_RAM_Init;
/** Init external ram **/
sOSPI_RAM_Init.LatencyType = BSP_OSPI_RAM_FIXED_LATENCY;
sOSPI_RAM_Init.BurstType = BSP_OSPI_RAM_LINEAR_BURST;
sOSPI_RAM_Init.BurstLength = BSP_OSPI_RAM_BURST_32_BYTES;
if (BSP_OSPI_RAM_Init(0, &sOSPI_RAM_Init) != BSP_ERROR_NONE) {
Error_Handler();
}
/** Put exRam in memory mapped mode **/
if (BSP_OSPI_RAM_EnableMemoryMappedMode(0) != BSP_ERROR_NONE) {
Error_Handler();
}
while (1) {
mem_addr = (__IO uint16_t*)(OCTOSPI2_BASE + address);
for (index = 0; index < BUFFERSIZE; (index += 2)) {
/* Writing Sequence --------------------------------------------------- */
*mem_addr = *(uint16_t*)&aTxBuffer[index];
//HAL_Delay(1); <<<---- Adding this delay cause the read to fail
/* Reading Sequence --------------------------------------------------- */
if (*mem_addr != *(uint16_t*)&aTxBuffer[index]) {
BSP_LED_On(LED_RED);
}
mem_addr++;
}
BSP_LED_Toggle(LED_GREEN);
HAL_Delay(100);
address += OSPI_HYPERRAM_INCR_SIZE;
if (address >= OSPI_HYPERRAM_END_ADDR) {
address = 0;
}
}
I tried changing the timming configuration in many ways but none with success. Currently the MCU is running at 280MHz and the OctoSPI Clock is 40MHz.
Does anybody have a similar issue?
Solved! Go to Solution.
2021-10-08 12:28 PM
ChahinezC Thank you for the tip.
I actually found that I forgot to fit resistor R75 in the EVAL board.
Now everything is working fine
2021-10-08 06:05 AM
Hello @DReis.2,
I suggest you setting the ChipSelectBoundary to 0.
Please keep me informed whether this helped you solve your problem.
Chahinez.
2021-10-08 12:28 PM
ChahinezC Thank you for the tip.
I actually found that I forgot to fit resistor R75 in the EVAL board.
Now everything is working fine