Skip to main content
YTagu.1
Associate II
January 21, 2022
Solved

STM32 Cube H7 HAL_OSPIM_Config() corrupts previous port configuration on the second call ?

  • January 21, 2022
  • 18 replies
  • 6129 views

We are using STM32Cube_FW_H7 latest version and faced the similar problem happened on STM32Cube_FW_L4 which is discussed here. We use two Octo SPI with one running in Octo memory mapped mode and one running in Quad SPI direct mode.

Firstly, we configured the Octo mode IO ports with HAL_OSPIM_Config and then configured the Quad SPI. If we configure Octo only, the Octo memory mapped mode works well. However, If we configure Quad SPI as well, the first Octo configuration got corrupted.

Does someone face the same problem? I suspect that the similar bug exists in Cube_FW_H7 like the one in STM32Cube_FW_L4.

This topic has been closed for replies.
Best answer by ChahinezC

Hello @YTagu.1​;

I am getting back to you regarding the problem you faced. I have reproduced the issue and reported it internally to our team.

Thank you for highlighting the matter and helping us improve.

Chahinez.

18 replies

ChahinezC
Associate II
January 21, 2022

Hello @YTagu.1​,

Are you using the STM32CubeMX for the generation of your project?

Chahinez.

YTagu.1
YTagu.1Author
Associate II
January 22, 2022

Hi @ChahinezC​ ,

Yes, We're using STM32CubeMX for the generation of our project.

YTagu.1

ChahinezC
Associate II
January 25, 2022

Hello @YTagu.1​,

Can you please specify which ST device you're using and whether you are using the same port or different ones?

Chahinez.

YTagu.1
YTagu.1Author
Associate II
January 25, 2022

Hi @ChahinezC​ ,

Our ST Device is STM32H7A3LIH6Q. We are using different ports, that is, we don't use multiplexed mode.

ChahinezC
Associate II
January 31, 2022

Hello @YTagu.1​,

Can you please state the versions you have used? (The STM32CubeMX and the H7 cube FW versions).

Can you also share with us your .ioc file? It helps us reproduce the issue.

Thank you.

Chahinez.

YTagu.1
YTagu.1Author
Associate II
February 1, 2022

Hi @ChahinezC​ 

Here are the versions:

  • STM32CubeMX: 6.4.0
  • STM32Cube FW_H7 v1.9.0​

Yes, we can share the .ioc file with you. However, it would be better if we can share the .ioc file privately. Could you give me your e-mail address to share the file? Or, do you have any other way to share the file privately?

We really appreciate your effort to reproduce the problem.

Best regards,

Yoshitaka

ChahinezC
Associate II
February 1, 2022

Hi @YTagu.1​,

You can share with me your .ioc file and IAR project by private message.

Can you also provide me with the following details:

Please describe the problem you are facing in details so I can reproduce it.

"the first Octo configuration got corrupted" --> How did you exactly see the corruption?

  • did you face any compilation errors?
  • did the configuration you set in STM32CubeMX get changed?
  • did the first configuration got changed, overwritten or removed (if so please share with me the before and the after)

Chahinez.

YTagu.1
YTagu.1Author
Associate II
February 2, 2022

Hi @ChahinezC​ 

Thanks for suggesting the way to share the file. As I don't use IAR workbench, I only sent you my .ioc file via a private message. Please check your inbox.

We are using external SRAM memory with OctoSPI memory mapped mode. The HyperBus protocol is used. This peripheral is assigned to OctoSPI1. We also use external Flash memory with QuadSPI. This peripheral is assigned to OctoSPI2.

  • We configure the OctoSPI1 and OctoSPI2 on STM32CubeMX at the same time.
  • The CubeMX32 generates initialization function (MX_OCTOSPIx_Init) for both OctoSPI1 and OctoSPI2. We do not face any compilation errors in the generated code.
  • If we call the MX_OCTOSPI1_Init first and then MX_OCTOSPI2_Init, the MCU halts on the first access to the external RAM. The MCU does not jump to any fault handler. It just stop immediately after the access to the external RAM.
  • If we call the MX_OCTOSPI1_Init only and commend out the call of MX_OCTOSPI2_Init, then the external RAM works. We can read and write data to the external RAM with memory mapped mode correctly.

"the first Octo configuration got corrupted" does not mean the corruption of the configuration in CubeMX. It means the corruption of configurations in the registers which were made by HAL_OSPIM_Config function.

To be honest, the statement that "HAL_OSPIM_Config() corrupts previous port configuration on the second call" is just an assumption. As the reference manual states "two OCTOSPI works separately", we assume the problem is happening on the common parts of two OCTOSPI - that is, IO configuration, which is made by HAL_OSPIM_Config.

