Wakeup DA14531 from Deep Sleep using RTC, Clocked wakeup controller

We are using DA14531MOD with SDK 6.0.14.1114. We are using RTC alarm & clocked wakeup controller(P0_11) in deep sleep mode using below code

rtc_get_time_clndr( &time, NULL );
// Alarm interrupt in five seconds
alarm_time = time;
alarm_time.sec += 10;
rtc_set_alarm( &alarm_time, NULL, RTC_ALARM_EN_SEC );

wkupct_enable_irq(WKUPCT_PIN_SELECT(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN), // Select pin
WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, WKUPCT_PIN_POLARITY_LOW), // Polarity low
1, // 1 event
0); // debouncing time = 0

// Ensure PD_TIM is open
SetBits16(PMU_CTRL_REG, TIM_SLEEP, 0);

// Wait until PD_TIM is opened
while ((GetWord16(SYS_STAT_REG) & TIM_IS_UP) != TIM_IS_UP);

// Go to deep sleep
arch_set_deep_sleep(PD_SYS_DOWN_RAM_OFF,PD_SYS_DOWN_RAM_OFF,PD_SYS_DOWN_RAM_OFF, false );

No issue is found to Wakeup the device from above sources. We are expecting RTC date & time should not reset after wakeup from sleep.

returns always zero with GetBits16(SYS_STAT_REG, TIM_IS_UP); after wake up

Issues we are facing here
1. RTC date & time is not continuing after wake up.
2. After wakeup from sleep from any one source, How to find out from which source (either RTC alarm, clocked) the DA14531 wakeups.

