本帖最后由 小恩GG 于 2021-2-7 11:26 编辑
【经验分享】RT10XX SNVS唤醒源识别 一, 文档描述
SNVS功耗模式作为MIMXRT10XX中的极低功耗模式,只有极少部分模块可以工作,比如RTC。从IMXRT低功耗特性应用笔记AN12085中,可以获悉SNVS功耗模式的唤醒源:
可以知道,唤醒源可以是GPIO也就是WAKEUP引脚唤醒,还可以是RTC唤醒,另外还有终极唤醒就是POR。
那么实际使用中,如何区分是POR唤醒还是SNVS的唤醒源唤醒的呢? 第一想法,就像SDK低功耗代码那样,可以通过系统复位控制器的SRC_SRSR寄存器去查看,比如位ipp_reset_b, 可以表示power-up sequence复位。但是实际测试下来,发现进入SNVS模式之后,不论是WAKEUP pin唤醒还是POR唤醒,都会导致ipp_reset_b位置1,那么到底如何去区分POR唤醒和SNVS唤醒源WAKUP引脚唤醒呢?下面将详细讲解。
二,SNVS POR与SNVS唤醒源区分
SNVS低功耗可以通过SW或者ON/OFF按键进入,然后片上DCDC模块会关闭,PMIC_ON_REQ引脚也会输出低去通知外部。从SOC的角度,SNVS和POR上电是一样的,所以会导致SRC_SRSR[ipp_reset_b]都是1,不论是POR还是SNVS唤醒源唤醒SNVS模式。 解决方案:利用SNVS_LP_GPR通用寄存器去区分。 从IMIMXRT106XSRM文档中,我们可以知道,SNVS_LP模块是一直上电的模块,也就是说纵然进入了SNVS低功耗模式,但是SNVS_LP模块还是一直供电的,所以我们可以利用SNVS_LP_GPR通用寄存器在进入SNVS模式之前,写入特定数据,然后等待进入SNVS模式,并且唤醒,查看SNVS_LP_GPR寄存器的值是否还有,如果是POR,那么所有的SNVS_LP_GPR将会清零,但是如果是SNVS唤醒源唤醒,则SNVS_LP_GPR的值还会保持。 SNVS_LP_GPR寄存器可以使用软件存储256位数据。 在操作SNVS_LP_GPR寄存器的时候还需要注意配置SNVS_LPCR[GPR_Z_DIS]位为1, 关闭当security事件发生的时候GPR寄存器清零。 实际上,如果GPR_Z_DIS默认为0,如果不配置为1, 写了GPR寄存器之后,读出来的数据依旧是0,所以需要先置1 GPR_Z_DIS,再写GPR寄存器。 下面以MIMXRT1064 SDK的power_mode_switch_rtos为例测试SNVS POR与SNVS唤醒源情况。 代码修改如下: static void PowerModeSwitchTask(void*pvParameters) 函数中修改SNVS模式如下:
- #if (HAS_WAKEUP_PIN)
- else if (LPM_PowerModeSNVS == s_targetPowerMode)
- {
- SNVS->LPCR |= 1<<24;
- PRINTF("1:SNVS_LP GPPR0=0X%X \r\n",SNVS->LPGPR[0]);
- SNVS->LPGPR[0] = 0XA5;
- PRINTF("2:SNVS_LP GPPR0=0X%X \r\n",SNVS->LPGPR[0]);
- APP_GetWakeupConfig(s_targetPowerMode);
- APP_SetWakeupConfig(s_targetPowerMode);
- APP_PowerPreSwitchHook(s_targetPowerMode);
- LPM_EnterSNVS();
- }
- #endif
复制代码 添加了GPR_Z_DIS=1, GPR[0]写入具体数据并且查看的代码。 Main代码中,添加打印GPR[0]数据的寄存器值,这样可以判别POR或者SNVS唤醒源区别。 - PRINTF("SNVS wakeup:SNVS_LP GPPR0=0X%X \r\n",SNVS->LPGPR[0]);
复制代码 如果SNVS->LPGPR[0]=0, 则是POR唤醒,如果SNVS->LPGPR[0]=0XA5,则是SNVS WAKEUP 引脚唤醒。 测试结果如下:
综上可以看出,添加了SNVS_LP_GPR寄存器之后,确实可以识别SNVS模式是POR唤醒还是WAKEUP引脚唤醒。 附件添加修改后的MCUXPresso IDE工程代码,希望对涉及到该块的网友有所帮助。 |