To state our situation more accurately, "Call of MX_OCTOSPI2_Init corrupts the configuration made by MX_OCTOSPI1_Init".

Best regards,

Yoshitaka

YTagu.1
YTagu.1Author
Associate II
February 9, 2022

Hi, @ChahinezC​ 

Any updates on this topic?

Best regards,

Yoshitaka 

ChahinezC
Associate II
February 9, 2022

Hello Yoshitaka,

I am still trying to reproduce the issue you reported.

I will keep you updated.

Chahinez.

YTagu.1
YTagu.1Author
Associate II
February 9, 2022

Hello Chahinez,

We appreciate your continuous effort to reproduce our problem. Please do not hesitate to ask us if you need further information.

Yoshitaka​

ChahinezC
ChahinezCBest answer
Associate II
February 15, 2022

Hello @YTagu.1​;

I am getting back to you regarding the problem you faced. I have reproduced the issue and reported it internally to our team.

Thank you for highlighting the matter and helping us improve.

Chahinez.

YTagu.1
YTagu.1Author
Associate II
February 15, 2022

Hi @ChahinezC​ ,

We're very glad to hear that you could reproduce our problem.

I'd like to ask a few more questions:

  1. Because we're working on a project with strict schedule, we'd like to have a patch immediately if possible. Do you have any idea when this problem will be fixed?
  2. We have found that reversing the order of initialization makes it possible to use the two interfaces correctly. In short, when we call MX_OCTOSPI2_Init first and then call MX_OCTOSPI1_Init, the external SRAM and Flash memory seem working well. Is this a correct way to fix this provisionally? We're afraid that this is not a right solution and this will cause other problem.

Yoshitaka.

ChahinezC
Associate II
February 16, 2022

Hello @YTagu.1​,

  1. Unfortunately, I have not a date for the problem resolution. Yet, I will keep you informed whenever I have any updates.
  2. When reproducing the issue, I have tried to reverse the order as you did but it didn't work from my side, that's why I can not say it is a workaround.

Chahinez.

YTagu.1
YTagu.1Author
Associate II
February 17, 2022

Hi @ChahinezC​ ,

Thank you for your answer. We're looking forward to hearing updates from you.

Yoshitaka​

YTagu.1
YTagu.1Author
Associate II
May 24, 2022

Hi @ChahinezC​,

Is there any option to get paid support, not the community-based free support for this problem?

In our product development, this remains a serious problem. If paid support is possible, we're willing to use it.

Ufuk.Akkaya
Associate
August 8, 2022

Hello @ChahinezC​ ,

I had the same problem. Only when OctoSPI2 was init FLASH was working. Only when OctoSPI1 was init SRAM was working. When OctoSPI1 was inited after OctoSPI2, only OctoSPI1(SRAM ) worked. It broke OctoSPI2's operation. Both worked when I didn't configure(HAL_OSPIM_Config) the OctoSPI2 port. I don't understand how OctoSPI1 works without configuring NCS, Clock and IOLowPort. I think it may have worked because the pins are configured in MsbInit.

OctoSPI2 Not Working, OctoSPI1 working

--------------------------------------------------------------------

