7.28. 开关机

7.28.1. 概述

本文介绍芯片开机流程、开机方式、软关机、软关机唤醒以及复位重启。

相关源文件

文件路径

说明

include_lib/driver/cpu/wl83/asm/power/power_api.h

电源接口、软关机、power_control 命令定义

include_lib/driver/cpu/wl83/asm/power/power_wakeup.h

IO唤醒配置、唤醒源判断 API

include_lib/driver/cpu/wl83/asm/power/power_reset.h

复位原因判断 API

include_lib/driver/cpu/wl83/asm/power/power_app.h

power_early_flowing、board_power_init


7.28.2. 开机

开机方式有三种,分别是上电开机唤醒开机以及复位重启。三种开机的主要流程都是一样的:

开机流程: 上电/唤醒/复位 -> maskrom -> uboot -> app

注意:唤醒开机相比于上电开机的开机log少很多信息,这是由于软关机IO锁存还未解锁,导致解锁前的log无法输出。正常的软关机唤醒log是从解锁的打印====soff latch release=======开始的。如果需要唤醒开机也有完整log信息,可以使用HUSBDP/HUSBDM作为打印口,这两个IO口在maskrom阶段已解锁。

// 唤醒开机log起始位置
[00:00:00.138][Info]: [PMU]==============soff latch release=================
[00:00:00.139][Info]: [PMU]power SYSVDD : 0xc
[00:00:00.139][Info]: [PMU]power VDDIO : 0x6 / 0x0
[00:00:00.140][Info]: [PMU]power VDC14 : 0x3
...

7.28.2.1. 上电开机

上电开机是指芯片从完全断电状态 或者 低电复位,通过接入电源启动的过程。

开机流程

VBAT上电 → POR复位 → 开机流程

开机判断

如果开机信息中有P33_VDDIO_POR_RST打印,即为上电开机。

[00:00:00.100][Info]: [PMU]msys_rst_src: 0x1
[00:00:00.100][Info]: [PMU]MSYS_P33_RST
[00:00:00.100][Info]: [PMU]P33_LEVEL0_RST
[00:00:00.100][Info]: [PMU]P33_LEVEL1_RST
[00:00:00.100][Info]: [PMU]P33_LEVEL2_RST
[00:00:00.100][Info]: [PMU]p33_rst_src: 0x1
[00:00:00.100][Info]: [PMU]P33_VDDIO_POR_RST
[00:00:00.100][Info]: [PMU]R3_RST_SRC_VDDIO
[00:00:00.100][Info]: [PMU]reset_source_value: 0x20020002
[00:00:00.100][Info]: [PMU]reset_source_value1: 0x0

上电开机判断

if (is_reset_source(P33_VDDIO_POR_RST)) {
    // 上电开机处理
}

7.28.2.2. 唤醒开机

唤醒开机是指芯片从软关机(soff)状态被唤醒源触发后重新启动的过程,支持IO唤醒RTC唤醒LP定时唤醒三种唤醒方式。

判断方式

if (is_reset_source(P33_POWER_RETURN)) { // P33未被复位,等于说明芯片是唤醒开机
    // 软关机唤醒开机
}

7.28.2.2.1. IO唤醒

IO唤醒是通过 GPIO 引脚的边沿信号将芯片从软关机状态唤醒。AC792N最大可同时支持配置12个IO唤醒。

支持唤醒功能的IO有:PA、PB、PC、PD、PE、FUSB(DP/DM)、HUSB(DP/DM)、PV。

IO唤醒配置

唤醒源通过 p33_io_wakeup_config_t 结构体配置:

typedef struct {
    u32 gpio;                                   ///< 唤醒io
    u32 pullup_down_enable;                     ///< 内部上下拉是否使能
    p33_io_wkup_flt_t filter;                   ///< 滤波参数
    p33_io_wkup_edge_t edge;                    ///< 唤醒边沿条件
    void (*callback)(p33_io_wkup_edge_t edge);  ///< 唤醒回调
} p33_io_wakeup_config_t;

IO唤醒边沿枚举 p33_io_wkup_edge_t

枚举值

说明

RISING_EDGE

上升沿唤醒

FALLING_EDGE

下降沿唤醒

BOTH_EDGE

双边沿唤醒

IO唤醒滤波参数枚举 p33_io_wkup_flt_t

枚举值

说明

PORT_FLT_DISABLE

关闭滤波

PORT_FLT_16us

16μs 滤波

PORT_FLT_128us

128μs 滤波

PORT_FLT_1ms

1ms 滤波

PORT_FLT_4ms

4ms 滤波

回调接口

唤醒回调在唤醒边沿触发时执行,在中断上下文中运行:

