cancel
Showing results for 
Search instead for 
Did you mean: 

RTC Wakeup doesn't after sleep

vneff
Associate II
Posted on October 15, 2014 at 19:38

I'm trying to wakeup the processor after it has been put to sleep by the _wfe instruction via the RTC wakeup event.

It is not working for me. There are no examples of WFE wakeup in the library projects that I can find. The processor does wake up if I type a character as the UART Rx interrupt is still enabled and it wakes up on CAN activity. Here is my sleep procedure, you will notice that there are a couple of FreeRTOS associated calls:

start_wakeup_timer( 60 ); // 1 minutes for testing purposes
CAN_OperatingModeRequest( CAN1, CAN_OperatingMode_Sleep );
CAN_Sleep( CAN1 );
disable_system_timer(); // shutdown the high speed tick
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
__asm volatile( ''cpsid i'' );
SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
__asm volatile( ''dsb'' );
__asm volatile( ''sev'' );
__asm volatile( ''wfe'' );
__asm volatile( ''wfe'' );
__asm volatile( ''isb'' );
SCB->SCR &= ~SCB_SCR_SEVONPEND_Msk;
/* Re-enable interrupts. */
__asm volatile( ''cpsie i'' );
/* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;

void start_wakeup_timer( uint16_t wakeup_seconds )
{
RTC_WakeUpCmd( DISABLE );
RTC_SetWakeUpCounter( wakeup_seconds );
RTC_ClearITPendingBit( RTC_IT_WUT );
RTC_ITConfig( RTC_IT_WUT, ENABLE );
RTC_WakeUpCmd( ENABLE );
RTC_ClearFlag( RTC_FLAG_WUTF );
}

RTC_powerup is called during the reset procedure

bool RTC_Config(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
RCC_BackupResetCmd( ENABLE );
RCC_BackupResetCmd( DISABLE );
PWR_BackupAccessCmd(ENABLE);
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
return RTC_WaitForSynchro();
}
void RTC_powerup( void )
{
RTC_InitTypeDef RTC_InitStructure;
RTC_DateTimeTypeDef dateTime;
RTC_Config();
RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
RTC_InitStructure.RTC_SynchPrediv = 0xFF;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure;
set_date_time( &dateTime, false );
RTC_WakeUpCmd( DISABLE );
RTC_WakeUpClockConfig( RTC_WakeUpClock_CK_SPRE_16bits );
}

What am I missing? Thanks, Vance #sleep #timer #stm32 #rtc #wfe #wakeup
5 REPLIES 5
chen
Associate II
Posted on October 16, 2014 at 10:17

Hi

There are a number of thing to look at :

Battery Backup  domain

External OSC for RTC

RTC IRQ

I believe that the RTC will not work in any of the Low Power modes unless it is being clocked from an external OSC, that is what I have read others saying here in the forum.

(my project does not use the RTC so I have not used it myself)

The RTC may also not work is the 'Battery Backup Domain' is not enabled.

Check that the RTC is generating an IRQ. Disable the sleep mode, and put a break point in the RTC ISR then execute and see if you hit the break point.

The fact that any IRQ wakes it up means that WFE is working, just that the RTC is not generating an IRQ.

vneff
Associate II
Posted on October 16, 2014 at 22:14

Thanks for the reply!

I assume the WFE is working because both CAN activity and USART Rx wakes up the processor.

I know that the the RTC is running because it kept track of time during the period the processor was asleep.  Presumable, it is clocked by the same clock (ck_spre) that I selected as the input to the wakeup timer.

BUT, the wakeup timer does not seem to be running.  Even while the processor is not sleeping.

I started it and checked the counter value and after 5 seconds. No change, just the value I had set it to.

Vance

chen
Associate II
Posted on October 17, 2014 at 10:43

''I know that the the RTC is running because it kept track of time during the period the processor was asleep''

Good.

''BUT, the wakeup timer does not seem to be running.  Even while the processor is not sleeping.''

That will be your problem. Review the STM32F4 reference manual with regards to the alarm section of the RTC.

Also review the IRQ register of the RTC and the NVIC registers for the RTC.

Basically, the RTC alarm IRQ is not working for you.

vneff
Associate II
Posted on October 17, 2014 at 22:20

Chen_chung,

Thanks again for giving some of your time for my issue. Oops, The wakeup timer is running. I thought I could read the current state of the timer; but turns out that all I can read is the reload value. Incidentally, I'm using a STM32F215, not that it should matter. Anyway, I did verify the the WUTF flag does get set, at least while the processor is running. I am under the impression that I should not have to enable the NVIC for the wakeup to work, just the wakeup timer's IRQ and the timer of course. But, I did try enabling the NVIC for the wakeup timer as well, with no improvement. And, the interrupt does not seem to be working. It never calls the IRQ handler. Just to be sure we are on the same page, here is the procedure that I am using to start the timer (my last attempt):

void start_wakeup_timer( uint16_t wakeup_seconds )
{
/* disable the wake-up, need to be disabled to set wake-up time */
if (RTC_WakeUpCmd( DISABLE ) != SUCCESS)
{
log_printf( LPF_always, ''NV: could not disable Wakeup
'' );
}
/* configure wake-up clock source = ck_spre usually 1 Hz */
RTC_WakeUpClockConfig( RTC_WakeUpClock_CK_SPRE_16bits );
/* configure the wake-up time in seconds (max 2 hours) */
RTC_SetWakeUpCounter( wakeup_seconds );
/* Enable the Wakeup Interrupt */
RTC_ITConfig( RTC_IT_WUT, ENABLE );
/* CLear WakeUp interrupt pending bit */
RTC_ClearITPendingBit( RTC_IT_WUT );
/* Clear WakeUp (WUTF) pending flag */
RTC_ClearFlag( RTC_FLAG_WUTF );
/* Clear Wakeup flag */
PWR->CR |= PWR_CR_CWUF;
/* enable the wake-up timer */
if (RTC_WakeUpCmd( ENABLE ) != SUCCESS)
{
log_printf( LPF_always, ''NV: could not enable Wakeup
'' );
}
log_printf( LPF_always, ''NV: started wakeup timer
'' );
}

The NVIC for the wakeup timer is configured in the RTC configuration with priorities of 0. I called the start_wakeup_timer with an argument of 10 seconds. The interrupt routine should be displaying something every 10 seconds.

void RTC_WKUP_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_WUT) != RESET)
{
//RTC_ITConfig( RTC_IT_WUT, DISABLE );
RTC_ClearITPendingBit(RTC_IT_WUT);
RTC_ClearFlag( RTC_FLAG_WUTF );
UTILITY_send_byte_from_isr( 'X' );
UTILITY_send_string_from_isr( ''WUTF
'' );
}
}

Any ideas would be greatly appreciated! Vance
chen
Associate II
Posted on October 20, 2014 at 10:34

Hi

''I am under the impression that I should not have to enable the NVIC for the wakeup to work, just the wakeup timer's IRQ and the timer of course.''

No, both the NVIC and the peripheral need to be set up correctly for peripheral IRQs to work correctly.

''And, the interrupt does not seem to be working.  It never calls the IRQ handler.''

This is your problem.

Forget the low power mode for now, get the IRQ/ISR working.

Once this is working, you should find the wake up should work.

For the RTC period timeout (if there is one, I have not checked)

the RTC period timer need to be enabled

the NVIC need to be enabled

the IRQ for the RTC Period Timer in the NVIC need to be configured.