最近在研究 S32K314 +SBC FS26的低功耗解决方案(使用NXP提供的MCAL ,V2.0.3, AS4.4.0)
MCU应用为BOOT + APP 的模式,未使用自带的OTA功能;
1. 参考及关键参数说明
基本的休眠唤醒步骤及其配置可以参考如下的博客,写的通俗易懂。
S32K3_Power(低功耗) standby模式配置与唤醒(wakeup)-- 基于Mcal层_s32k3 standby-CSDN博客
这篇文章主要对于休眠前和唤醒后的详细步骤做另外说明:
先梳理一下所需要的知识点:
如图:截取于S32K3XXRM
1.VDD_HV_B (Main I/O voltage supply, 主电源)
2.VDD_HV_A (Other I/O domain voltage supply 其他电源)
3.V15 (High-current input for core or logic supply from either an external BJT or from direct 1.5 V external supply)大电流输入,影响PLL)
4 Last Mile Regulator :直译最后一英里调节监控,来判断当前输入的V15是否满足MCU的工作要求
5. FIRC :快速内部参考时钟
FS26提供MCU的 VDD_HV_B,VDD_HV_A ,由 FS26_LDO2 提供;FS26提供MCU的 V15 ,由 FS26_VCORE提供;(V15也可以由BJT方式提供,这里我们不选择该方案)
LMAUTOEN: 自动使能标志,如果使能,则上电会自动判断
LMEN : LM是否启用
LMSTAT :显示当前LM的状态
详细处理在MCU_INIT()函数中体现,不详细描述。
正文开始:
2.休眠前:
主要流程: 1.sbc先进入休眠;
2.mcu再进入休眠;
mcu 的soc standby模式下,flash会掉电,mcu会停止工作;所以必须先让sbc进入standby模式;
在这个点下问题就出现了:
sbc进入standby模式后,会将ldo2,vcore电源关闭;这样就会导致mcu无法正常工作导致出现异常;
需要将ldo2配置为在standby模式下也可以正常输出;
但是vcore就不允许设置,vcore提供v15电源,所以我们需要失能Last Mile Regulator;
为此引申出来一个前模式即SOC_PREPARE_STANDBY;
调用Mcu_SetMode(SOC_PREPARE_STANDBY):mcu会将Last Mile Regulator关闭,进入低速run模式,将v15与mcu芯片内部断开;
下一步,调用spi接口操作sbc,你会发现进入了硬件错误中断,这是因为进入这个模式下,spi的参考时钟被更改,所以在进入这个模式前需要去初始化spi ,spi_deinit,然后在进入SOC_PREPARE_STANDBY模式后,再初始化spi,如果spi使用了dma,也需要把dma重新初始化。
继续调用:
Icu_EnableEdgeDetection(IcuChannel_0);
Icu_EnableWakeup(IcuChannel_0);
Mcu_SetMode(SOC_STANDBY):
设置完唤醒源,再进入休眠,如果休眠电流过大,请在睡眠前关闭各类外设。
完整流程:
Spi_DeInit();
Mcu_SetMode(PREPARE_STANDBY);
Mcu_InitClock(Clock_Standby);
Spi_Init(NULL_PTR);
Icu_Init(NULL_PTR);
Icu_EnableEdgeDetection(IcuChannel_0);
Icu_EnableWakeup(IcuChannel_0);
Sbc_SetPowerState(SBC_REG_LDO1,false);
Sbc_SetPowerState(SBC_REG_LDO2,true);
Sbc_GoToStandby();
Mcu_SetMode(SOC_STANDBY);
3.唤醒后:
由于我们在vbatt上电的时候使用了 Last Mile Regulator , 使用了PLL, 则V15是必不可少的;
但是我们的fs26处于standby模式,vcore是关闭的,mcu在重新开始跑的时候会卡死在MCU_INIT出不来,唤醒失败;
为了解决这个问题:
我们需要在启动时先使用FIRC内部参考时钟,不开启LM,类似于 SOC_PREPARE_STANDBY模式,再唤醒SBC之后再使能PLL时钟;
因为使用的是boot + app的设计方案,我们仅需要在boot启动时配置成上述模式:
Mcu_Init(&Mcu_Config);
Mcu_InitClock(McuClockSetting_PreStandby);
Mcu_SetMode(McuModeSettingPreStandby);
此时mcu正常工作;