static void wakeup_port0_callback_in_irq(p33_io_wkup_edge_t edge)
{
    // 唤醒回调处理,其中edge为唤醒沿
}

注意:IO唤醒不是软关机状态,在芯片运行状态下触发IO也会触发回调,等效于外部中断。

IO唤醒板级配置示例

static const p33_io_wakeup_config_t wakeup_port0 = {
    .pullup_down_enable     = 1,
    .filter                 = TCFG_LOWPOWER_WAKEUP_PORT0_FILTER,
    .edge                   = TCFG_LOWPOWER_WAKEUP_PORT0_EDGE,
    .gpio                   = TCFG_LOWPOWER_WAKEUP_PORT0_IO,
    .callback               = wakeup_port0_callback_in_irq,
};

IO唤醒板级配置宏

#define TCFG_LOWPOWER_WAKEUP_PORT0_ENABLE   1
#define TCFG_LOWPOWER_WAKEUP_PORT0_IO       IO_PORTD_00
#define TCFG_LOWPOWER_WAKEUP_PORT0_EDGE     FALLING_EDGE
#define TCFG_LOWPOWER_WAKEUP_PORT0_FILTER   PORT_FLT_DISABLE

IO唤醒配置相关API

void p33_io_wakeup_port_init(const p33_io_wakeup_config_t *config);  // 初始化唤醒口
void p33_io_wakeup_enable(u32 gpio, u32 enable);                     // 使能/关闭唤醒
void p33_io_wakeup_port_uninit(u32 gpio);                            // 关闭IO唤醒功能
void p33_io_wakeup_set_callback(u32 gpio, void (*callback)(p33_io_wkup_edge_t edge));  // 设置回调
int  p33_get_io_wakeup_port_used(u32 gpio);                          // 查询IO是否设置了唤醒
u32 is_gpio_wakeup(u32 gpio);                                        // 判断是否为指定gpio唤醒,返回边沿类型

配置位置参考:

u8 power_soff_callback(void)
{
// ...
#if TCFG_LOWPOWER_WAKEUP_PORT0_ENABLE
    p33_io_wakeup_port_init(&wakeup_port0); // 配置唤醒IO
    p33_io_wakeup_enable(TCFG_LOWPOWER_WAKEUP_PORT0_IO, 1); // 使能唤醒IO
#endif
// ...
    gpio_config_soft_poweroff();

    return 0;
}

static void gpio_config_soft_poweroff(void)
{
    PORT_TABLE(g);

#if TCFG_LOWPOWER_WAKEUP_PORT0_ENABLE
    PORT_PROTECT(TCFG_LOWPOWER_WAKEUP_PORT0_IO); // 保护唤醒IO,防止软关机被__port_init()配置为高阻态
#endif

    __port_init((u32)gpio_config);
}

IO唤醒判断方法

  1. 通过唤醒回调判断(.callback)

  2. 通过api接口获取唤醒源和唤醒IO口

if (is_wakeup_source(PWR_WK_REASON_PORT_EDGE)) { // 判断是否为IO唤醒
    if (is_gpio_wakeup(IO_PORTC_01)) {
        // 目标唤醒口的处理程序
    }
}

开机log参考:

[00:00:00.100][Info]: [PMU]msys_rst_src: 0x2
[00:00:00.100][Info]: [PMU]MSYS_DVDD_POR_RST
[00:00:00.100][Info]: [PMU]P33 POWER RETURN
[00:00:00.100][Info]: [PMU]R3 POWER RETURN
[00:00:00.100][Info]: [PMU]reset_source_value: 0x10000008
[00:00:00.100][Info]: [PMU]reset_source_value1: 0x1
[00:00:00.100][Info]: [WKUP]p33_wkup_src : 0x2
[00:00:00.100][Info]: [WKUP]rtc_wkup_src : 0x0
[00:00:00.100][Info]: [WKUP]PWR_WK_REASON_PORT_EDGE
[00:00:00.100][Info]: [WKUP]wkup_p_pnd: 0x0, wkup_n_pnd: 0x2
[00:00:00.100][Info]: [WKUP]PWR_WK_REASON_EDGE_FALLING_EDGE_1
[00:00:00.100][Info]: [WKUP]wakeup_source_value0: 0x108
[00:00:00.100][Info]: [WKUP]wakeup_source_value1: 0x0
[00:00:00.100][Info]: [WKUP]soff_g_wkup_p_pnd: 0x0
[00:00:00.100][Info]: [WKUP]soff_g_wkup_n_pnd: 0x2
[00:00:00.100][Info]: [WKUP]soff_a_wkup_p_pnd: 0x0
[00:00:00.100][Info]: [WKUP]soff_a_wkup_n_pnd: 0x0
[00:00:00.100]soff_port_sel0: 0x30
[00:00:00.100]soff_port_sel1: 0x2f
// ...

