Skip to main content
JRand.1
Associate
October 21, 2021
Solved

STM32H735 Multiplexed Memory Mapped OSPI Hyperram Hardfault

Hi, I use OCTOSPI1 and OCTOSPI2 in multiplexed mode to interface with two S27KL0641 ram in Memory Mapped mode.

Those Rams are used for LTDC Frame Buffer and for other application data (structure, data ...).

I started from the STM32Cube_FW_H7_V1.9.0\Drivers\BSP\Components\s70kl1281 and STM32Cube_FW_H7_V1.9.0\Drivers\BSP\STM32H735G-DK from cubeMX to initialise the OSPI, I changed pin affectation, added HAL_OSPIM_Config and enabled IoManager clock.

The application starts correctly but after some minutes it enters in Hardfault.

Depending on MPU initilization, the problem occurs faster.

Here is my MPU configuration

//ospi2 data

 MPU_InitStruct.Enable = MPU_REGION_ENABLE;

 MPU_InitStruct.BaseAddress = OCTOSPI2_BASE;

 MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;

 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;

 MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

 MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;

 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;

 MPU_InitStruct.Number = MPU_REGION_NUMBER0;

 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;

 MPU_InitStruct.SubRegionDisable = 0x00;

 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

 HAL_MPU_ConfigRegion(&MPU_InitStruct);

 //ospi 1 data

 MPU_InitStruct.Enable = MPU_REGION_ENABLE;

 MPU_InitStruct.BaseAddress = OCTOSPI1_BASE;

 MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;

 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;

 MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

 MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;

 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;

 MPU_InitStruct.Number = MPU_REGION_NUMBER1;

 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;

 MPU_InitStruct.SubRegionDisable = 0x00;

 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

 HAL_MPU_ConfigRegion(&MPU_InitStruct);  

  

//octospi1 frame buff, size = 0x200000

 MPU_InitStruct.Enable = MPU_REGION_ENABLE;

 MPU_InitStruct.BaseAddress = OCTOSPI1_BASE;

 MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;

 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;

 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;

 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;

 MPU_InitStruct.Number = MPU_REGION_NUMBER2;

 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;

MPU_InitStruct.SubRegionDisable = ~0x03; 

 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

 HAL_MPU_ConfigRegion(&MPU_InitStruct); 

Here is the Ram parameters

hospi->Init.DualQuad       = HAL_OSPI_DUALQUAD_DISABLE;

hospi->Init.MemoryType      = HAL_OSPI_MEMTYPE_HYPERBUS;

hospi->Init.DeviceSize      = Init->MemorySize;

hospi->Init.FreeRunningClock   = HAL_OSPI_FREERUNCLK_DISABLE;

hospi->Init.ClockMode       = HAL_OSPI_CLOCK_MODE_0;

hospi->Init.WrapSize       = HAL_OSPI_WRAP_128_BYTES;

hospi->Init.SampleShifting    = Init->SampleShifting;

hospi->Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;  

hospi->Init.ChipSelectBoundary  = 23; /* memory die boundary 2^23=8MBs*/

hospi->Init.Refresh        = 275; //250; /*4us @100MHz*/

hospi->Init.FifoThreshold     = 1;

hospi->Init.ChipSelectHighTime  = 20;

hospi->Init.ClockPrescaler    = 4; //clocked from 275Mhz

 ospi_ram_init.LatencyType = BSP_OSPI_RAM_FIXED_LATENCY;

 ospi_ram_init.BurstType  = BSP_OSPI_RAM_LINEAR_BURST;

 ospi_ram_init.BurstLength = BSP_OSPI_RAM_BURST_32_BYTES;

Can you tell me if there is something wrong in my code that may cause this issue? Thanks in advance

This topic has been closed for replies.
JRand.1
JRand.1Best answer
Associate
January 31, 2022

Hi, I tested with your code and i have the same issue.

I managed to solved the problem, it was due to some timing problems, I had to enable DelayBlock to make it work

hospi->Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED;

DelayBlock_Configure(DLYB_OCTOSPI1,1,50);

Thanks for your help

5 replies

Alex - APMemory
Associate II
January 17, 2022

Hi,

I'm not sure if this could help, but see below for reference corresponding settings of APS6408L-3OBM.

These OPI device family (APS6408..., APS12808..., APS256.., APS512...) are an equivalent of HyperRAM in term of performance, with same BGA24 package footprint, also supported by STM32H7