/* OCTOSPI1 init function */
void MX_OCTOSPI1_Init(void)
{
 OSPIM_CfgTypeDef OSPIM_Cfg_Struct = {0};
 
 hospi1.Instance = OCTOSPI1;
 hospi1.Init.FifoThreshold = 1;
 hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
 hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
 hospi1.Init.DeviceSize = 18;
 hospi1.Init.ChipSelectHighTime = 1;
 hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
 hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
 hospi1.Init.ClockPrescaler = 3;
 hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_HALFCYCLE;
 hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
 hospi1.Init.ChipSelectBoundary = 0;
 hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
 if (HAL_OSPI_Init(&hospi1) != HAL_OK)
 {
 Error_Handler();
 }
 OSPIM_Cfg_Struct.ClkPort = 1;
 OSPIM_Cfg_Struct.NCSPort = 1;
 OSPIM_Cfg_Struct.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
 if (HAL_OSPIM_Config(&hospi1, &OSPIM_Cfg_Struct, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 Error_Handler();
 }
 
}
 
 
/* OCTOSPI2 init function */
void MX_OCTOSPI2_Init(void)
{
 OSPIM_CfgTypeDef OSPIM_Cfg_Struct = {0};
 
 hospi2.Instance = OCTOSPI2;
 hospi2.Init.FifoThreshold = 4;
 hospi2.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
 hospi2.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
 hospi2.Init.DeviceSize = 25;
 hospi2.Init.ChipSelectHighTime = 2;
 hospi2.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
 hospi2.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
 hospi2.Init.ClockPrescaler = 1;
 hospi2.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
 hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
 hospi2.Init.ChipSelectBoundary = 0;
 hospi2.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
 if (HAL_OSPI_Init(&hospi2) != HAL_OK)
 {
 Error_Handler();
 }
 OSPIM_Cfg_Struct.ClkPort = 2;
 OSPIM_Cfg_Struct.IOLowPort = HAL_OSPIM_IOPORT_2_LOW;
	OSPIM_Cfg_Struct.NCSPort = 0;
 if (HAL_OSPIM_Config(&hospi2, &OSPIM_Cfg_Struct, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 Error_Handler();
 }
 
}
 
int main()
{
	(...)
 
	MX_OCTOSPI2_Init();
	MX_OCTOSPI1_Init();
	(...)
}

OctoSPI2 and OctoSPI1 are working.

-------------------------------------------------------------------------

/* OCTOSPI1 init function */
void MX_OCTOSPI1_Init(void)
{
 OSPIM_CfgTypeDef OSPIM_Cfg_Struct = {0};
 
 hospi1.Instance = OCTOSPI1;
 hospi1.Init.FifoThreshold = 1;
 hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
 hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
 hospi1.Init.DeviceSize = 18;
 hospi1.Init.ChipSelectHighTime = 1;
 hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
 hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
 hospi1.Init.ClockPrescaler = 3;
 hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_HALFCYCLE;
 hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
 hospi1.Init.ChipSelectBoundary = 0;
 hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
 if (HAL_OSPI_Init(&hospi1) != HAL_OK)
 {
 Error_Handler();
 }
 OSPIM_Cfg_Struct.ClkPort = 1;
 OSPIM_Cfg_Struct.NCSPort = 1;
 OSPIM_Cfg_Struct.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
 if (HAL_OSPIM_Config(&hospi1, &OSPIM_Cfg_Struct, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 Error_Handler();
 }
 
}
 
 
/* OCTOSPI2 init function */
/* OCTOSPI2 init function */
void MX_OCTOSPI2_Init(void)
{
 OSPIM_CfgTypeDef OSPIM_Cfg_Struct = {0};
 
 hospi2.Instance = OCTOSPI2;
 hospi2.Init.FifoThreshold = 4;
 hospi2.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
 hospi2.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
 hospi2.Init.DeviceSize = 25;
 hospi2.Init.ChipSelectHighTime = 2;
 hospi2.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
 hospi2.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
 hospi2.Init.ClockPrescaler = 1;
 hospi2.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
 hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
 hospi2.Init.ChipSelectBoundary = 0;
 hospi2.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
 if (HAL_OSPI_Init(&hospi2) != HAL_OK)
 {
 Error_Handler();
 }
// OSPIM_Cfg_Struct.ClkPort = 2;
// OSPIM_Cfg_Struct.IOLowPort = HAL_OSPIM_IOPORT_2_LOW;
// if (HAL_OSPIM_Config(&hospi2, &OSPIM_Cfg_Struct, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
// {
// Error_Handler();
// }
 
}
 
int main()
{
	(...)
 
	MX_OCTOSPI2_Init();
	MX_OCTOSPI1_Init();
	(...)
}
 

I am configuring the project from CubeMx 6.0.1. OctoSPI2 CS pin is disabled. I control the cs pin with software. It seems that disabling the CS pin in the HAL_OSPIM_Config function is not taken into account. Is there a problem with the HAL_OSPIM_Config function? Or are we making a mistake somewhere?

0693W00000QNAv7QAH.png 

Best regards.

Sam A
Associate
April 12, 2023

I am using Cube FW 1.10.1 and seeing the same issue when using both OSPI1 and OSPI2.

  1. It looks like the issue is with HAL_OSPIM_Config() as others pointed out.
  2. when port 2 gets init after port 1 then port 2 doesn't work until you re-init port 2 separately by just calling HAL_OSPIM_Config() with appropriate port 2 handle and now if you want to write to port 1, you have to do same thing by just calling HAL_OSPIM_Config() with appropriate port 1 handle and its parameters. just before every write cycle.
  3. When using both the ports at the same time, its very time consuming calling HAL_OSPIM_Config() everytime you switch ports in real time - as this function takes tenths of microseconds which is very crucial for our application as it introduces additional delay every time.
  4. Is there a fix for this yet ? - 4/12/2023
  5. As a work around for now I am following one of the above posted temp solution to init port 2 first and 1 later and then commenting the HAL_OSPIM_Config for port 2 - seems to work fine but not sure if that is reliable enough ?

Thanks. Any other inputs on this ?