7.28.2.2.2. RTC唤醒

RTC唤醒是通过RTC闹钟PR口边沿唤醒信号将芯片从软关机状态唤醒。

7.28.2.2.2.1. 闹钟唤醒

RTC的使用方法参考RTC章节。这里仅介绍闹钟唤醒使用方法:

保证RTC正常跑时,在软关机前配置好闹钟时间,当闹钟时间一到,芯片将唤醒开机。

唤醒判断方法

  1. 软关机RTC唤醒也会回调.alarm_wakeup_cb_in_irq

  2. 唤醒源api判断是否为PWR_RTC_WK_REASON_ALM唤醒

if (is_wakeup_source(PWR_RTC_WK_REASON_ALM)) {
    // 闹钟唤醒处理
}

开机log参考:

[00:00:00.100][Info]: [PMU]msys_rst_src: 0x2
[00:00:00.100][Info]: [PMU]MSYS_DVDD_POR_RST
[00:00:00.100][Info]: [PMU]P33 POWER RETURN
[00:00:00.100][Info]: [PMU]R3 POWER RETURN
[00:00:00.100][Info]: [PMU]reset_source_value: 0x10000008
[00:00:00.100][Info]: [PMU]reset_source_value1: 0x1
[00:00:00.100][Info]: [WKUP]p33_wkup_src : 0x0
[00:00:00.100][Info]: [WKUP]rtc_wkup_src : 0x1
[00:00:00.100][Info]: [WKUP]R3_WKUP_SRC_ALM
[00:00:00.100][Info]: [WKUP]wakeup_source_value0: 0x0
[00:00:00.100][Info]: [WKUP]wakeup_source_value1: 0x100
7.28.2.2.2.2. PR口唤醒

RTC不使用外部晶振时(.clk_sel时钟源不要选择CLK_SEL_32K),可将PR口作特殊IO使用,支持IO唤醒,需要使用专用配置接口。PR口有两个,分别是IO_PORT_PR_00IO_PORT_PR_01。PR口属于RTCVDD电源域,作为IO使用时其工作电平电压取决于RTCVDD。

int rtc_port_pr_wkup_cfg(int port, pr_io_wkup_edge_t wkup_edge, pr_io_wkup_flt_t flt_cfg);
int rtc_port_pr_wkup_disable(int port);

回调接口

static void pr_wakeup_cb_in_irq(int port)
{
    // TODO
    // port为触发IO
    // 注意不要加打印
}

RTC_PLATFORM_DATA_BEGIN(rtc_data)
    .pr_wakeup_cb_in_irq    = pr_wakeup_cb_in_irq,
RTC_PLATFORM_DATA_END()

注意:PR口唤醒不是软关机专用,在芯片运行状态下触发IO也会触发回调,等效于外部中断。

PR口唤醒边沿枚举pr_io_wkup_edge_t

枚举值

说明

PR_RISING_EDGE

上升沿

PR_FALLING_EDGE

下降沿

PR_BOTH_EDGE

双边沿

PR口唤醒滤波枚举pr_io_wkup_flt_t

枚举值

说明

PR_PORT_FLT_DISABLE

关闭滤波

PR_PORT_FLT_16us

16us滤波

PR_PORT_FLT_128us

128us滤波

PR_PORT_FLT_1ms

1ms滤波

PR_PORT_FLT_4ms

4ms滤波

唤醒判断方法

使用唤醒源api判断是否为PWR_RTC_WK_REASON_PORT唤醒

if (is_wakeup_source(PWR_RTC_WK_REASON_PORT)) {
    // PR口唤醒处理
}

开机log参考:

[00:00:00.100][Info]: [PMU]msys_rst_src: 0x40
[00:00:00.100][Info]: [PMU]MSYS_LPMR_RST
[00:00:00.100][Info]: [PMU]P33 POWER RETURN
[00:00:00.100][Info]: [PMU]R3 POWER RETURN
[00:00:00.100][Info]: [PMU]reset_source_value: 0x10000040
[00:00:00.100][Info]: [PMU]reset_source_value1: 0x1
[00:00:00.100][Info]: [WKUP]p33_wkup_src : 0x0
[00:00:00.100][Info]: [WKUP]rtc_wkup_src : 0x8
[00:00:00.100][Info]: [WKUP]R3_WKUP_SRC_PORT
[00:00:00.100][Info]: [WKUP]wakeup_source_value0: 0x0
[00:00:00.100][Info]: [WKUP]wakeup_source_value1: 0x2000

