Skip to main content
CCHAU.2
Associate
May 5, 2023
Question

STM8 low power wait mode HSIRDY never unset we are trying tio put the micro in low power wait mode. But the software stops at : while((CLK->ICKCR & CLK_ICKCR_HSIRDY) == CLK_ICKCR_HSIRDY); see file drv_sleep

  • May 5, 2023
  • 3 replies
  • 3007 views
    This topic has been closed for replies.

    3 replies

    AA1
    Senior III
    May 5, 2023

    I didn't see your code, but it seems you are trying to stop current system clock. If this is the case, you can't.

    CCHAU.2
    CCHAU.2Author
    Associate
    May 5, 2023

    here is the code :

    /* Put system in low power wait mode until next round of test */

    #include "Micro_hw_defs.h" //Micro-specific HW configuration

    #include "stm8l15x_clk.h"

    #include "stm8l15x_flash.h"

    //Sleep until woken up by an event

    //Can't call non-RAM functions! Only FLASH_PowerRunModeConfig() is certified for that

    IN_RAM(void sleep(void))

    {

     //1 - Enter Low Power Run Mode

     //Be in RAM, done by the prototype modifier

    #ifdef TEST_WITHOUT_MOTHERBOARD

     //Switch clock to LSI

     CLK->CKDIVR = (uint8_t)CLK_SYSCLKDiv_1;

     CLK->SWR = (uint8_t)CLK_SYSCLKSource_LSI;

     while(CLK->SCSR != CLK_SYSCLKSource_LSI);

    #else

     //Switch clock to LSE

     CLK->CKDIVR = (uint8_t)CLK_SYSCLKDiv_1;

     CLK->SWR = (uint8_t)CLK_SYSCLKSource_LSE;

     while(CLK->SCSR != CLK_SYSCLKSource_LSE);

    #endif

     //Switch off peripherals

     SPI1->CR1 &= (uint8_t)(~SPI_CR1_SPE); //the other drivers are already off when not used

     CLK->PCKENR1 = 0x00;

     CLK->PCKENR2 = 0x00;

     //Switch off HSI

     CLK->ICKCR &= (uint8_t)(~CLK_ICKCR_HSION);

     while((CLK->ICKCR & CLK_ICKCR_HSIRDY) == CLK_ICKCR_HSIRDY); //don't know why it doesn't fall

     //Mask all interrupts

     disableInterrupts();

     //Switch off flash

     FLASH_PowerRunModeConfig(FLASH_Power_IDDQ);

     while((CLK->REGCSR & CLK_REGCSR_EEREADY) == CLK_REGCSR_EEREADY);

     //Configure regulator ultra-low power mode

     CLK->REGCSR |= CLK_REGCSR_REGOFF;

     while((CLK->REGCSR & CLK_REGCSR_REGREADY) == CLK_REGCSR_REGREADY);

     //2 - Enter (and leave on event) Low Power Wait Mode

     wfe();

     //Clear RTC Wake Up Event

     RTC->ISR2 = 0; //We don't use the other bits

     //3 - Exit Low Power Run Mode

     //Switch on main regulator

     CLK->REGCSR &= (uint8_t)(~CLK_REGCSR_REGOFF);

     while((CLK->REGCSR & CLK_REGCSR_REGREADY) == 0);

     //Switch on flash

     FLASH_PowerRunModeConfig(FLASH_Power_On);

     while((CLK->REGCSR & CLK_REGCSR_EEREADY) == 0);

     //Switch on HSI

     CLK->ICKCR |= CLK_ICKCR_HSION;

     while((CLK->ICKCR & CLK_ICKCR_HSIRDY) == 0);

     //Switch clock to HSI

     CLK->CKDIVR = (uint8_t)CLK_SYSCLKDiv_2;

     CLK->SWR = (uint8_t)CLK_SYSCLKSource_HSI;

     while(CLK->SCSR != CLK_SYSCLKSource_HSI);

     //reset interrupt mask

     enableInterrupts();

     //switch on peripherals

     SPI1->CR1 |= SPI_CR1_SPE;

     CLK->PCKENR1 = CLK_GATING_REG1;

     CLK->PCKENR2 = 0x04; //RTC

    }

    in the datasheet to enter low power run mode you must disable high speed oscillator

    AA1
    Senior III
    May 5, 2023

    You are not following the instructions to switch clock, see RM0031 pages 93 and 94. CLK_SWCR is not used in you code. It seems current system clock is still HSI.

    CCHAU.2
    CCHAU.2Author
    Associate
    May 5, 2023

    SWEN is lset to 1 before this function

    SWEN==1

    SWR=LSI

    check SCSR == LSI

    and in the register SCSR == LSI

    so we are using the LSI clock