当前文档版本为 v1.0.2,您可以访问当前页面的 开发中 版本以获取最近可能的更新。

LowPower: Standby Mode 1 LP Timer Wakeup

1 功能概述

本例程演示如何使 SoC 进入 Stnadby Mode 1 状态,然后通过内部 LP Timer 定时将其唤醒。

2 环境准备

  • 硬件设备与线材:

    • PAN1080 EVB 核心板底板各一块

    • JLink 仿真器(用于烧录例程程序)

    • 电流计(本文使用电流可视化测量设备 PPK2 [Nordic Power Profiler Kit II] 进行演示)

    • USB-TypeC 线一条(用于底板供电和查看串口打印 Log)

    • 杜邦线数根(用于连接各个硬件设备)

  • 硬件接线:

    • 为确保能够准确地测量 SoC 本身的功耗,排除底板外围电路的影响,请勿将 EVB 核心板插到 EVB 底板上

    • 使用 USB-TypeC 线,将 PC USB 插口与 EVB 底板 USB->UART 插口相连

    • 使用杜邦线将(根据核心板芯片的型号不同,以下两种接法二选一):

      • EVB 底板上的 TX0 引脚与核心板上的 P00 引脚相连, EVB 底板上的 RX0 引脚与核心板上的 P01 引脚相连(若核心板芯片为 QFN32 或 LQFP64 封装)

      • EVB 底板上的 TX0 引脚与核心板上的 P30 引脚相连, EVB 底板上的 RX0 引脚与核心板上的 P31 引脚相连(若核心板芯片为 QFN48 封装)

    • 使用杜邦线将 JLink 仿真器的:

      • SWD_CLK 引脚与 EVB 核心板的 P46 引脚相连

      • SWD_DAT 引脚与 EVB 核心板的 P47 引脚相连

      • SWD_GND 引脚与 EVB 核心板的 GND 引脚相连

    • 将 PPK2 硬件的:

      • USB DATA/POWER 接口连接至 PC USB 接口

      • VOUT 引脚连接至 EVB 核心板的 VBAT 引脚

      • GND 引脚连接至 EVB 核心板的 GND 引脚

  • PC 软件:

    • 串口调试助手(UartAssist)或终端工具(SecureCRT),波特率 921600(用于接收串口打印 Log)

    • nRF Connect Desktop(用于配合 PPK2 测量 SoC 电流)

3 编译和烧录

例程位置:zephyr\samples_panchip\low_power\standby_m1_lptmr_wakeup

使用 ZAL 工具擦除 Flash 程序。关于 ZAL 工具的详细介绍请参考:Zephyr APP Launcher 工具介绍

4 例程演示说明

  1. PC 上打开 PPK2 Power Profiler 软件,供电电压选择 3300 mV,然后打开供电开关:

    image

    PPK2 使能芯片供电

    测试芯片中目前还没有程序,所以看到此时芯片耗电保持在 3mA 左右。

  2. 使用 ZAL 工具将编译后的例程烧录至芯片

    烧录成功后,最好断开 JLink 与芯片的连接以防止芯片 P46 和 P47 两个引脚有漏电情况发生

  3. 从串口工具中看到如下的打印信息:

    Try to load HW calibration data.. DONE.
    - Chip Type         : 0x80
    - Chip CP Version   : None
    - Chip FT Version   : 5
    - Chip MAC Address  : D0000C0293CA
    - Chip Flash UID    : 31373237300A29494330FFFFFFFFFFFF
    - Chip Flash Size   : 1024 KB
    *** Booting Zephyr OS build zephyr-v2.7.0-1347-g4073b5da347f  ***
    
    Reset Reason: NVIC System Reset.
    
    Busy wait 1s to keep SoC in active mode..
    
    Now try to enter SoC standby mode 1 with specific lptmr timeout..
    
    Try to load HW calibration data.. DONE.
    - Chip Type         : 0x80
    - Chip CP Version   : None
    - Chip FT Version   : 5
    - Chip MAC Address  : D0000C0293CA
    - Chip Flash UID    : 31373237300A29494330FFFFFFFFFFFF
    - Chip Flash Size   : 1024 KB
    *** Booting Zephyr OS build zephyr-v2.7.0-1347-g4073b5da347f  ***
    
    Reset Reason: Standby Mode 1 LP Timer Wakeup.
    
    Busy wait 1s to keep SoC in active mode..
    
    Now try to enter SoC standby mode 1 with specific lptmr timeout..
    

    由上述 Log 可得知以下信息:

    • 第一次芯片 Reset 原因为 NVIC System Reset,这是因为本次芯片是程序烧录后由 JLink 触发的软件 Reset

    • 接着芯片在 Active 状态下等待了 1s,随后进入了 Standby Mode 1 状态

    • 约 5s 后,芯片从 Standby Mode 1 下醒来并复位,此次 Reset 原因为 Standby Mode 1 LP Timer Wakeup

    • 然后芯片继续在 Active 状态下等待 1s,随后重新进入了 Standby Mode 1 状态

    • 如此往复

  4. 此时观察芯片电流波形:

    image

    使用 LP Timer 将芯片从 Standby Mode 1 模式下唤醒

    由电流波形看出芯片在 Standby Mode 1 状态下保持了 5s(此状态下电流为 1.4uA 左右),然后被唤醒并触发复位, 重新初始化后又进入 Standby Mode 1 模式等待再次唤醒