7.28.2.2.3. LP_TIMER定时唤醒

软关机时开启LP_TIMER定时器,定时时间到自动唤醒。

配置接口

调用软关机接口时传入的参数即LP_TIMER定时唤醒时间参数,参数ms大于0生效,参数范围大概0 ~ 21474000(计算公式2^32^/ 200000Hz * 1000,受实际LRC200K频率影响)。

void power_set_soft_poweroff(u32 ms)

注意:LP_TIMER定时唤醒的时钟源为LRC200K(有偏差)

唤醒判断方法

暂不提供唤醒源判断方法。LP定时唤醒log参考:

[00:00:00.100][Info]: [PMU]msys_rst_src: 0x2
[00:00:00.100][Info]: [PMU]MSYS_DVDD_POR_RST
[00:00:00.100][Info]: [PMU]P33 POWER RETURN
[00:00:00.100][Info]: [PMU]R3 POWER RETURN
[00:00:00.100][Info]: [PMU]reset_source_value: 0x10000008
[00:00:00.100][Info]: [PMU]reset_source_value1: 0x1
[00:00:00.100][Info]: [WKUP]p33_wkup_src : 0x0
[00:00:00.100][Info]: [WKUP]rtc_wkup_src : 0x0
[00:00:00.100][Info]: [WKUP]wakeup_source_value0: 0x0
[00:00:00.100][Info]: [WKUP]wakeup_source_value1: 0x0

7.28.3. 关机

7.28.3.1. 软关机

软关机是指系统在软件控制下进入极低功耗状态。

触发软关机

void power_set_soft_poweroff(u32 ms);  // ms: 定时唤醒时间,0表示不定时唤醒

软关机回调

系统进入软关机前会调用 power_soff_callback(),在该回调中完成唤醒源初始化和 GPIO 配置等。

典型调用(新版可能会有调整,以实际公版SDK为准):

u8 power_soff_callback(void)
{
    printf("++++++++%s--------", __FUNCTION__);

#if TCFG_RTC_ENABLE
    poweroff_save_rtc_time(); //保存RTC时间
#endif

#if TCFG_ADKEY_ENABLE || (defined CONFIG_BT_ENABLE || TCFG_WIFI_ENABLE) || TCFG_RTC_ENABLE
    adc_suspend(); // 挂起ADC
#endif

#if TCFG_LOWPOWER_WAKEUP_PORT0_ENABLE
    // 配置唤醒IO
    p33_io_wakeup_port_init(&wakeup_port0);
    p33_io_wakeup_enable(TCFG_LOWPOWER_WAKEUP_PORT0_IO, 1);
#endif

    __mask_io_cfg(); // maskrom IO相关

    gpio_config_soft_poweroff();// deinit IO状态,避免功耗高

    return 0;
}

7.28.3.1.1. 软关机IO锁存

软关机(SOFF)时锁存住IO电平状态。比如用户用IO控制某个外设电源,需要在软关机状态下保持住高电平。

注意:仅PA~PE、FUSB口支持锁存,PF、PV、PR、HUSB口不支持锁存状态。HUSB由于是烧录固件口,开机时必须解锁,因此不支持锁存。

配置方法

软关机状态本身会锁存住当前IO状态,但软关机流程__port_init()里会将IO配置为高阻态,因此只需用PORT_PROTECT()要告诉__port_init()哪些IO不需要deinit即可。

#define TEST_PIN  IO_PORTC_00
static void gpio_config_soft_poweroff(void)
{
// ...
    PORT_TABLE(g);
    gpio_set_mode(TEST_PIN, GPIO_OUTPUT_HIGH); // 配置需要锁存的IO状态
    PORT_PROTECT(TEST_PIN); // 保护IO,避免被__port_init()清成高阻态
    __port_init((u32)gpio_config);
// ...
}

7.28.3.1.2. keep VCM

软关机时保持 VCM,使软关机状态仍然支持VCM复位。

配置方法

通过PCONTROL_SF_KEEP_VCM_DET命令配置。在power_init()前调用power_control()设置软关机时keep住VCM。

// board_xxx.c
static void board_power_init(void)
{
    // ...
    power_control(PCONTROL_SF_KEEP_VCM_DET , true);// soff时保持VCM检测 (1=保持, 0=不保持)
    power_init(&power_pdata);
    // ...
}

7.28.3.2. 直接掉电

直接掉电是指芯片在运行过程中外部电源直接断电,属于非正常关机。

