CN / EN
CN / EN

提问

获得支持

您的项目私密技术问题如需获得一对一支持,请点击下方联系我们。

GR551x 如何在睡眠前测量GPIO上下拉状态分析GPIO配置是否正确 GR551x

已解决

best

2022-01-07 16:36

1、睡眠前测量GPIO状态的目的是什么?

通常在功耗调试阶段,遇到sleep功耗较大时,会有需要针对所有GPIO口的漏电情况进行排查,这个工作量比较大,且进行起来比较低效率,下文会介绍sleep前将GPIO状态读出来保存的调试手段。

2、在SDK中有保留 sleep前回调函数如下:

typedef void (*io_dump_func_t)(void);
void pwr_mgmt_register_io_dump_func(io_dump_func_t dump_func);

3、读取GPIO状态实现

#define GPIO_PULL_STATUS(x)       (((x)==(LL_GPIO_PULL_NO))?"PULL_NO":(((x)==(LL_GPIO_PULL_UP))?"PULL_UP":"PULL_DOWN"))
#define AON_GPIO_PULL_STATUS(x)   (((x)==(LL_AON_GPIO_PULL_NO))?"PULL_NO":(((x)==(LL_AON_GPIO_PULL_UP))?"PULL_UP":"PULL_DOWN"))
#define MSIO_PULL_STATUS(x)       
SECTION_RAM_CODE void before_deep_sleep_op(void)
{    
    ll_aon_gpio_set_pin_mode(LL_AON_GPIO_PIN_3, LL_AON_GPIO_MODE_OUTPUT);    
    ll_aon_gpio_disable_it(LL_AON_GPIO_PIN_3);    
    ll_aon_gpio_toggle_pin(LL_AON_GPIO_PIN_3);    
    ll_aon_gpio_toggle_pin(LL_AON_GPIO_PIN_3);	    
    for(uint8_t i = 0;i<16;i++)    
    {        
        gpio0_pull_status[i] = ll_gpio_get_pin_pull(GPIO0, (LL_GPIO_PIN_0<<i));    
    }    
    for(uint8_t i = 0;i<16;i++)    
    {        
        gpio1_pull_status[i] = ll_gpio_get_pin_pull(GPIO1, (LL_GPIO_PIN_0<<i));    
    }    
    for(uint8_t i = 0;i<8;i++)    
    {        
        aon_gpio_pull_status[i] = ll_aon_gpio_get_pin_pull(LL_AON_GPIO_PIN_0<<i);    
    }    
    for(uint8_t i = 0;i<5;i++)    
    {        
        msio_pull_status[i] = ll_msio_get_pin_pull(LL_MSIO_PIN_0<<i);    
    }	
}

4、实现部分

需要将before_deep_sleep_op函数注册到pwr_mgmt_register_io_dump_func接口中,以实现sleep前调用。

    diag_no25_isr_start_func = app_diag_no25_isr_start;    
    diag_no25_isr_done_func = app_diag_no25_isr_done;    
    pwr_mgmt_register_io_dump_func(before_deep_sleep_op);

5,测试代码&测试结果

    gpio_config.mode = GPIO_MODE_OUTPUT;    
    gpio_config.pin  = LED2_PIN;    
    gpio_config.pull = GPIO_PULLUP;    
    hal_gpio_init(LED2_PORT, &gpio_config);//GPIO_PIN_4	    
    gpio_config.mode = GPIO_MODE_OUTPUT;    
    gpio_config.pin  = GPIO_PIN_5;    
    gpio_config.pull = GPIO_PULLDOWN;    
    hal_gpio_init(LED2_PORT, &gpio_config);//GPIO_PIN_5	    
    gpio_config.mode = GPIO_MODE_OUTPUT;    
    gpio_config.pin  = GPIO_PIN_6;    
    gpio_config.pull = GPIO_NOPULL;    
    hal_gpio_init(LED2_PORT, &gpio_config);//GPIO_PIN_6

6、相关说明

在调试过程中,若遇到获取IO状态不正确的情况,这时需要去确认GR551X是否有正常进入sleep状态,需要注意的是不能在

before_deep_sleep_op中加相关printf函数,否则会导致sleep状态异常,可利用AON_GPIO翻转来实现debug。

  • 比如注册BLE睡眠唤醒中断处理标记函数,将AON GPIO7拉高在拉低,标记BLESLP_ISR处理时间及时序
SECTION_RAM_CODE void app_diag_no25_isr_start(void)
{    
    ll_aon_gpio_set_pin_mode(LL_AON_GPIO_PIN_7,    LL_AON_GPIO_MODE_OUTPUT);    
    ll_aon_gpio_disable_it(LL_AON_GPIO_PIN_7);    
    ll_aon_gpio_set_output_pin(LL_AON_GPIO_PIN_7);
}

SECTION_RAM_CODE void app_diag_no25_isr_done(void)
{    
    ll_aon_gpio_reset_output_pin(LL_AON_GPIO_PIN_7);
}
  • 比如在热启动流程的代码(main_init函数)中,添加
void main_init(void)
{    
    uint32_t boot_flag = get_wakeup_flag();    
    if(COLD_BOOT == boot_flag)    
    {        
        extern void __main(void);        
        __main();    
    }    
    else    
    {        
        ll_aon_gpio_set_pin_mode(LL_AON_GPIO_PIN_5, LL_AON_GPIO_MODE_OUTPUT);        
        ll_aon_gpio_disable_it(LL_AON_GPIO_PIN_5);        
        ll_aon_gpio_toggle_pin(LL_AON_GPIO_PIN_5);        
        ll_aon_gpio_toggle_pin(LL_AON_GPIO_PIN_5);			        
        pwr_mgmt_warm_boot();        
        while (1);    
    }    // Never execute here
}
  • 在before_deep_sleep_op 实现中加入
    ll_aon_gpio_set_pin_mode(LL_AON_GPIO_PIN_3, LL_AON_GPIO_MODE_OUTPUT);    ll_aon_gpio_disable_it(LL_AON_GPIO_PIN_3);    ll_aon_gpio_toggle_pin(LL_AON_GPIO_PIN_3);    ll_aon_gpio_toggle_pin(LL_AON_GPIO_PIN_3);
  • 测试结果,通道01 IO翻转后BLE进入sleep,通道00为BLESLP_SIR中断唤醒,进入Warmboot。


2收藏

1赞成

最佳答案

best

2022-01-20 16:45


0条评论

1赞成

1收藏

您的评论

登录后可回答问题,请 注册

我们时刻倾听您的声音
联系销售

扫描关注公众号

打开微信,使用“扫一扫”即可关注