Forum: System Workbench for STM32

Need help with RTC from LSE and exit from stop mode when SLEEPDEEP bit set

Hi,
I have STM32F103CBU6 running on HSI with RTC from LSE.
Can wake up after 2 seconds when using sleep mode (SLEEPDEEP bit is off).
But, can’t wake up when using stop mode (SLEEPDEEP bit is on).

I need some ideas how to fix it, thanks.

//
void rtc_isr(void){
bitclr(GPIOA->ODR,GPIO_ODR_ODR3); //led off
bitclr(RTC->CRL,RTC_CRL_ALRF);
bitset(EXTI->PR,EXTI_LINE_RTCALARM);
}

//use HSI default
int main(void) {

// led
//PORTA
bitset(RCC->APB2ENR,RCC_APB2ENR_IOPAEN);
//GPIOA3 push-pull 10Mhz
GPIOA->CRL= (GPIOA->CRL&(~(GPIO_CRL_CNF3_1 | GPIO_CRL_CNF3_0 |GPIO_CRL_MODE3_1))) |
(GPIO_CRL_MODE3_0);
bitset(GPIOA->ODR,GPIO_ODR_ODR3); //led on

// rtc init
RCC->APB1ENR|=(RCC_APB1ENR_BKPEN|RCC_APB1ENR_PWREN);
bitset(PWR->CR,PWR_CR_DBP);

//Enable the LSE clock
bitset(RCC->BDCR,RCC_BDCR_LSEON);
while ((RCC->BDCR&RCC_BDCR_LSERDY) == 0);

//Select LSE as the RTC clock source
if (((RCC->BDCR)&0x300)!=0x100) {
bitset(RCC->BDCR,RCC_BDCR_BDRST);
bitclr(RCC->BDCR,RCC_BDCR_BDRST);
bitset(RCC->BDCR,0x100);
}

while ((RTC->CRL&RTC_CRL_RTOFF) == 0);
bitset(RTC->CRL,RTC_CRL_CNF);

//Set the RTC prescaler value
while ((RTC->CRL&RTC_CRL_RTOFF) == 0);
RTC->PRLL=0x7fff;
while ((RTC->CRL&RTC_CRL_RTOFF) == 0);
RTC->PRLH=0x0;

//clear alarm
while ((RTC->CRL&RTC_CRL_RTOFF) == 0);
RTC->ALRH=0;
while ((RTC->CRL&RTC_CRL_RTOFF) == 0);
RTC->ALRL=0;


bitclr(RTC->CRL,RTC_CRL_CNF);
while ((RTC->CRL&RTC_CRL_RTOFF) == 0);

//Enable RTC
bitset(RCC->BDCR,RCC_BDCR_RTCEN);





// rtc alarm init
bitset(EXTI->PR,EXTI_LINE_RTCALARM);
//not masked
bitset(EXTI->IMR,EXTI_LINE_RTCALARM);
//masked
bitclr(EXTI->EMR,EXTI_LINE_RTCALARM);
//rising trigger enabled
bitset(EXTI->RTSR,EXTI_LINE_RTCALARM);
//falling trigger disabled
bitclr(EXTI->FTSR,EXTI_LINE_RTCALARM);


// Enable RTC interrupts
NVIC_SetPriority(RTC_IRQn, 0);
NVIC_EnableIRQ(RTC_IRQn);



//set alarm curtime + 2 sec
uint32_t alarmcnt=(RTC->CNTHCRL&RTC_CRL_RTOFF) == 0);
bitset(RTC->CRL,RTC_CRL_CNF);

bitclr(RTC->CRH,RTC_CRH_ALRIE);
bitclr(RTC->CRL,RTC_CRL_ALRF);

while ((RTC->CRL&RTC_CRL_RTOFF) == 0);
RTC->ALRH=alarmcnt>>16;
while ((RTC->CRL&RTC_CRL_RTOFF) == 0);
RTC->ALRL=alarmcnt&0xFFFF;

bitset(RTC->CRH,RTC_CRH_ALRIE);
bitclr(RTC->CRL,RTC_CRL_CNF);
while ((RTC->CRL&RTC_CRL_RTOFF) == 0);

// stop
PWR->CR = (PWR->CR & (~ (PWR_CR_PDDS | PWR_CR_LPDS))) | PWR_CR_CWUF;
SCB->SCR=(SCB->SCR & (~(SCB_SCR_SLEEPONEXIT_Msk | SCB_SCR_SEVONPEND_Msk))) | SCB_SCR_SLEEPDEEP_Msk;
__WFI();


Problem has solved!
You can use WFE and WFI for sleep mode (SLEEPDEEP bit is off).
You can use only WFE for stop mode (SLEEPDEEP bit is on).