注意:直接掉电的关机方式风险很大,如果芯片程序正在操作flash,可能导致flash中关键区数据被擦除或者误写入,进而出现系统异常、无法开机等情况。

如果客户方案中关机需要给AC792N断电,有如下方法:

1、通过外设通知AC792N关机 -> AC792N走完软关机流程 -> 外部给AC792N断电

2、通过外设通知AC792N关机 -> AC792N进入hold cpu的临界区 -> 外部给AC792N断电

/* AC792N进入hold cpu的临界区的方法 */

// cpu_enter_hold_critical接口会关中断,并hold住另一个cpu,当前cpu跑传入的函数cb()。
extern void cpu_enter_hold_critical(void (*cb)(void *), void *priv, int unmark_suspend);

SEC(.volatile_ram_code) // 注意回调的函数应该放在内部ram的段里
static void my_hold_cpu_cb(void *priv)
{
     // TODO
    while(1);
}

int my_enter_hold_cpu_critical(void)
{
    // wdt_close();
    cpu_enter_hold_critical(my_hold_cpu_cb, NULL, 1);
}

7.28.4. 系统复位

系统复位类型有:软复位、WDT复位、MCLR复位、长按复位、上电复位、VCM复位等。

7.28.4.1. 复位功能配置

7.28.4.1.1. 软复位

触发条件

调用软复位接口触发复位。

// flag参数用于传递复位原因,复位开机时可以获取到。
void system_reset(rst_flag_t flag);

注意:系统触发异常重启,也属于软复位。

参考log:

[00:00:00.100][Info]: [PMU]msys_rst_src: 0x1
[00:00:00.100][Info]: [PMU]MSYS_P33_RST                          <-- P33复位联动MSYS复位
[00:00:00.100][Info]: [PMU]P33_LEVEL2_RST
[00:00:00.100][Info]: [PMU]p33_rst_src: 0x80
[00:00:00.100][Info]: [PMU]P33_SOFT_RST                          <-- P33软复位
[00:00:00.100][Info]: [PMU]P33_EXCEPTION_SOFT_RST                <-- system_reset时传递的flag复位原因是exception
[00:00:00.100][Info]: [PMU]R3 POWER RETURN                       <-- RTC未出现复位
[00:00:00.100][Info]: [PMU]reset_source_value: 0x2000002
[00:00:00.100][Info]: [PMU]reset_source_value1: 0x1

7.28.4.1.2. WDT复位

触发条件

开启WDT后,系统死机会自动触发WDT复位。

配置方法

见《WDT章节》。

7.28.4.1.3. MCLR复位

AC792N PD08脚有一个特殊的功能,MCLR复位输入。MCLR低电平复位,可软件关闭。该引脚在进行IO分配时需要特别注意。该引脚上电默认上拉。最新SDK在uboot阶段已经关闭MCLR。

触发条件

开启MCLR功能后,将MCLR脚的电压拉到低电平。

配置方法

/**
* @brief  使能MCLR
*/
void mclr_reset_enable(void);

/**
* @brief  关闭MCLR
*/
void mclr_reset_disable(void);

7.28.4.1.4. 长按复位

SDK中又名PPINR,IO处于低/高电平状态N秒后系统复位。除了PF和PR口以外的IO支持映射长按复位

参数可配:

  • 有效电平可配:0低电平、1高电平。比如配置为0时,当该引脚被拉到低电平N秒后,系统复位。

  • 长按复位时间可配:1S、2S、4S、8S、16S。

  • 复位释放时刻配置:timeout后,立刻释放系统 或者 等待复位IO恢复后释放系统。

注意:

  1. PD01芯片硬件上默认开启长按复位功能。

  2. PD01的配置支持上锁,该IO使用本接口使能长按复位功能后,DIE、DIEH、PU、PD、DIR等配置将锁死,需要断电后才能解锁。该功能能够避免程序跑飞后误修改长按复位配置,其它IO则无此上锁功能。

  3. 按键功能需要复用长按复位时,应在key初始化完成后再设置长按复位,即gpio_longpress_pin0_reset_config()应在key_driver_init()之后调用。这是由于按键功能初始化会影响到长按复位的配置,因此有顺序要求。

触发条件

配置使能PPINR后,拉低PPINR引脚到低电平N秒后复位。

配置方法