(Section 7.9 of https://www.st.com/resource/en/user_manual/dm00682073-discovery-kit-with-stm32h735ig-mcu-stmicroelectronics.pdf)

You may want to compare the code to find the issue or just try different device.

Alex

 ***************************************

 /* Initialize OctoSPI ----------------------------------------------------- */

 OSPIHandle.Instance = OCTOSPI2;

 HAL_OSPI_DeInit(&OSPIHandle);

 OSPIHandle.Init.FifoThreshold        = 1;

 OSPIHandle.Init.DualQuad             = HAL_OSPI_DUALQUAD_DISABLE;

 OSPIHandle.Init.MemoryType           = HAL_OSPI_MEMTYPE_APMEMORY;

 OSPIHandle.Init.DeviceSize           = 23; /* 64 MBits */

 OSPIHandle.Init.ChipSelectHighTime   = 1;

 OSPIHandle.Init.FreeRunningClock     = HAL_OSPI_FREERUNCLK_DISABLE;

 OSPIHandle.Init.ClockMode            = HAL_OSPI_CLOCK_MODE_0;

 OSPIHandle.Init.WrapSize             = HAL_OSPI_WRAP_NOT_SUPPORTED;

 OSPIHandle.Init.ClockPrescaler       = 0x3;

 OSPIHandle.Init.SampleShifting       = HAL_OSPI_SAMPLE_SHIFTING_NONE;

 OSPIHandle.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;

 OSPIHandle.Init.ChipSelectBoundary   = 0;

 OSPIHandle.Init.FreeRunningClock     = HAL_OSPI_FREERUNCLK_ENABLE;

   /* 1- Writing Sequence ------------------------------------------------ */

   sCommand.OperationType     = HAL_OSPI_OPTYPE_COMMON_CFG;

   sCommand.FlashId           = HAL_OSPI_FLASH_ID_1;

   sCommand.Instruction       = WRITE_CMD;

   sCommand.InstructionMode   = HAL_OSPI_INSTRUCTION_8_LINES;

   sCommand.InstructionSize   = HAL_OSPI_INSTRUCTION_8_BITS;

   sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;

   sCommand.Address           = 0x0;

   sCommand.AddressMode       = HAL_OSPI_ADDRESS_8_LINES;

   sCommand.AddressSize       = HAL_OSPI_ADDRESS_32_BITS;

   sCommand.AddressDtrMode    = HAL_OSPI_ADDRESS_DTR_ENABLE;

   sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

   sCommand.DataMode          = HAL_OSPI_DATA_8_LINES;

   sCommand.NbData            = BUFFER_LENGTH;

   sCommand.DataDtrMode       = HAL_OSPI_DATA_DTR_ENABLE;

   sCommand.DummyCycles       = DUMMY_CLOCK_CYCLES_WRITE;

   sCommand.DQSMode           = HAL_OSPI_DQS_ENABLE;

   sCommand.SIOOMode          = HAL_OSPI_SIOO_INST_EVERY_CMD;

   

    if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

   {

     Error_Handler();

   }

   

    if (HAL_OSPI_Transmit(&OSPIHandle, TX_Buffer, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

   {

     Error_Handler();

   }

   

    /* 2- Reading Sequence ------------------------------------------------ */

   sCommand.Instruction = READ_CMD;

   sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ;

   sCommand.DQSMode    = HAL_OSPI_DQS_ENABLE;

   if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

   {

     Error_Handler();

   }

   

    if (HAL_OSPI_Receive(&OSPIHandle, RX_Buffer, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

   {

     Error_Handler();

   }

 ***********************************************

David Littell
Senior II
January 17, 2022

You do realize your example sets .FreeRunning Clock to ..._DISABLE then later to ..._ENABLE?

Alex - APMemory
Associate II
January 18, 2022

Yes, RAM is set to disable

Anyway this and your other examples provide working examples for running different devices option upon final user choice such as as availabilty or competitivness.

David Littell
Senior II
January 17, 2022

The following "works for me" with a single S27KL0641DABHV020 device and some OCTOSPIM voodoo:

/* OCTOSPI1 init function */

void MX_OCTOSPI1_Init(void)

{

 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;

 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 = 2;

 sOspiManagerCfg.NCSPort = 1;

 sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_2_LOW;

 sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;

/***[Local modification begin]***/

 sOspiManagerCfg.Req2AckTime = 1;  /* ??? should be set by CMX (0 from struct decl above will assert in HAL_OSPIM_Config(). */

/***[Local modification end]***/

 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();

 }

/***[Local modification begin]***/

 {

   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();

     }

 }

/***[Local modification end]***/

}

JRand.1
JRand.1AuthorBest answer
Associate
January 31, 2022

Hi, I tested with your code and i have the same issue.

I managed to solved the problem, it was due to some timing problems, I had to enable DelayBlock to make it work

hospi->Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED;

DelayBlock_Configure(DLYB_OCTOSPI1,1,50);

Thanks for your help