RTC interrupt doesn't happen

I’m trying to get the RTC to interrupt every second, so the interrupt source will set a flag to true and clear the interrupt flag. Unfortunately, the interrupt never happens. Can you see what I’m doing wrong?

  1. The 32.768 KHz crystal clock is enabled.
	ACS->XTAL32K_CTRL = XTAL32K_ENABLE;
	// Wait for XTAL32K oscillator to be ready
	while (ACS_XTAL32K_CTRL->READY_ALIAS != XTAL32K_OK_BITBAND);
	ACS->AOUT_CTRL = AOUT_VSSA | AOUT_XTAL_CLK;
  1. The clock is set as the source for the RTC, which has a reload value of 0x7fff (for a 1 second period).
	Sys_RTC_Config(0x7FFF, RTC_ENABLE | RTC_CLK_SRC_XTAL32K | RTC_RESET);
	Sys_RTC_Start(RTC_ENABLE_BITBAND);
  1. I enable the RTC_ALARM_ZERO interrupt.
	ACS->RTC_CTRL = ACS->RTC_CTRL | RTC_ALARM_ZERO;

    NVIC_ClearPendingIRQ(RTC_ALARM_IRQn);
    NVIC_EnableIRQ(RTC_ALARM_IRQn);
  1. The interrupt routine, RTC_ALARM_IRQHandler, sets a boolean flag to true.
void RTC_ALARM_IRQHandler(void) {
	g_alarmFlag = true;
}
  1. This flag is acted upon in the main loop and cleared there, ready for another round.
while(1) {
    BDK_Schedule();

    if (g_alarmFlag) {
        printf("ALARM\n");
        g_alarmFlag = false;
    }
}

Hi @ken1 ,
I think the issue is that you need clear RTC_ALARM wakeup flag in RTC_ALARM_IRQHandler().

void RTC_ALARM_IRQHandler(void) {
  ACS_WAKEUP_CTRL->RTC_ALARM_WAKEUP_CLEAR_ALIAS=WAKEUP_RTC_ALARM_CLEAR_BITBAND;
  g_alarmFlag = true;
}

This doesn’t fix the problem. Right now I’m not using any low power mode, so the RSL10 SIP doesn’t need to wake up. It’s always running, and I just need the interrupt to happen, but it doesn’t. I’ve checked and verified that the 32.768 Khz crystal clock is working and is the source for the RTC, and that the RTC repeatedly counts down from ox7fff to 0 once every second, by using polling (not interrupts). So then I enable the interrupt and I expect that once per second the interrupt service routine would run, but it doesn’t. Is there another level of interrupt enabling that I need to do? Is there an interrupt pending flag that I need to unmask, or clear? Is my code (see above) actually enabling the RTC_ALARM_ZERO interrupt on the RTC_ALARM_IRQn?

Hi @ken1 ,
I guess your might need clear the RTC_ALARM_CLEAR flag at initialization first.

void Initialize(void){

/* Configure RTC */
ACS->RTC_CFG = RTC_CNT_START_VALUE;

*((volatile uint8_t *) &ACS->RTC_CTRL) = (uint8_t)(RTC_CLK_SRC_XTAL32K |
                                                       RTC_ALARM_ZERO);

/* Reset and enable RTC */
ACS_RTC_CTRL->RESET_ALIAS = RTC_RESET_BITBAND;
ACS_RTC_CTRL->ENABLE_ALIAS = RTC_ENABLE_BITBAND;

/* - Enable XTAL32K oscillator amplitude control
 * - Set XTAL32K load capacitance
 * - Enable XTAL32K oscillator */
ACS->XTAL32K_CTRL = \
	(XTAL32K_XIN_CAP_BYPASS_DISABLE                                |
	 XTAL32K_AMPL_CTRL_ENABLE                                      |
	 XTAL32K_NOT_FORCE_READY                                       |
	 (XTAL32K_CLOAD_TRIM_VALUE << 8) |
	 (XTAL32K_ITRIM_VALUE << 4)           |
	 XTAL32K_IBOOST_DISABLE                                        |
	 XTAL32K_ENABLE);

/* Wait for XTAL32K oscillator to be ready */
while (ACS_XTAL32K_CTRL->READY_ALIAS != XTAL32K_OK_BITBAND);
// Clear the ALARM flag
ACS_WAKEUP_CTRL->RTC_ALARM_WAKEUP_CLEAR_ALIAS=WAKEUP_RTC_ALARM_CLEAR_BITBAND;
NVIC_ClearPendingIRQ(RTC_ALARM_IRQn);
NVIC_EnableIRQ(RTC_ALARM_IRQn);


}

void RTC_ALARM_IRQHandler(void)
{
ACS_WAKEUP_CTRL->RTC_ALARM_WAKEUP_CLEAR_ALIAS=WAKEUP_RTC_ALARM_CLEAR_BITBAND;
timestamp = Sys_RTC_Value();
Sys_GPIO_Toggle(LED_DIO);
}

1 Like

Hi @larry.zhu

Clearing the RTC_ALARM_CLEAR flag at initialization solved the problem. Here’s the setup code:

    ACS->XTAL32K_CTRL = XTAL32K_ENABLE;
	
    while (ACS_XTAL32K_CTRL->READY_ALIAS != XTAL32K_OK_BITBAND);
    ACS->AOUT_CTRL = AOUT_VSSA | AOUT_XTAL_CLK;
	
    Sys_RTC_Config(0x7FFF, RTC_ENABLE | RTC_CLK_SRC_XTAL32K | RTC_RESET);
    Sys_RTC_Start(RTC_ENABLE_BITBAND);
    ACS->RTC_CTRL = ACS->RTC_CTRL | RTC_ALARM_ZERO;
    ACS_WAKEUP_CTRL->RTC_ALARM_WAKEUP_CLEAR_ALIAS = WAKEUP_RTC_ALARM_CLEAR_BITBAND;
    NVIC_ClearPendingIRQ(RTC_ALARM_IRQn);
    NVIC_EnableIRQ(RTC_ALARM_IRQn);

And here’s the IRQHandler code:

void RTC_ALARM_IRQHandler(void) {
    ACS_WAKEUP_CTRL->RTC_ALARM_WAKEUP_CLEAR_ALIAS = WAKEUP_RTC_ALARM_CLEAR_BITBAND;
    g_alarmFlag = true;
}

Thanks for your help!

1 Like

I have one further question about this. What should I add to this code to put the chip into standby mode between alarm interrupts? I’ve looked at the peripheral server standby example, but it seems more complicated than necessary.

Hi @ken1,
peripheral_server_standby sample code uses WAKEUP_IRQHandler for sleep wake up.
You could add code into there to judge if this wakeup comes from RTC_ALARM.
For example:
/* Call RTC_ALARM Handler to process wakeup event */
if(ACS->WAKEUP_CTRL & WAKEUP_RTC_ALARM_EVENT_SET)
{
ACS_WAKEUP_CTRL->RTC_ALARM_WAKEUP_CLEAR_ALIAS = WAKEUP_RTC_ALARM_CLEAR_BITBAND;
……
}

1 Like