/* ------------------------------------------------------------------------------------*/
/**
 * @brief gpio_longpress_pin0_reset_config
 *
 * @Params pin          映射的IO(除了PF和PR口以外的IO)。
 * @Params level        只能是0或1。0-低电平,1-高电平。
 * @Params time         只能是0/1/2/4/8/16,其中,参数为0时,表示关闭长按复位功能。
 * @Params release      只能是0或1。0-等待复位IO恢复后释放系统,1-立刻释放系统。
 * @Params pull_enable  上/下拉使能。非0-使能。level为0时,IO被配置为上拉;level为1时,IO被配置为下拉。
 *
 * @note  IO_PORTD_01芯片硬件上默认开启长按复位功能。
 * @note  IO_PORTD_01较特殊,该IO使用本接口使能长按复位功能后,DIE、DIEH、PU、PD、DIR等配置将锁死,需要断电后才能解锁。该功能能够避免程序跑飞后误修改长按复位配置,其它IO则无此锁存功能。
 */
/* ------------------------------------------------------------------------------------*/
void gpio_longpress_pin0_reset_config(u32 pin, u32 level, u32 time, u32 release, u32 pull_enable);

7.28.4.1.5. VCM复位

触发条件

VCM脚接高电平会触发VCM复位。

配置方法

芯片上电默认会开启VCM复位。如果需要软关机也支持VCM复位,见《软关机keep VCM章节》。

7.28.4.2. 复位源获取

系统开机后可通过 is_reset_source() 判断本次开机的复位原因。

bool is_reset_source(rst_reason_t index);   // 判断是否为指定复位源
if (is_reset_source(MSYS_DVDD_POR_RST) || is_reset_source(P33_VDDIO_POR_RST)) {
    // 上电开机
}

常见复位源

枚举值

说明

MSYS_DVDD_POR_RST

DVDD 上电复位

MSYS_SOFT_RST

主系统软件复位

P33_VDDIO_POR_RST

VDDIO 上电复位

P33_VDDIO_LVD_RST

低压复位

P33_WDT_RST

看门狗复位

P33_VCM_RST

VCM 短接高电平复位

P33_MCLR_RST

MCLR复位

P33_PPINR_RST

长按复位

P33_SOFT_RST

p33软件复位

从枚举值可以看出,芯片分MSYS、P33、R3(RTC)三模块(AC792N不支持P11),枚举值代表各模块的复位原因。

7.28.5. 常见问题

1、怎么实现长按开机?

答:开机时board_power_init()中判断IO是否长按,如果短按则重新进关机状态。在参考如下代码:

// board_xxx.c
static void board_power_init(void)
{
// ...
#if TCFG_PRESS_LONG_KEY_POWERON_ENABLE
    if (is_gpio_wakeup(adkey_data.adkey_pin)) {
        for (int i = 0; i < 500; i++) {
            if (0 == read_power_key(1)) {
                sys_power_poweroff();
                break;
            }
        }
    }
#endif
// ...
}

2、为什么开发板进入软关机状态后,给板子断电再上电,无法开机或者无法进下载模式?

答:芯片进入低功耗状态后,功耗极低,由于板上电容或串口倒灌电,芯片并没有完全掉电,仍然处于软关机状态,因此重新上电也不开机。

解决办法:

  • 断开开发板电源,拔掉可能得灌电外设(比如串口打印线),然后等待电容完全放电(如果有需要可以用镊子短接DVDD的电容放电)。

  • 配置IO唤醒,触发开机后再操作。

  • 配置软关机keep VCM,通过短接VCM到VDDIO的方式触发VCM RESET复位cpu。

3、PD1作串口可能触发PINR长按复位。

答:换调试串口IO,或者关闭PINR。

7.28.6. API参考

Defines

AT_VOLATILE_RAM_POWER
AT_VOLATILE_RAM_CODE_POWER

Enums

enum lowpower_config_t

Values:

enumerator LOWPOWER_CLOSE
enumerator SLEEP_EN
enumerator DEEP_SLEEP_EN
enum lowpower_osc_type

Values:

enumerator OSC_TYPE_LRC
enumerator OSC_TYPE_BT_OSC
enumerator OSC_TYPE_NULL
enum vddio_keep_t

Values:

enumerator VDDIO_KEEP_TYPE_NULL
enumerator VDDIO_KEEP_TYPE_NORMAL
enumerator VDDIO_KEEP_TYPE_TRIM
enumerator VDDIO_KEEP_TYPE_PG
enum power_control_cmd_t

Values:

enumerator PCONTROL_POWER_DRIVER_RESERVE
enumerator PCONTROL_P_PUTBYTE
enumerator PCONTROL_POWER_MODE
enumerator PCONTROL_DCVDD_CAP_SW
enumerator PCONTROL_FLASH_PG_VDDIO
enumerator PCONTROL_RTC_CLK
enumerator PCONTROL_PD_VDDIO_KEEP
enumerator PCONTROL_PD_WDVDD_LEV
enumerator PCONTROL_PD_DVDD_LEV
enumerator PCONTROL_PD_KEEP_LPCTMU
enumerator PCONTROL_SF_KEEP_LRC
enumerator PCONTROL_SF_VDDIO_KEEP
enumerator PCONTROL_SF_KEEP_NVDD
enumerator PCONTROL_SF_KEEP_PVDD
enumerator PCONTROL_SF_KEEP_VCM_DET
enumerator PCONTROL_PHW_RESERVE
enumerator PCONTROL_P33_RESERVE
enumerator PCONTROL_P11_RESERVE
enumerator PCONTROL_LP_FLOW_IC_RESERVE

Functions

void power_early_init(u32 arg)
void power_later_init(u32 arg)
void power_init(const power_pdata_t *pdata)
u32 power_control(power_control_cmd_t cmd, u32 arg)
void low_power_sys_request(void *priv)
s32 low_power_trace_drift(u32 usec)
void low_power_reset_osc_type(u8 type)
u8 low_power_get_default_osc_type(void)
u8 low_power_get_osc_type(void)
void power_set_soft_poweroff(u32 ms)
void mask_softflag_config(struct boot_soft_flag_t *softflag)
struct power_param_t

Public Members

u8 vddiom_lev
u8 vddiow_lev
u8 vdc14_lev
u8 sysvdd_lev
u8 avdd18_lev
u8 avdd28_lev
u8 avdd18_enable
u8 avdd28_enable
u8 config
u8 osc_type
u8 lptmr_flow
u32 btosc_hz
u32 osc_delay_us
u32 t1
u32 t2
u32 t3
u32 t4
struct power_pdata_t

Public Members

const power_param_t *power_param

唤醒原因

MAX_WAKEUP_PORT
MAX_WAKEUP_ANA_PORT
enum wakeup_reason_t

Values:

enumerator PWR_WK_REASON_PLUSE_CNT_OVERFLOW

pcnt唤醒复位

enumerator PWR_WK_REASON_P11

P11唤醒复位

enumerator PWR_WK_REASON_LPCTMU

触摸唤醒复位

enumerator PWR_WK_REASON_PORT_EDGE

数字io输入边沿唤醒复位

enumerator PWR_WK_REASON_ANA_EDGE

模拟io输入边沿唤醒复位

enumerator PWR_WK_REASON_VDDIO_LVD

vddio lvd唤醒复位

enumerator PWR_WK_REASON_WDT

vddio lvd看门狗唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_0

p33 index0 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_1

p33 index1 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_2

p33 index2 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_3

p33 index3 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_4

p33 index4 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_5

p33 index5 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_6

p33 index6 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_7

p33 index7 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_8

p33 index8 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_9

p33 index9 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_10

p33 index10 io下降沿唤醒复位

enumerator PWR_WK_REASON_FALLING_EDGE_11

p33 index11 io下降沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_0

p33 index0 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_1

p33 index1 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_2

p33 index2 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_3

p33 index3 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_4

p33 index4 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_5

p33 index5 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_6

p33 index6 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_7

p33 index7 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_8

p33 index8 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_9

p33 index9 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_10

p33 index10 io上升沿唤醒复位

enumerator PWR_WK_REASON_RISING_EDGE_11

p33 index11 io上升沿唤醒复位

enumerator PWR_ANA_WK_REASON_FALLING_EDGE_LDOIN

LDO5V下降沿唤醒复位

enumerator PWR_ANA_WK_REASON_FALLING_EDGE_VBATCH

VBATCH下降沿唤醒复位

enumerator PWR_ANA_WK_REASON_FALLINIG_EDGE_VBATDT

vbatdt下降沿唤醒复位

enumerator PWR_ANA_WK_REASON_FALLINIG_EDGE_CHARGEFULL

charge full下降沿唤醒复位

enumerator PWR_ANA_WK_REASON_RISING_EDGE_LDOIN

LDO5V上降沿唤醒复位

enumerator PWR_ANA_WK_REASON_RISING_EDGE_VBATCH

VBATCH上降沿唤醒复位

enumerator PWR_ANA_WK_REASON_RISING_EDGE_VBATDT

vbatdet上升沿唤醒复位

enumerator PWR_ANA_WK_REASON_RISING_EDGE_CHARGEFULL

chargefull上升沿唤醒复位

enumerator PINR_PND1_WKUP
enumerator PWR_RTC_WK_REASON_ALM

RTC闹钟唤醒复位

enumerator PWR_RTC_WK_REASON_256HZ

RTC 256Hz时基唤醒复位

enumerator PWR_RTC_WK_REASON_64HZ

RTC 64Hz时基唤醒复位

enumerator PWR_RTC_WK_REASON_2HZ

