da14531休眠及timer1 唤醒问题

你好,

我现在正在测试用timer1唤醒处于ARCH_EXT_SLEEP_ON状态的设备,我将时钟设置为LP_CLK_RCX20,即15KHz,但是我有点弄不清楚timer1的时间计算,理论上最大是 (1/15000) * 2^11 ~= 0.1365 sec or 136.5 msec? 实际上.reload_val设置的最大值为65535,计算的话最大4秒多,但是事实上通过修改这个参数值发现有几个临界值,设为8191时观测为ms级,8192就变成min级。。

static void configure_timer1_wakeup(void)
{
    timer1_count_options_t count_options = {.input_clk = TIM1_CLK_SRC_LP,
                                            .free_run = TIM1_FREE_RUN_OFF,
                                            .irq_mask = TIM1_IRQ_MASK_OFF,
                                            .count_dir = TIM1_CNT_DIR_UP,
                                            .reload_val = 8191,   //TIM1_RELOAD_MAX
    };
    // Enable Timer1 interrupt
    timer1_enable_irq();
//#if defined (CFG_EXT_SLEEP_WAKEUP_TIMER1)
//    app_easy_wakeup_set(app_wakeup_cb);
//#endif
    timer1_count_config(&count_options, timer1_interrupt_hdlr);

    // Start the Timer
    timer1_start();
        SEGGER_RTT_printf(0,"\r timer1 set!\r\n");    
}

所以搞不清楚这个值与时间的具体关系,是否有具体的计算方式呢?

 

另外关于休眠状态低功耗还有一个疑问,我设置为ARCH_EXT_SLEEP_ON,休眠状态大概为0.19ma,理论应该到ua吧?设置deep sleep的话休眠电流反而比ext sleep更大,我是以ble_app_peripheral工程作为模板进行修改的。请问这个情况问题是出在哪里呢,未休眠的时候是0.24ma左右。

我的休眠设置如下:

static void app_resume_system_from_sleep(void)
{
//    if (arch_ble_ext_wakeup_get())
//    {
//        arch_set_sleep_mode(ARCH_EXT_SLEEP_ON);
//        arch_ble_force_wakeup();
//        arch_ble_ext_wakeup_off();
//        app_easy_wakeup();
//    }
			arch_ble_force_wakeup();
			user_app_adv_start(); 
			SEGGER_RTT_printf(0,"\rwake up!\r\n");
}

static void timer1_interrupt_hdlr(void)
{
#if defined (CFG_EXT_SLEEP_WAKEUP_TIMER1)
	SEGGER_RTT_printf(0,"\r timer1 interrupt\r\n");
    app_resume_system_from_sleep(); 
#endif
}


static void configure_timer1_wakeup(void)
{
    timer1_count_options_t count_options = {.input_clk = TIM1_CLK_SRC_LP,
                                            .free_run = TIM1_FREE_RUN_OFF,
                                            .irq_mask = TIM1_IRQ_MASK_OFF,
                                            .count_dir = TIM1_CNT_DIR_UP,
                                            .reload_val = 8191,   //TIM1_RELOAD_MAX
    };
    // Enable Timer1 interrupt
    timer1_enable_irq();
//#if defined (CFG_EXT_SLEEP_WAKEUP_TIMER1)
//    app_easy_wakeup_set(app_wakeup_cb);
//#endif
    timer1_count_config(&count_options, timer1_interrupt_hdlr);

    // Start the Timer
    timer1_start();
		SEGGER_RTT_printf(0,"\r timer1 set!\r\n");	
}

void user_app_adv_start(void) 
{
    // Schedule the next advertising data update
//    app_adv_data_update_timer_used = app_easy_timer(APP_ADV_DATA_UPDATE_TO, adv_data_update_timer_cb);

    struct gapm_start_advertise_cmd* cmd;
    cmd = app_easy_gap_undirected_advertise_get_active(); 
    
        cmd->info.host.adv_data_len = stored_adv_data_len;
    // Store advertising data
    memcpy(cmd->info.host.adv_data, stored_adv_data, stored_adv_data_len);
    // Store scan response data length
    cmd->info.host.scan_rsp_data_len = stored_scan_rsp_data_len;
    // Store scan_response data
    memcpy(cmd->info.host.scan_rsp_data, stored_scan_rsp_data, stored_scan_rsp_data_len);
    
    // Add manufacturer data to initial advertising or scan response data, if there is enough space
    app_add_ad_struct(cmd, &mnf_data, sizeof(struct mnf_specific_data_ad_structure), 1);
    
//    app_easy_gap_undirected_advertise_start();
        app_easy_gap_undirected_advertise_with_timeout_start(user_default_hnd_conf.advertise_period, NULL);  
}

void user_app_adv_undirect_complete(uint8_t status)
{
    // If advertising was canceled then update advertising data and start advertising again

    if (status == GAP_ERR_CANCELED)
    {    
//        user_app_adv_start();
                
//                arch_ble_ext_wakeup_on();
            
            #if defined (CFG_EXT_SLEEP_WAKEUP_RTC) || defined (CFG_EXT_SLEEP_WAKEUP_TIMER1)
            // 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);
            #endif
            
            #if defined (CFG_EXT_SLEEP_WAKEUP_RTC)
                configure_rtc_wakeup();
            #endif
            
            #if defined (CFG_EXT_SLEEP_WAKEUP_TIMER1)
                configure_timer1_wakeup();
            #endif
            arch_set_sleep_mode(ARCH_EXT_SLEEP_ON);
            SEGGER_RTT_printf(0,"\r sleep!\r\n");
    }
}

我这样设置后确认可以进入休眠,现象符合我的要求,广播一段时间后停止广播,然后进入休眠,随后通过timer1唤醒,继续广播后再次进入休眠 如此循环下去。

我参考了prox_reporter工程,但是我如果按prox_reporter工程去设置,会导致app_wakeup_cb这个回调函数不被触发,这个函数应该在app_easy_wakeup();执行后就自动触发,但是实际效果并未触发,不知道是什么问题?

 

期待您的回复!