2024-12-02 2:12 AM - edited 2024-12-02 12:36 PM
Issue
Higher ambient temperatures cause communication malfunctions with XSPI memories.
Details
Our design is heavily adopted from STM32H7S78-DK which also has the same issue described below.
The application uses memory-mapped mode for both Flash and RAM as the main operational units. These memories are configured in the bootloader and everything generated using CubeMX. According to the datasheets, all three components (CPU, Flash, and RAM) are specified to operate reliably under the given conditions, and they do function correctly under normal temperatures.
The problem arises when the ambient temperature increases from 25°C to 60°C. These temperatures are within the acceptable operating range for all components, as stated in their specifications. Upon reaching higher temperatures, the memories start to exhibit failures. However, further investigation revealed that the issue is not with the memories themselves. When the memories alone are heated, they continue to operate reliably, even at elevated temperatures.
The issue was traced to the CPU. When the CPU is heated, the failures begin around 55°C. At this point, the CPU starts to malfunction in its communication with the memories. This leads to the CPU entering an undefined state, with fault reports showing inconsistent and varying results.
Lowering the temperature restores normal operation.
Investigations
Specifications
CPU - STM32H7S7L8H6H
XSPI1 - APS256XXN-OBR-BG
XSPI2 - MX25UW6345GXDI00
STM32CubeMX ver 6.13.0
STM32CubeMX package STM32H7RS v 1.1.0
VCC 3.3V
XSPI1 & XSPI2 1.8V
CPUCPLK 600MHz
HCLK 300MHz
XSPI1 & XSPI2 176MHz with no prescaler
ZIP
schematics, layouts, scatter file, mxcube configs & clocks, option bytes
Solved! Go to Solution.
2026-02-12 2:06 PM
Hello everyone
Two question : @Schwarzbach Can you kindly share the code that fix the issue. I plan to realese a product with thip chip and it is not clear to understand how the workaroud "works".
@STOne-32 Do you plan to realese a knowledge base / exemple for this feature and the errata since it can be a big issue for the H7S7L8.
Thanks everyone
2026-02-12 11:18 PM
@Schwarzbach We are still in the process of evaluating. The differences with a one time calibration on our first series of boards are small, so we are looking at a fixed solution. This especially because the work-around suggests to increase the values found troughs calibration are increase with 2 in both directions.
We will retest with a different series to see how consistent they are. Preferably we use fixed values to save the hassle in production to store the actual values and avoid the risk the auto calibration goes off track due to another problem on the board which is then stored and used after the board is repaired. These things are hard to control.
We will also create multiple products with the STM32H7S3 and are watching if we see difference per layout. We do strive to keep layout on all products mostly identical.
@STOne-32 We assume if you increase/decrease the number referenced to 8 you increase rise/fall time. Is this the right assumption? The most important thing to control is keeping the clock symmetrical because of the DTR access.
2026-02-13 12:13 AM
@Hamady I also do not have a final solution for this. I think we are waiting for am waiting for @STOne-32 to provide an official statement like a knowledge base / example how to treat the issue.
Up to now, we achieve quite good results by disabling the SBS HSLV code generation in CubeMX and adding the following user code:
/* Configure the compensation cell */
HAL_SBS_ConfigCompensationCell(SBS_IO_XSPI1_CELL, SBS_IO_CELL_CODE, 0U, 0U);
HAL_SBS_ConfigCompensationCell(SBS_IO_XSPI2_CELL, SBS_IO_CELL_CODE, 0U, 0U);
/* Enable compensation cell */
HAL_SBS_EnableCompensationCell(SBS_IO_XSPI1_CELL);
HAL_SBS_EnableCompensationCell(SBS_IO_XSPI2_CELL);
/* wait ready before enabled IO */
while(HAL_SBS_GetCompensationCellReadyStatus(SBS_IO_XSPI1_CELL_READY) != 1U);
while(HAL_SBS_GetCompensationCellReadyStatus(SBS_IO_XSPI2_CELL_READY) != 1U);
uint32_t code1, code2, nmos1, nmos2, pmos1, pmos2;
HAL_SBS_GetCompensationCell(SBS_IO_XSPI1_CELL, &code1, &nmos1, &pmos1);
HAL_SBS_GetCompensationCell(SBS_IO_XSPI2_CELL, &code2, &nmos2, &pmos2);
HAL_SBS_ConfigCompensationCell(SBS_IO_XSPI1_CELL, SBS_IO_REGISTER_CODE, nmos1, pmos1);
HAL_SBS_ConfigCompensationCell(SBS_IO_XSPI2_CELL, SBS_IO_REGISTER_CODE, nmos2, pmos2);
HAL_SBS_DisableCompensationCell(SBS_IO_XSPI1_CELL);
HAL_SBS_DisableCompensationCell(SBS_IO_XSPI2_CELL);
/* high speed low voltage config */
HAL_SBS_EnableIOSpeedOptimize(SBS_IO_XSPI1_HSLV);
HAL_SBS_EnableIOSpeedOptimize(SBS_IO_XSPI2_HSLV);
@taste We did not increase/decrease the values by 2 yet, as also described in the errata - STM32H7Rxx/7Sxx device errata - Errata sheet.
That would be the next step to test.
2026-03-03 1:55 AM
Hi @Schwarzbach
I Had good result with the code below.
If i disable the compensation cell I have random hardfault but now everything run perfectly
#define NMOS_ADJ +2
#define PMOS_ADJ -2
// Macro générique pour ajuster une valeur et la clamp sur une plage [0, 15]
#define ADJUST_AND_CLAMP(val, adj) ( ((int32_t)(val) + (adj) < 0) ? 0 : \
(((int32_t)(val) + (adj) > 15) ? 15 : ((int32_t)(val) + (adj))) )
void configure_XPSI(){
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
__HAL_RCC_SBS_CLK_ENABLE();
/* System interrupt init*/
/* Enable the XSPIM_P1 interface */
HAL_PWREx_EnableXSPIM1();
/* Enable the XSPIM_P2 interface */
HAL_PWREx_EnableXSPIM2();
/* The CSI is used by the compensation cells and must be enabled before enabling the
compensation cells.
For more details refer to RM0477 [SBS I/O compensation cell management] chapter.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_CSI;
RCC_OscInitStruct.CSIState = RCC_CSI_ON;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Configure the compensation cell */
HAL_SBS_ConfigCompensationCell(SBS_IO_XSPI1_CELL, SBS_IO_CELL_CODE, 0U, 0U);
HAL_SBS_ConfigCompensationCell(SBS_IO_XSPI2_CELL, SBS_IO_CELL_CODE, 0U, 0U);
/* Enable compensation cell */
HAL_SBS_EnableCompensationCell(SBS_IO_XSPI1_CELL);
HAL_SBS_EnableCompensationCell(SBS_IO_XSPI2_CELL);
/* wait ready before enabled IO */
while(HAL_SBS_GetCompensationCellReadyStatus(SBS_IO_XSPI1_CELL_READY) != 1U);
while(HAL_SBS_GetCompensationCellReadyStatus(SBS_IO_XSPI2_CELL_READY) != 1U);
uint32_t code1, code2, nmos1, nmos2, pmos1, pmos2;
HAL_SBS_GetCompensationCell(SBS_IO_XSPI1_CELL, &code1, &nmos1, &pmos1);
HAL_SBS_GetCompensationCell(SBS_IO_XSPI2_CELL, &code2, &nmos2, &pmos2);
// Appliquer ajustement + clamp
nmos1 = ADJUST_AND_CLAMP(nmos1, NMOS_ADJ);
nmos2 = ADJUST_AND_CLAMP(nmos2, NMOS_ADJ);
pmos1 = ADJUST_AND_CLAMP(pmos1, PMOS_ADJ);
pmos2 = ADJUST_AND_CLAMP(pmos2, PMOS_ADJ);
HAL_SBS_ConfigCompensationCell(SBS_IO_XSPI1_CELL, SBS_IO_REGISTER_CODE, nmos1, pmos1);
HAL_SBS_ConfigCompensationCell(SBS_IO_XSPI2_CELL, SBS_IO_REGISTER_CODE, nmos2, pmos2);
/* high speed low voltage config */
HAL_SBS_EnableIOSpeedOptimize(SBS_IO_XSPI1_HSLV);
HAL_SBS_EnableIOSpeedOptimize(SBS_IO_XSPI2_HSLV);
}