RTC 2Hz时基唤醒复位

enumerator PWR_RTC_WK_REASON_1HZ

RTC 1Hz时基唤醒复位

enumerator PWR_RTC_WK_REASON_PORT

RTC PR口边沿唤醒

enumerator PWR_WKUP_REASON_RESERVE

唤醒边沿

enum p33_io_wkup_edge_t

Values:

enumerator RISING_EDGE
enumerator FALLING_EDGE
enumerator BOTH_EDGE

唤醒边沿滤波时间

enum p33_io_wkup_flt_t

Values:

enumerator PORT_FLT_DISABLE
enumerator PORT_FLT_16us
enumerator PORT_FLT_128us
enumerator PORT_FLT_1ms
enumerator PORT_FLT_4ms

唤醒IO配置

bool is_wakeup_source(wakeup_reason_t index)

判断是否为指定唤醒源

Parameters

index – 唤醒源

Return values

1 – 是 0: 否

u32 is_gpio_wakeup(u32 gpio)
void p33_io_wakeup_port_init(const p33_io_wakeup_config_t *config)
void p33_io_wakeup_port_uninit(u32 gpio)

关闭IO唤醒功能

void p33_io_wakeup_filter(u32 gpio, p33_io_wkup_flt_t filter)

设置IO唤醒的滤波时间

void p33_io_wakeup_enable(u32 gpio, u32 enable)

使能IO唤醒功能

void p33_io_wakeup_edge(u32 gpio, p33_io_wkup_edge_t edge)

设置IO唤醒边沿

void p33_io_wakeup_set_callback(u32 gpio, void (*callback)(p33_io_wkup_edge_t edge))

设置IO唤醒回调

int p33_get_io_wakeup_port_used(u32 gpio)

IO是否设置了唤醒

Return values
  • index – 设置成功的index

  • -1 – 没有设置唤醒

struct p33_io_wakeup_config_t

Public Members

u32 gpio

唤醒io

u32 pullup_down_enable

内部上下拉是否使能

p33_io_wkup_flt_t filter

滤波参数

p33_io_wkup_edge_t edge

唤醒边沿条件

void (*callback)(p33_io_wkup_edge_t edge)

唤醒回调

复位原因(系统复位源)

enum rst_reason_t

Values:

enumerator MSYS_P11_RST
enumerator MSYS_P33_RST
enumerator MSYS_DVDD2_POR_RST
enumerator MSYS_DVDD_POR_RST
enumerator MSYS_SOFT_RST
enumerator MSYS_P2M_RST
enumerator MSYS_LPMR_RST
enumerator MSYS_POWER_RETURN
enumerator P11_PVDD_POR_RST
enumerator P11_LPMR_RST
enumerator P11_P33_RST
enumerator P11_P33_POR_RST
enumerator P11_WDT_RST
enumerator P11_SOFT_RST
enumerator P11_MSYS_RST
enumerator P11_WVDD_POR
enumerator P11_POWER_RETURN
enumerator P33_VDDIO_POR_RST
enumerator P33_VDDIO_LVD_RST
enumerator P33_WDT_RST
enumerator P33_VCM_RST
enumerator P33_MCLR_RST
enumerator P33_PPINR_RST
enumerator P33_P11_RST
enumerator P33_MSYS_RST
enumerator P33_SOFT_RST
enumerator P33_PPINR1_RST
enumerator P33_PPINR1_SOFT_RST
enumerator P33_POWER_RETURN
enumerator R3_VDDIO_RST
enumerator R3_SOFT_RST
enumerator R3_LV0_SOFT_RST
enumerator R3_POWER_RETURN
enumerator RST_REASON_RESERVE

复位原因(自定义复位源)

enum rst_flag_t

Values:

enumerator RESET_FLAG_RESERVE
enumerator EXCEPTION_FLAG
enumerator ASSERT_FLAG
enumerator UPDATE_FLAG
enumerator BT_FLAG
enumerator LP_OSC_UP_TO
bool is_reset_source(rst_reason_t index)

判断是否为指定复位源

Parameters

index – 复位源

Return values

1 – 是 0: 否

bool is_system_reset(rst_flag_t flag)

判断是否为指定系统软件复位源

Parameters

flag – 指定软件复位源

Return values

1 – 是 0: 否

void system_reset(rst_flag_t flag)

系统软复位,并指定复位信息

Parameters

flag:系统软复位源

Return values

1 – 是 0: 否

void latch_reset(void)

复位的时候锁存模拟模块状态,例如GPIO

Functions

void power_early_flowing(void)

系统电源开机初始化

void board_power_init(void)

系统电源板级初始化