5 开发者说明

5.1 App Config 配置

本例程的 App Config(对应 prj.conf 文件)配置如下:

# Low Power
CONFIG_PM=y
CONFIG_BT_CTLR_SLEEP_CLOCK_SOURCE=1

# Disable Serial Uart & Log.
# CONFIG_SERIAL=n
# CONFIG_UART_INTERRUPT_DRIVEN=n
# CONFIG_CONSOLE=n
# CONFIG_UART_CONSOLE=n
# CONFIG_PRINTK=n

# Forcely calibrate 32K RCL Clock
CONFIG_SOC_FORCE_CALIB_RCL_CLK=y

# Enable DC/DC
CONFIG_SOC_DCDC_PAN1080=y

其中:

  • CONFIG_PM=y:使能低功耗流程

  • CONFIG_BT_CTLR_SLEEP_CLOCK_SOURCE=1:低功耗时钟相关配置(目前必须固定配置为1)

  • CONFIG_SOC_FORCE_CALIB_RCL_CLK=y:在系统初始化阶段强制校准内部 32K RCL Clock 时钟(若当前使用的芯片为校准后的芯片,则此开关也可以不开以节约系统启动时间)

  • CONFIG_SOC_DCDC_PAN1080=y:使能芯片的 DCDC 供电模式,以降低芯片动态功耗

5.2 App DeviceTree 配置

本例程的 App DeviceTree(对应 app.overlay 文件)配置如下:

&uart1 {
	status = "disabled";
};

&clk_xtl {
	/* Frequency of XTL clock, DO NOT CHANGE THIS ITEM */
	clock-frequency = <32768>;
	/* Enable/Disable the external 32768 Hz low speed crystal oscillator */
	status = "disabled";
};

&clk_rcl {
	/* Frequency of RCL clock, DO NOT CHANGE THIS ITEM */
	clock-frequency = <32000>;
	/* Enable/Disable the internal 32 KHz Low Speed RC */
	status = "okay";
};

&dpll {
	/* f(dpll_output) = f(dpll_input) / clock_div * clock_mult */
	clocks = <&clk_xth>;
	clock-div = <2>;  /* Fixed to 2 */
	clock-mult = <4>; /* Can be 3 (48MHz) or 4 (64MHz) */
	status = "okay";
};

&rcc {
	clock-names = "clk_system", "clk_slow";
	clocks = <&dpll &clk_rcl>;
	clock-frequency-system = <DT_FREQ_M(64)>;
	clock-frequency-slow = <32000>;
	ahb-prescaler = <1>;
	apb1-prescaler = <1>;
	apb2-prescaler = <1>;
};

其中:

  • uart1status 属性配置为 disabled 以禁止系统上电后初始化 uart1 设备,确保不会因为 uart1 的引脚配置产生 IO 漏电

  • clk_xtlstatus 属性配置为 disabled 以禁用 32768Hz XTL 低速晶振(此为 SDK 默认配置)

  • clk_rclstatus 属性配置为 okay 以打开 32kHz RCL 内部低速时钟(此为 SDK 默认配置)

  • dpllclock-mult 属性配置为 4 以将 DPLL 时钟输出配置为 64MHz(此为 SDK 默认配置)

  • rcc 的:

    • clocks 属性的第 1 项(clk_system)配置为 dpll 以将系统高速时钟(AHB 总线时钟)源选择为 DPLL 时钟(此为 SDK 默认配置)

    • clocks 属性的第 2 项(clk_slow)配置为 clk_rcl 以使系统使用 32kHz RCL 内部低速时钟(此为 SDK 默认配置)

    • clock-frequency-slow 属性配置为 32000 以告诉系统当前使用的低速时钟频率为 32000 Hz(此为 SDK 默认配置)

5.3 程序代码

5.3.1 主程序

主程序 main() 函数内容如下:

void main(void)
{
	uint8_t rst_reason;
	uint32_t lptmr_cnt;

	/* Get the last reset reason */
	printk("\nReset Reason: ");
	rst_reason = soc_reset_reason_get();
	switch (rst_reason) {
	case SOC_RST_REASON_PIN_RESET:
		printk("nRESET Pin Reset.\n");
		break;
	case SOC_RST_REASON_SYS_RESET:
		printk("NVIC System Reset.\n");
		break;
	case SOC_RST_REASON_STBM1_LPTMR_WAKEUP:
		printk("Standby Mode 1 LP Timer Wakeup.\n");
		break;
	default:
		printk("Unhandled Reset Reason, refer to more reason define in soc.h!\n");
	}

	printk("\nBusy wait 1s to keep SoC in active mode..\n");
	k_busy_wait(1000000);

	printk("\nNow try to enter SoC standby mode 1 with specific lptmr timeout..\n\n");

#ifdef CONFIG_SERIAL
	/* Waiting for UART Tx done and re-set UART IO before entering standby mode 1 to avoid current leakage */
	reset_uart_io();
#endif
	/* Convert timeout in milliseconds to LP Timer Count */
	lptmr_cnt = LPTMR_TIMEOUT_MS * PAN_RCC_CLOCK_FREQUENCY_SLOW / 1000ull;
	/* Enter standby mode 1 */
	soc_enter_standby_mode_1(STBM1_WAKEUP_SRC_LPTMR, STBM1_RETENTION_SRAM_NONE, lptmr_cnt);

#ifdef CONFIG_SERIAL
	/* Set IO pinmux to UART again */
	set_uart_io();
#endif
	printk("WARNING: Failed to enter SoC standby mode 1 due to unknown reason.\n");

	while (1) {
		/* Busy wait */
	}
}
  1. 获取本次系统复位的原因,本例程中仅检测 3 种情况(更多复位情况请参考 soc.h 文件中的相关定义):

    • 芯片 nRESET 引脚复位(nRESET 按键按下)

    • NVIC System Reset 软件复位(JLink 烧录后自动触发,或者软件调用 sys_reboot(0) 触发)

    • Standby Mode 1 LP Timer Wakeup 唤醒复位

  2. 将 UART Pinmux IO 恢复为默认的 GPIO 状态

  3. 使芯片进入 Standby Mode 1 模式,并配置为 LP Timer 唤醒,唤醒时间为 5s,且所有 SRAM 均不保持

    需要注意 soc_enter_standby_mode_1() 接口第三个参数为 LP Timer 定时,其单位为 32K Clock Count,而不是时间, 因此在使用过程中需要将预期定时的时间 LPTMR_TIMEOUT_MS 通过程序中的公式转换为 32K Count 后再将其传入函数中。

  4. 若芯片未成功进入 Standby Mode 1 模式,则重新配置 UART Pinmux IO 状态并打印 Warning log

5.3.2 UART 引脚 Pinmux 配置与恢复

若芯片在使用过程中有诸如 UART 等外设模块配置了 IO,则芯片在进入低功耗状态前,要考虑将其 Pinmux 功能切换为 GPIO 功能; 若有必要,还需在芯片唤醒后将其功能切换回 UART 等功能以继续使用。

#ifdef CONFIG_SERIAL
__ramfunc static void reset_uart_io(void)
{
	/* Wait until all UART0 data sending done before entering low power mode */
	while (!(UART_GetLineStatus(UART0) & UART_LINE_TXSR_EMPTY)) {
		/* Busy wait */
	}

	/*
	 * Reset UART PINs to GPIO function and disable digital input path of UART Rx PIN
	 * to avoid possible current leakage.
	 */
	SYS_SET_MFP(P0, 0, GPIO);
	SYS_SET_MFP(P0, 1, GPIO);
	GPIO_DisableDigitalPath(P0, BIT1);
}

__ramfunc static void set_uart_io(void)
{
	/* Resume UART PIN Configurations to reenable UART function */
	SYS_SET_MFP(P0, 0, UART0_TX);
	SYS_SET_MFP(P0, 1, UART0_RX);
	GPIO_EnableDigitalPath(P0, BIT1);
}
#endif
  1. reset_uart_io() 函数用于:

    • 等待串口 Log 数据都打印完毕(即 UART0 Tx FIFO 应为空)

    • P00 引脚 Pinmux 功能由 UART0 Tx 切换回 GPIO

    • P01 引脚 Pinmux 功能由 UART0 Rx 切换回 GPIO,并将其数字输入功能关闭

  2. set_uart_io() 函数用于:

    • P00 引脚 Pinmux 功能由 GPIO 重新切换成 UART0 Tx

    • P01 引脚 Pinmux 功能由 GPIO 重新切换成 UART0 Rx,并将其数字输入功能重新打开

6 RAM/Flash资源使用情况

Memory region         Used Size  Region Size  %age Used
FLASH:       19184 B       384 KB      4.88%
SRAM:        6952 B        64 KB     10.61%