Search code examples
cstm32wakeupstandbystm32ldiscovery

Not working standby mode in the stm32l100


I'm tuning stm32l100 for a STANDBY mode. The MCU should woke up 2 times per second. For this I use RTC wakeup timer. But after how MCU has entered to the STANDBY mode it immediately wakes up.

If instead the STANDBY mode I use a simple sleep-mode (__WFI) all works fine.

My code is here

  1. After the MCU is starting

    a. saves flags CSR_SBF and CSR_WUF, after that clears them.

    if (PWR->CSR & PWR_CSR_SBF_BIT) {
       // ...
    }
    
    if (PWR->CSR & PWR_CSR_WUF_BIT) {
        // ...
    }
    
    PWR->CR |= PWR_CR_CSBF_BIT|PWR_CR_CWUF_BIT;
    
    //while (PWR->CSR & PWR_CSR_SBF_BIT);
    while (PWR->CSR & PWR_CSR_WUF_BIT);
    

    I noted that CSR_SBF never clears. If I uncomment string with while then MCU stall on it place. I don't understand why.

    b. saves reset source flags, after that clears them.

    volatile uint32_t csr;
    csr = RCC->CSR;
    
    // .... saving
    
    // clear flags
    RCC->CSR |= RCC_CSR_RMVF_BIT;
    

    After how MCU woke up from the STANDBY all reset source flags are cleared. It seems how reset sources are absent but code execute from 0x0.

  2. Tuning RTC wakeup-timer

    void rtc_set_wakeup_mode(const uint32_t wakeup_counter)
    {
        RTC_WRITE_PROTECT_DISABLE();
        RTC->CR &= ~RTC_CR_WUTE_BIT;
        while (!(RTC->ISR & RTC_ISR_WUTWF_BIT));
    
        RTC->WUTR = wakeup_counter;
        RTC->CR &= 0xfffffff7;
        RTC->CR |= RTC_WAKEUPCLOCK_RTCCLK_DIV2;
    
        __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
        __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_RISING_EDGE();
    
        RTC->CR |= RTC_CR_WUTIE_BIT|RTC_CR_WUTE_BIT;
        RTC_WRITE_PROTECT_ENABLE();
    }
    
  3. Enter in the STANDBY mode

    void pwdm_enter_standby_mode(void)
    {
        PWR->CR |= PWR_CR_PDDS_BIT;
        SCB->SCR |= SCB_SCR_SLEEPDEEP_BIT;
    
        __WFI();
    }
    

Solution

  • So, finally I got it.

    It was my own fail with startup initialization. The key was in this:

    I noted that CSR_SBF never clears. If I uncomment string with while then MCU stall on it place. I don't understand why.

    I placed the code working with wakeup/standby flags at the begining of main. But this code didn't do this operation __HAL_RCC_PWR_CLK_ENABLE(); because that operation will executed in a oscill initialization routine. So, the PWR->CSR was in undefined state and the PWR_CSR_WUF flag is never clearing.