cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB SRAM2

lizerd
Associate III

So once again I have a problem with the STM32WB , I have spent alot of time with the L4 series, and always used the SRAM2 retention in standby function without any problem.

And the WB series should be based on the L4, so I had hope for an easy migration.

But no.

So how do I enable the SRAM2 retention in standby ??

All the datasheets tells the story that it it possible.

SRAM2a: 32 Kbytes located at address 0x2003 0000 also mirrored at 0x1000 0000,
with hardware parity check (this SRAM can be retained in Standby mode)

And from the header of stm32wbxx_hal_pwr.c

   *** Standby mode ***
   ====================
    [..] The Standby mode offers two options: 
      (+) option a) all clocks off except LSI and LSE, RRS bit set (keeps voltage regulator in low power mode).
          SRAM and registers contents are lost except for the SRAM2 content, the RTC registers, RTC backup registers 
          and Standby circuitry.      
      (+) option b) all clocks off except LSI and LSE, RRS bit cleared (voltage regulator then disabled).
          SRAM and register contents are lost except for the RTC registers, RTC backup registers 
          and Standby circuitry.
 
      (++) Entry:
          (+++) The Standby mode is entered thru HAL_PWR_EnterSTANDBYMode() API. 
                SRAM1 and register contents are lost except for registers in the Backup domain and 
                Standby circuitry. SRAM2 content can be preserved if the bit RRS is set in PWR_CR3 register. 
                To enable this feature, the user can resort to HAL_PWREx_EnableBKRAMContentRetention() API
                to set RRS bit.

It tells that I must use HAL_PWREx_EnableBKRAMContentRetention() to enable the SRAM2 retention in stanby.

But there is NO function that is named HAL_PWREx_EnableBKRAMContentRetention()

But there is a function that is named HAL_PWREx_EnableSRAMRetention() as in the L4 series.

That calls LL_PWR_EnableSRAM2Retention()

/**
  * @brief  Enable SRAM2a content retention in Standby mode
  */
__STATIC_INLINE void LL_PWR_EnableSRAM2Retention(void)
{
  SET_BIT(PWR->CR3, PWR_CR3_RRS);
}

But in the function call

/**
  * @brief Enter Standby mode.
  * @note  In Standby mode, the PLL, the HSI, the MSI and the HSE oscillators are switched 
  *        off. The voltage regulator is disabled, except when BKRAM content is preserved
  *        in which case the regulator is in low-power mode.
  *        SRAM and register contents are lost except for registers in the Backup domain and
  *        Standby circuitry. BKRAM content can be preserved if the bit RRS is set in PWR_CR3 
  */
void HAL_PWR_EnterSTANDBYMode(void)

It tells that the SRAM is lost and the BKRAM can be saved.

But I guess that BKRAM text should be replaced with SRAM2

But still I can not get it to work.

Have anyone got this to work ?

3 REPLIES 3
lizerd
Associate III

I made a clean example from the example project PWR_STANDBY_RTC

volatile uint32_t Counter __attribute__((section("MB_MEM2")));
 
 
int main(void)
{
 
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	uint8_t i  = 0;
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
  LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
  /* Initialize all configured peripherals */
  MX_RTC_Init();
  MX_GPIO_Init();
  /* Check if the system was resumed from StandBy mode */
  /* Note: On STM32WB, both CPU1 and CPU2 must be in standby mode to set the entire system in standby mode */
  if(   (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
     && (__HAL_PWR_GET_FLAG(PWR_FLAG_C2SB) != RESET)
    )
  {
    /* Clear Standby flag */
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB); 
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_C2SB);
  }
  
  
 
  // set working n of blinks
  if((Counter < 1) || (Counter > 10))
  {
	  Counter = 1;
  }
 
 
	// Blink LED
  __HAL_RCC_GPIOH_CLK_ENABLE();
	GPIO_InitStruct.Pin = GPIO_PIN_3;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
 
	for(i=0;i < Counter; i++)
	{
		HAL_GPIO_WritePin(GPIOH, GPIO_PIN_3, GPIO_PIN_SET);
		HAL_Delay(100);
		HAL_GPIO_WritePin(GPIOH, GPIO_PIN_3, GPIO_PIN_RESET);
		HAL_Delay(100);
	}
 
	// Increase counter
	Counter++;
 
 
	
 
  /* Disable all used wakeup sources*/
  HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
  
  /* Clear all related wakeup flags */
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
  
  /* Re-enable wakeup source */
  /* ## Setting the Wake up time 
    Set wakeup time to 2seconds */
  HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 4000, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
  
  if(   (LL_PWR_IsActiveFlag_C1SB() == 0)
     || (LL_PWR_IsActiveFlag_C2SB() == 0)
    )
  {
    /* Set the lowest low-power mode for CPU2: shutdown mode */
    LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
  }
 
  HAL_PWREx_EnableSRAMRetention();
  /* Enter the Standby mode */
  HAL_PWR_EnterSTANDBYMode();
  
  /* Program should never reach this point (program restart when exiting from standby mode) */
  Error_Handler(); 
 
  while (1)
  {
  }
}

And it do not preserve the Counter value !!

If I check the Counter address, I can see that it is within the SRAM2A

0693W00000GWSCrQAP.png

lizerd
Associate III

Okay this is wired..

I have been adding this to my linker script, always been and it has worked for all STM32L4 variants I have used before.

Adding RAM2 (here I have been testing the mirror address of the SRAM2A)

MEMORY
{
FLASH (rx)                 : ORIGIN = 0x08000000, LENGTH = 512K
RAM1 (xrw)                 : ORIGIN = 0x20000008, LENGTH = 0x2FFF8
RAM_SHARED (xrw)           : ORIGIN = 0x20030100, LENGTH = 2K
RAM2 (xrw)   			   : ORIGIN = 0x10000000, LENGTH = 2K
}

and

  .ram2 (NOLOAD):
  {
    _sram2 = .;
    *(.ram2*)
    . = ALIGN(4);
    _eram2 = .;
  } >RAM2

and the variable

volatile uint32_t Counter __attribute__((section(".ram2")));

and it has worked.

I have played around with the RAM_SHARED and RAM2 address and length, and I found a strange thing.

I accidentally used an ref that I did remove in the linker script.

So I had static __attribute__((section(".sram2"))) uint32_t Counter;

.sram2 do not exist.

But I it worked, the led starting to increase blinking for each iteration, So the variable was preserved!!.

Checking the variable address showed in the beginning of SRAM1

0693W00000GWVEHQA5.png 

But if I changed the variable declaration to static uint32_t Counter;

then it did not work, it did not preserve the value

And the address was just a few bytes from the address when it worked !!

0693W00000GWVEvQAP.png 

And then I also tested the mirror address for SRAM2A

0693W00000GWVEgQAP.pngAnd that did not work

I am going crazy here :loudly_crying_face:

lizerd
Associate III

Here Is the files that has been changed for the PWR_STANDBY_RTC project

C:\ST_Demo\STM32Cube_FW_WB_V1.12.0\Projects\P-NUCLEO-WB55.Nucleo\Examples\PWR\PWR_STANDBY_RTC