Parents
  • 1, have you called this function rtc_set_keep_reg_on_reset 

    void rtc_init(const rtc_config_t *cfg)
    {
        rtc_set_hour_clk_mode(cfg->hour_clk_mode);
        // this keep_rtc should be true, when you want keep rtc registors
        rtc_set_keep_reg_on_reset(cfg->keep_rtc);
    }

    2, there is no register for wake up source, so you can distinguish the callbacks for different sources.

    DA14531 deep sleep - multiple wake up events possible? - Bluetooth Low Energy - Wireless Connectivity - Renesas Engineering Community

  • Thank you for your reply.

    We are using DA14531 SMARTBOND TINYTm MODULE Development Kit, RCX20 as low power clock and USB powered. Any coincell battery needs to be connected to module continue RTC date & time. After configure_rtc_wakeup function is called, date & time is continuing till the module went to sleep. After wakeup from sleep, TIM_IS_UP of SYS_STAT_REG is showing zero.

    Full code as given below for RTC wakeup.

    static void configure_rtc_wakeup(void)
    {
        rtc_time_t alarm_time;
    
    //    // Init RTC
    //    rtc_reset();
    	
        // Configure the RTC clock; RCX is the RTC clock source (14420 Hz)
    	if (arch_clk_is_RCX20()) {
    		extern uint32_t rcx_freq;
    		/* Use the calibrated RCX frequency */
    		rtc_clk_config(RTC_DIV_DENOM_1000, rcx_freq);
    	} else {
    		rtc_clk_config(RTC_DIV_DENOM_1024, 32768);
    	}
    
        rtc_clock_enable( );
    
        rtc_config_t cfg = {.hour_clk_mode = RTC_HOUR_MODE_24H, .keep_rtc = true};
    
        rtc_time_t time = {.hour_mode = RTC_HOUR_MODE_24H, .pm_flag = 0, .hour = 11,
                           .minute = 55, .sec = 30, .hsec = 00};
    	rtc_calendar_t date = { .year = 2000, .month =1 , .mday = 10, .wday=1 };
    	
    	rtc_get_time_clndr( &time, &date );
    //     Alarm interrupt in five seconds
        alarm_time = time;
        alarm_time.sec += 10;
        if( alarm_time.sec > 59 ) {
    		alarm_time.sec %= 60;
    		alarm_time.minute++;
    		if( alarm_time.minute > 59 ) {
    			alarm_time.minute = 0x00;
    			
    			alarm_time.hour++;
    			if( alarm_time.hour > 23 ) {
    				alarm_time.hour = 0x00;
    			}
    		}
    	}
    	
    #if defined (CFG_USER_PRINTF)
    	debug_printf( "%s\n", __FUNCTION__);
    	debug_printf( "Time %02d:%02d:%02d\n", time.hour, time.minute, time.sec );
    #endif
    
        // Initialize RTC, set time and data, register interrupt handler callback function and enable seconds interrupt
        rtc_init( &cfg );
    
        // Start RTC
        rtc_set_time_clndr(&time, &date );
        rtc_set_alarm(&alarm_time, NULL, RTC_ALARM_EN_SEC);
    
        // Clear pending interrupts
        rtc_get_event_flags();
        rtc_register_intr(rtc_interrupt_hdlr, RTC_INTR_ALRM);
    #if defined (CFG_EXT_SLEEP_WAKEUP_RTC)
        app_easy_wakeup_set(app_wakeup_cb);
    #endif
    }

  • void put_system_into_deep_sleep(void)
    {
    #if defined (CFG_DEEP_SLEEP_WAKEUP_POR)
        // Configure button for POR
        GPIO_EnablePorPin(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, GPIO_POR_PIN_POLARITY_LOW, GPIO_GetPorTime());
    #endif
    
    #if defined ( CFG_DEEP_SLEEP_WAKEUP_GPIO )
        wkupct_enable_irq( WKUPCT_PIN_SELECT( BUTTON_PORT, BUTTON_PIN ), 							// Select pin
                          WKUPCT_PIN_POLARITY( BUTTON_PORT, BUTTON_PIN, WKUPCT_PIN_POLARITY_LOW ), 	// Polarity low
                          1, 	// 1 event
                          0x3F ); 	// debouncing time = 0x3F
    #endif
    
    #if defined (CFG_DEEP_SLEEP_WAKEUP_RTC)
        configure_rtc_wakeup( );
    #endif
    
    #if defined (CFG_DEEP_SLEEP_WAKEUP_TIMER1)
        configure_timer1_wakeup();
    #endif
    
    #if defined (CFG_USER_PRINTF)
    	debug_printf( "%s\n", __FUNCTION__);
    #endif
    
    	// Ensure PD_TIM is open
    	SetBits16(PMU_CTRL_REG, TIM_SLEEP, 0);
    	
    	// Wait until PD_TIM is opened
    	while ((GetWord16(SYS_STAT_REG) & TIM_IS_UP) != TIM_IS_UP);	
    
        // Go to deep sleep
        arch_set_deep_sleep(CFG_DEEP_SLEEP_RAM1,
                            CFG_DEEP_SLEEP_RAM2,
                            CFG_DEEP_SLEEP_RAM3,
                            CFG_DEEP_SLEEP_PAD_LATCH_EN);
    }

  • Hi Vijay,

    I have checked this my site.

    the RTC is configurated by this function: void configure_rtc_wakeup(void).

    So, please make sure the configuration only been made one time for RTC.

  • We are using Prox_reporter example application. We used KEIL IDE for our development.

    RTC is initialized (time_Init() is called) when button is pressed.

    Issues:

    1.       RTC date & time is not continuing after wakeup from sleep

    2.       RTC time is incrementing, but difference is not matching with real time.

    3.       Is it possible to avoid restart when device wakeups from sleep.??

    Source Code (prox_reporter.zip, SDK files are not included), Application Log (Readme.docx) are attached for your reference.

    Part of the source code pasted here.

    #define CFG_DEEP_SLEEP_RAM1            PD_SYS_DOWN_RAM_OFF
    #define CFG_DEEP_SLEEP_RAM2            PD_SYS_DOWN_RAM_OFF
    #define CFG_DEEP_SLEEP_RAM3            PD_SYS_DOWN_RAM_ON
    #define CFG_DEEP_SLEEP_PAD_LATCH_EN    false
    
    static void configure_rtc_wakeup(void)
    {
        rtc_time_t alarm_time;
    
        // Init RTC
        rtc_reset();
    
        // Configure the RTC clock; RCX is the RTC clock source (14420 Hz)
        rtc_clk_config(RTC_DIV_DENOM_1000, 14420);
        rtc_clock_enable();
    
        rtc_config_t cfg = {.hour_clk_mode = RTC_HOUR_MODE_24H, .keep_rtc = 0};
    
        rtc_time_t time = {.hour_mode = RTC_HOUR_MODE_24H, .pm_flag = 0, .hour = 11,
                           .minute = 55, .sec = 30, .hsec = 00};
    
        // Alarm interrupt in ten seconds
        alarm_time = time;
       
        alarm_time.sec += 10;
        if( alarm_time.sec > 59 ) {
    		alarm_time.sec %= 60;
    		alarm_time.minute++;
    		if( alarm_time.minute > 59 ) {
    			alarm_time.minute = 0x00;
    			
    			alarm_time.hour++;
    			if( alarm_time.hour > 23 ) {
    				alarm_time.hour = 0x00;
    			}
    		}
    	}
    
        // Initialize RTC, set time and data, register interrupt handler callback function and enable seconds interrupt
        rtc_init(&cfg);
    
        // Start RTC
        rtc_set_time_clndr(&time, NULL);
        rtc_set_alarm(&alarm_time, NULL, RTC_ALARM_EN_SEC);
    
        // Clear pending interrupts
        rtc_get_event_flags();
        rtc_register_intr(rtc_interrupt_hdlr, RTC_INTR_ALRM);
    #if defined (CFG_EXT_SLEEP_WAKEUP_RTC)
        app_easy_wakeup_set(app_wakeup_cb);
    #endif
    }
    
    void app_on_set_dev_config_complete(void)
    {
    	timeout_timer_hnd = sw_timer_start( SW_BTN_TIMER_DELAY, timeout_timer_cb, NULL );
    	
    	default_app_on_set_dev_config_complete( );
    }
    
    void timeout_timer_cb(void *arg)
    {
       timeout_timer_hnd = EASY_TIMER_INVALID_TIMER;
    	
    	if( GPIO_GetPinStatus(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN ) == 0 ) {
    		extern void time_init( void );
    		time_init( );
    	}
    	
    	timeout_timer_hnd = sw_timer_start( SW_BTN_TIMER_DELAY, timeout_timer_cb, NULL );
    	
      /* Queue event for processing in main loop */
    //  event_t evt = { .id = E_APP_EVENT_TIMEOUT_TIMER_EXPIRED };
     // (void)event_put(&evt);
    }
    
    void time_init(void)
    {
      /* Power domain in which the RTC resides is disabled by default and so
         needs to be enabled before we can use it.  */
      SetBits16(PMU_CTRL_REG, TIM_SLEEP, 0);
      while ((GetWord32(SYS_STAT_REG) & TIM_IS_UP) != TIM_IS_UP);
    
      /* Put RTC into known state */
      rtc_reset( );
    
      /* Configure the RTC 100Hz clock, based on the LP clock frequency */
      if( arch_clk_is_RCX20( ) ) {
        extern uint32_t rcx_freq;
        /* Use the calibrated RCX frequency */
        rtc_clk_config(RTC_DIV_DENOM_1000, rcx_freq);
      } else {
        rtc_clk_config(RTC_DIV_DENOM_1024, 32768);
      }
      rtc_clock_enable( );
    
      /* Default RTC configuration */
      static const rtc_config_t cfg_rtc = {
        .hour_clk_mode = RTC_HOUR_MODE_24H,
        .keep_rtc = true,
      };
    
      /* Initialize RTC, it will be started when the date and time are set */
      rtc_init( &cfg_rtc );
    
      /* Set the RTC to the UNIX epoch, future calls to the time function will then
         return seconds since this point (i.e. when the device was last reset). */
      rtc_time_t time;
      rtc_calendar_t clndr;
      time.hour = 0;
      time.minute = 0;
      time.sec = 0;
      time.hsec = 0;
      time.hour_mode = RTC_HOUR_MODE_24H;
      clndr.year = 1970;
      clndr.month = 1;
      clndr.mday = 1;
      clndr.wday = 1;
    
      /* Setting the time/date will also start the RTC if it was not running */
      (void)rtc_set_time_clndr(&time, &clndr);
      
      debug_printf( "RTC Init Done: %s...\n", __FUNCTION__ );
    }
    
    static void put_system_into_deep_sleep(void)
    {
    #if defined (CFG_DEEP_SLEEP_WAKEUP_POR)
        // Configure button for POR
        GPIO_EnablePorPin(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, GPIO_POR_PIN_POLARITY_LOW, GPIO_GetPorTime());
    #endif
    
    #if defined (CFG_DEEP_SLEEP_WAKEUP_GPIO)
        wkupct_enable_irq(WKUPCT_PIN_SELECT(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN), // Select pin
                          WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, WKUPCT_PIN_POLARITY_LOW), // Polarity low
                          1, // 1 event
                          0); // debouncing time = 0
    #endif
    
    #if defined (CFG_DEEP_SLEEP_WAKEUP_RTC)
        configure_rtc_wakeup();
    #endif
    
    #if defined (CFG_DEEP_SLEEP_WAKEUP_TIMER1)
        configure_timer1_wakeup();
    #endif
    
        // Go to deep sleep
        arch_set_deep_sleep(CFG_DEEP_SLEEP_RAM1,
                            CFG_DEEP_SLEEP_RAM2,
                            CFG_DEEP_SLEEP_RAM3,
                            CFG_DEEP_SLEEP_PAD_LATCH_EN);
    }
    
    void periph_init(void)  // set i2c, spi, uart, uart2 serial clks
    {
    #if defined (__DA14531__)
        // Disable HW Reset functionality of P0_0
        GPIO_Disable_HW_Reset();
    
        // In Boost mode enable the DCDC converter to supply VBAT_HIGH for the used GPIOs
        syscntl_dcdc_turn_on_in_boost(SYSCNTL_DCDC_LEVEL_3V0);
    #else
        // Power up peripherals' power domain
        SetBits16(PMU_CTRL_REG, PERIPH_SLEEP, 0);
        while (!(GetWord16(SYS_STAT_REG) & PER_IS_UP));
        SetBits16(CLK_16M_REG, XTAL16_BIAS_SH_ENABLE, 1);
    #endif
    
        // ROM patch
        patch_func();
    
        // Initialize peripherals
    #if defined (CFG_PRINTF_UART2)
        // Initialize UART2
        uart_initialize(UART2, &uart_cfg);
    #endif
    
    #if defined (CFG_SPI_FLASH_ENABLE)
        // Configure SPI Flash environment
        spi_flash_configure_env(&spi_flash_cfg);
    
        // Initialize SPI
        spi_initialize(&spi_cfg);
    #endif
    
    #if defined (CFG_I2C_EEPROM_ENABLE)
        // Configure I2C EEPROM environment
        i2c_eeprom_configure(&i2c_cfg, &i2c_eeprom_cfg);
    
        // Initialize I2C
        i2c_eeprom_initialize();
    #endif
    
        // Set pad functionality
        set_pad_functions();
    
    #if (BLE_PROX_REPORTER)
        app_proxr_port_reinit(GPIO_ALERT_LED_PORT, GPIO_ALERT_LED_PIN);
        app_button_enable();
    #endif
    
    #if BLE_BATT_SERVER
        app_batt_port_reinit();
    #endif
    	if( counter >= 10000 )
    		counter = 0;
    	counter++;
    	
    	// Ensure PD_TIM is open
    	SetBits16(PMU_CTRL_REG, TIM_SLEEP, 0);
    	
    	// Wait until PD_TIM is opened
    	while ((GetWord16(SYS_STAT_REG) & TIM_IS_UP) != TIM_IS_UP);	
    	
    	rtc_clock_enable( );
    	
    	rtc_start( );
    	
    	rtc_time_t time;
    	rtc_get_time_clndr( &time, NULL ); 
    	
    #ifdef CFG_PRINTF	
    	debug_printf( "%s count:%d  Time %02d:%02d:%02d\n", __FUNCTION__, counter, time.hour, time.minute, time.sec );	
    #endif
        // Enable the pads
        GPIO_set_pad_latch_en(true);
    }

    0020.prox_reporter.zipReadme.docx

  • Do you have any updates regarding this issue?

  • Hi Vijay,

    Let's make a conclusion.

    1, RTC can be alive during sleep as we talked using

     // Ensure PD_TIM is open
    SetBits16(PMU_CTRL_REG, TIM_SLEEP, 0);  

    So, you can wake up by the RTC.

    2, RTC can retain the registers during SW reset by using this API:

    // this keep_rtc should be true, when you want keep rtc registors
    rtc_set_keep_reg_on_reset(cfg->keep_rtc);

    This means when software reset triggered, the RTC registers can be retained. 

    But the wake-up belongs to HW/POR reset, so we can not avoid re configuration of the RTC.

    So, the RTC can works as a wake-up source but can't keep it's data after wake-up. you need align the current time after initialized by BLE service or other sources.

    BR,

    JH_Renesas

  • I have attached the prox_reporter example program, UART log in my previous chat. Features of application are BLE advertisement with RTC wakeup and RTC Initialization by switch. Please check once if required. Since RTC & Timer1 are in PD_TIM, I thought one time time Initialization is enough.

  • void arch_set_deep_sleep(pd_sys_down_ram_t ram1,
                             pd_sys_down_ram_t ram2,
                             pd_sys_down_ram_t ram3,
                             bool pad_latch_en)
    {
        // Stop watchdog timer
        wdg_freeze();
    
        // Disable Interrupts (CPSR)
        GLOBAL_INT_STOP()
    
    #if (WLAN_COEX_ENABLED)
        // Drive to inactive state the pin used for the BLE event in progress signal
        wlan_coex_set_ble_eip_pin_inactive();
    #endif
    
        // Disable radio
        SetBits16(PMU_CTRL_REG, RADIO_SLEEP, 1);
    
        // Disable the BLE core clocks
        SetBits16(CLK_RADIO_REG, BLE_ENABLE, 0);
    
        // Apply HW reset to BLE_Timers
        SetBits16(CLK_RADIO_REG, BLE_LP_RESET, 1);
    
        // Clear quadec pending interrupt - mask quadec interrupt
        SetWord16(QDEC_CTRL_REG, QDEC_IRQ_STATUS);
    
        // Close peripheral clock
        SetBits16(CLK_PER_REG, QUAD_ENABLE, 0);
    
        // Clear all pending interrupts
        NVIC->ICPR[0] = 0xFFFFFFFFUL;
    
        // Debugger must be disabled before entering a sleep mode. Wait until debugger has been disabled.
        while (GetBits16(SYS_STAT_REG, DBG_IS_UP) != 0);
        SetBits16(SYS_CTRL_REG, DEBUGGER_ENABLE, 0);
    
        // Set deep sleep mode
        SetBits16(HIBERN_CTRL_REG, HIBERNATION_ENABLE, 0);
        SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk);
    
        // Configure the state of RAM blocks during the deep sleep mode
        SetBits16(RAM_PWR_CTRL_REG, RAM1_PWR_CTRL, ram1);
        SetBits16(RAM_PWR_CTRL_REG, RAM2_PWR_CTRL, ram2);
        SetBits16(RAM_PWR_CTRL_REG, RAM3_PWR_CTRL, ram3);
    
        // Perform HW reset on wake-up
        SetBits16(PMU_CTRL_REG, RESET_ON_WAKEUP, 1);
    
        // Enable/Disable latching of pads state during sleep
        SetBits16(PAD_LATCH_REG, PAD_LATCH_EN, pad_latch_en);
    
        // Set clamp output (0xF = 603mV)
        SetBits(POWER_AON_CTRL_REG, LDO_RET_TRIM, 0x0F);
    
        // Disable the testmode comparator
        SetBits(POWER_AON_CTRL_REG, FORCE_RUNNING_COMP_DIS, 1);
    
        // Perform the following steps when in boost (or bypass) mode
        if (GetBits16(ANA_STATUS_REG, BOOST_SELECTED) == 0x1)
        {
            // Always LDO_LOW Off
            SetBits16(POWER_CTRL_REG, LDO_LOW_CTRL_REG, 1);
    
            // Force connection between VBAT_HIGH and VBAT_LOW
            SetBits(POWER_AON_CTRL_REG, VBAT_HL_CONNECT_RES_CTRL, 2);
        }
        // Perform the following steps, when in buck mode
        else
        {
            // High-current mode in active, Low-current mode in sleep
            SetBits16(POWER_CTRL_REG, LDO_LOW_CTRL_REG, 3);
    
            // Set automatic connection control between VBAT_HIGH and VBAT_LOW
            SetBits(POWER_AON_CTRL_REG, VBAT_HL_CONNECT_RES_CTRL, 3);
        }
    
        // Disable the POR triggered from VBAT_HIGH voltage level sensing
        SetBits(POWER_AON_CTRL_REG, POR_VBAT_HIGH_RST_MASK, 1);
    
        // Enable the POR triggered from VBAT_LOW voltage level sensing
        SetBits(POWER_AON_CTRL_REG, POR_VBAT_LOW_RST_MASK, 0);
    
        // Set for proper RCX operation
        SetBits16(GP_DATA_REG, 0x60, 2);
    
        __NOP();
        __NOP();
        __NOP();
    
        // Enter Deep Sleep Mode
        __WFI();
    }

    With reference to datasheet, it is possible to reset the PMU_CTRL_REG[RESET_ON_WAKEUP] bit to avoid system reset after wakeup from sleep. but PMU_CTRL_REG[RESET_ON_WAKEUP] is always set in arch_set_deep_sleep function definition. We require the system should not reset after wakeup from deep sleep. Please suggest the same.

  • Hi Vijay,

    Have you tried to set this bit to 0 to have a test.

    Will appreciate with the sharing for this.

    Thanks,

    JH_Renesas 

  • We tried to tried to set this bit to 0 in 49 line of arch_set_deep_sleep function definition, after that we are not able to program the chip even from 1 wire UART mode.

  • Do you have any updates regarding this issue?

Reply Children