This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] OMAP-L138:退出深度睡眠模式并恢复程序

Guru**** 2595770 points
Other Parts Discussed in Thread: SYSBIOS

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/585349/omap-l138-exit-deepsleep-mode-and-recovery-the-program

器件型号:OMAPL138B-EP
Thread 中讨论的其他器件:SYSBIOS

工具/软件:Starterware

尊敬的:

我已成功将器件置于深度睡眠模式。 但是、我无法恢复正常工作的问题。  

请帮我找出错误吗?

以下是我的代码:

静态空 DEEP_SLEEP_MODE (空)

//步骤1:DDR2的主动自刷新模式
//清除自刷新/低功耗(SR_PD)位为0
HWREG (SOC_DDR2_0_CTRL_regs + DDR2_mDDR_SDRCR)和=~DDR2_mDDR_SDRCR_SR_PD;
//设置低功耗模式使能
HWREG (SOC_DDR2_0_CTRL_regs + DDR2_mDDR_SDRCR)|= DDR2_mDDR_SDRCR_LPMODEN;

//步骤2:禁用 PHY SATA、USB2.0、USB1.1

//步骤3:将 PLL/PLLC0和 PLL/PLLC1置于旁路模式
/*PLLEN=0在 PLL0中将 PLL 置于旁路模式*/
HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)&=~PLLC_PLLCTL_PLLEN;
/*PLLEN=0在 PLL1中将 PLL 置于旁路模式*/
HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)&&=~PLLC_PLLCTL_PLLEN;

//步骤4:为 PLL 0和 PLL 1断电
PLL0中的/*PLLPWRDN=1 */
HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLPWRDN;
PLL1中的/*PLLPWRDN=1 */
HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLPWRDN;

//步骤5:将 DeepSleep 引脚配置为仅输入
//配置 GP0[8]-深度睡眠引脚-引脚编号9
uint32_t savePinmux =(HWREG (SOC_SYSCFG_0_regs + SYSCFG0_PINMUX (0))和
μ~(SYSCFG_PINMUX0_PINMUX0_31_28));
HWREG (SOC_SYSCFG_0_regs + SYSCFG0_PINMUX (0)=
(PINMUX0_GPIO0_8_ENABLE | savePinmux);
//将此引脚配置为仅输入
GPIODirModeSet (SOC_GPIO_0_regs、9、GPIO_DIR_INPUT);

//步骤6:SLEEPCOUNT 位的配置延迟(例如:0x0F)
HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DeepSleep)|=(0x0F 和 SYSCFG1_DeepSleep);

//步骤7:将 DeepSleep 中的 SLEEPENABLE 位设置为1
HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DEepSlep)|= SYSCFG1_DEepSlep_SLEEPENABLE;

//步骤8:轮询位 SLEEPCOMPLETE
while (~(SYSCFG1_DeepSlep_SLEEPCOMPLETE &
HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DeepSleep)))

//步骤9:将 DeepSleep 引脚驱动为低电平

/********* 退出深度睡眠模式 /

//步骤10:将 DeepSleep 中的 SLEEPENABLE 位清零
HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DEepSlep)&&=~SYSCFG1_DEEPSLE_SLEEPENABLE;

//步骤11:再次初始化 PLL
/*将 PLLCTL 中的 PLLRST 位清零*/
HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)&=~PLLC_PLLCTL_PLLRST;
HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)&&=~PLLC_PLLCTL_PLLRST;
/*清除 PLLCTL*中的 PLLPWRDN 位*/
HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)&=~PLLC_PLLCTL_PLLPWRDN;
HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)&=~PLLC_PLLCTL_PLLPWRDN;
/*将 PLLCTL 中的 PLLRST 位设置为1 -复位结束*/
HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLRST;
HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLRST;
/*等待 PLL 锁定*/
/*等待300次计数*/
延迟(300);
/*将 PLLCTL 中的 PLLEN 位置1 -删除旁路模式*/
HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLEN;
HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLEN;

//步骤12:启用时钟 DDR
/*启用 SDRAM 的时钟*/
PSCModuleControl (SOC_PSC_1_regs、HW_PSC_DDR2_mDDR、0、PSC_MDCTL_NEW_ENABLE);
/*在 DDR Phy*/中设置 RESET_PHY 位
HWREG (SOC_DDR2_0_CTRL_regs + DDR2_MDR_DRPYCRC)= DDR2_mDDR_DRPYRCR_RESET_PHY;
/*清除 SDRCR*/中的 MCLKSTOPEN 位
HWREG (SOC_DDR2_0_CTRL_regs + DDR2_mDDR_SDRCR)&&=~DDR2_mDDR_SDRCR_MCLKSTOPEN;
/*禁用自刷新率*/
//清除低功耗模式
HWREG (SOC_DDR2_0_CTRL_regs + DDR2_mDDR_SDRCR)&&=~DDR2_mDDR_SDRCR_LPMODEN;

此致、Nghia Quy

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Nguyen:

    我已将此事转交给专家。 他们的反馈应发布在此处。

    BR
    Tsvetolin Shulev
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在专家思考时有一些猜测。

    您的睡眠计数线:

    HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DeepSleep)|=(0x0F 和 SYSCFG1_DeepSleep);

    复位值为0xFFFF 时、可能会导致转换计数为0xFFFF。 在设置之前、不会清除睡眠计数位。 如下所示:

    HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DeepSleep)=
    (((HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DEepSleep)&~SYSCFG1_DEepSlep_SLEEPCOUNT)| 0x000F);

    我假设您的代码正在为 SLEEPCOMPLETE 循环。 您应该在深度睡眠模式中进行多路复用、而不是 GP0[8]。 跳过 GP0[8]代码。 奇怪的是、StarterWare 头文件未定义 pinmux DeepSleep 的常量。 使用默认值。

    uint32_t savePinmux =(HWREG (SOC_SYSCFG_0_regs + SYSCFG0_PINMUX (0))和
    μ~(SYSCFG_PINMUX0_PINMUX0_31_28));
    HWREG (SOC_SYSCFG_0_regs + SYSCFG0_PINMUX (0)=
    (SYSCFG_PINMUX0_PINMUX0_31_28_DEFAULT<<SYSCFG_PINMUX0_PINMUX0_31_28_SHIFT | savePinmux);

    我建议将代码放入 L2 RAM (DSP)或 L3 RAM (ARM)中、以将深度睡眠问题与 DDR 唤醒问题分开。

    您有两个有关此主题的主题。 这里的另一个:
    e2e.ti.com/.../585264

    将其留给主持人进行整理。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好、Norman、

    感谢您的回答、它非常有帮助。
    关于 sleepcount、您是对的、我修复了我的代码。
    关于 GP0[8]:我是这样做的、然后我在 JTAG 调试时通过 View GPIO 寄存器进行检查。
    3.我使用#pragma 将代码放入 Share_RAM 区域、然后查看.map 文件进行检查

    进入深度睡眠模式后、程序仍然无法唤醒。

    现在、我尝试检查 PLL0/1的进程关闭、然后开启是否正确。
    结果是在关闭 PLL 0/1后、我想这个过程是成功的、因为电流消耗确实急剧下降。
    然后我尝试打开 PLL 0/1、但在设置 PLLCTL 中的 PLLEN 位后、程序将不执行任何操作、它跳转至未知地址0xFFFFFF0010。

    我不知道为什么。 请帮助我修复此错误吗?
    我正在使用 SYS/BIOS、这里是我的代码测试(仅关闭 PLL、然后打开 PLL):
    静态空 DEEP_SLEEP_MODE (空)

    //关闭 PLL
    /*PLLEN=0在 PLL0中将 PLL 置于旁路模式*/
    HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)&=~PLLC_PLLCTL_PLLEN;
    /*PLLEN=0在 PLL1中将 PLL 置于旁路模式*/
    HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)&&=~PLLC_PLLCTL_PLLEN;

    延迟(4);

    //步骤4:为 PLL 0和 PLL 1断电
    PLL0中的/*PLLPWRDN=1 */
    HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLPWRDN;
    PLL1中的/*PLLPWRDN=1 */
    HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLPWRDN;


    /********* 退出深度睡眠模式 /

    //打开 PLL
    /*将 PLLCTL 中的 PLLRST 位清零*/
    HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)&=~PLLC_PLLCTL_PLLRST;
    /*设置 PLL 禁用输出*/
    HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLDIS;
    /*清除 PLLCTL*中的 PLLPWRDN 位*/
    HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)&=~PLLC_PLLCTL_PLLPWRDN;
    /*启用切换*/
    HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)&=~PLLC_PLLCTL_PLLDIS;
    /*等待300次计数*/
    延迟(300);
    /*将 PLLCTL 中的 PLLRST 位设置为1 -复位结束*/
    HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLRST;
    /*等待400次计数*/
    延迟(400);
    /*将 PLLCTL 中的 PLLEN 位置1 -删除旁路模式*/
    HWREG (SOC_PLLC_0_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLEN;
    //程序将跳转到未知地址

    /*将 PLLCTL 中的 PLLRST 位清零*/
    HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)&&=~PLLC_PLLCTL_PLLRST;
    /*设置 PLL 禁用输出*/
    HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLDIS;
    /*清除 PLLCTL*中的 PLLPWRDN 位*/
    HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)&=~PLLC_PLLCTL_PLLPWRDN;
    /*启用切换*/
    HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)&&=~PLLC_PLLCTL_PLLDIS;
    /*等待300次计数*/
    延迟(300);
    /*将 PLLCTL 中的 PLLRST 位设置为1 -复位结束*/
    HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLRST;
    /*等待 PLL 锁定*/
    /*等待400次计数*/
    延迟(400);
    /*将 PLLCTL 中的 PLLEN 位置1 -删除旁路模式*/
    HWREG (SOC_PLLC_1_regs + PLLC_PLLCTL)|= PLLC_PLLCTL_PLLEN;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    有一次、我设法通过其他节能功能将 C6748置于深度睡眠模式。 通过 RTC 唤醒、因为我的板未暴露深度睡眠引脚。 与裸机 StarterWare 完全相同。 没有 SYSBIOS 经验。 人们会希望这种东西能够被建立起来。 希望 SYSBIOS 专家能够发表评论。

    您在上一篇文章中未清楚您已多路复用的引脚。 不要多路复用到 GPIO 控制器。 使用深度睡眠连接。 如果我正在正确读取您的帖子、
    -您已成功地将处理器置于深度睡眠状态
    -您通过 DeepSleep 引脚成功唤醒处理器、即在 sleepcomplete 位上退出循环
    -您在重新启动 PLL 时遇到问题
    理论上、您可以保持 PLL 不变、并使用非常慢的时钟继续执行。 SYSBIO 计时器和调度可能不喜欢它。

    PLL 配置比较复杂。 我必须查看我的笔记、如果我发现任何问题、请返回给您。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在修改 PLLEN 之前、PLL 代码可能缺少 PLLENSRC 的清零。 此外、您可能还必须解锁 PLL 寄存器。 请参阅 CFGCHIP0:PLL_MASTER_LOCK 和 CFGCHIP3:PLL1_MASTER_LOCK。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Norman、

    感谢您的反馈。

    我修复了 PLL 配置错误、它与更改 PLLEN 位时的等待周期有关。

    我看到、我的程序在轮询循环中存根 SLEEPCOMPLETE 位。 然后、我将 PINMUX0的配置更改为 DeepSleep (非 GPIO 输入)、但程序仍在 while 环路中存根。

    下面是我的配置 DeepSleep 引脚和环路:

    #define PINMUX0_31_28_DeepSleep (0x0FFFFFFF)

    //配置 GP0[8]-深度睡眠引脚-引脚编号9
    savePinMux = HWREG (SOC_SYSCFG_0_regs + SYSCFG0_PINMUX (0));
    HWREG (SOC_SYSCFG_0_regs + SYSCFG0_PINMUX (0))= PINMUX0_31_28_DeepSleep & savePinMux;
    //步骤6:SLEEPCOUNT 位的配置延迟(例如:0x0F)
    HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DeepSleep)=\
    ((HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DeepSleep)和
    ~SYSCFG1_DEEPSLEEPCOUNT)| 0x000F);

    //步骤7:将 DeepSleep 中的 SLEEPENABLE 位设置为1
    HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DEepSlep)|= SYSCFG1_DEepSlep_SLEEPENABLE;

    //步骤8:轮询位 SLEEPCOMPLETE
    操作

    唤醒= SYSCFG1_DeepSlep_SLEEPCOMPLETE 和 HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DeepSleep);

    while (0 =唤醒);

    HWREG (SOC_SYSCFG_1_regs + SYSCFG1_DEepSlep)&&=~SYSCFG1_DEEPSLE_SLEEPENABLE;

    我在这里有什么错误吗?

    非常感谢您、

    Nghia Quy

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    pinmux 代码取决于 PINMUX0的复位值为零。 应该是哪种、但仅在以下情况下:

    savePinmux =(HWREG (SOC_SYSCFG_0_regs + SYSCFG0_PINMUX (0))
    savePinmux &=~(SYSCFG_PINMUX0_PINMUX0_31_28));
    savePinmux ||(<SYSCFG_PINMUX0_PINMUX0_31_28_SHIFT);
    HWREG (SOC_SYSCFG_0_regs + SYSCFG0_PINMUX (0))= savePinmux;

    只需检查一下、哪个 PAD 尝试切换进入/退出睡眠模式? 否则、它应该起作用。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的快速回复 、但我认为我并不真正理解您的想法。 您是不是说我应该使用代码块而不是我的代码块: //配置 GP0[8]-深度睡眠引脚-引脚编号9 savePinMux = HWREG (SOC_SYSCFG_0_regs + SYSCFG0_PINMUX (0)); HWREG (SOC_SYSCFG_0_regs + SYSCFG_0_RESP0_PINMUX (0)= SYSCMDIP0);HWREG (0)= SYSCMDIEP_INSLE_0)= 0 (步骤28) 0x0F) 我将进行测试并向您提供反馈。 您的问题"哪个部分正在尝试切换进入/退出睡眠模式?" 您是指 ARM 还是 DSP 器件? 我使用这两个器件、因此我正在尝试控制器的所有器件都进入深度睡眠模式、然后退出此模式。 再次感谢 您、Nghia Quy
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    抱歉、我的眼睛错过了 PINMUX0_31_28_DeepSleep 定义中的第一个零点。 这确实意味着字段 PINMUX0_31_28设置为零。

    焊盘编号是 F4、它是多路复用的 RTC_ALARM/GP0[8]/UART2_CTS/DeepSleep。 在 LCDK 上、此焊盘未连接。 我假设您使用的是定制板、并且您没有将焊盘用于其他功能之一。 文档说明 DeepSleep 引脚通常为高电平、低电平有效。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好、Norman、

    我使用的是定制板、只使用 F4引脚实现深度睡眠功能。
    通常、该引脚为高电平、仅在设置深度睡眠时才会变为低电平状态。

    我真的不明白为什么程序不退出 while 循环。 配置是如此清楚和合乎逻辑。
    使用 C6748时、是否使用 JTAG 进行调试?
    我正在使用 JTAG、但在 DeepSleep 引脚为低电平后、电路板无法立即保持与 CCS 的连接。 因此、我无法在进入深度睡眠模式后调试电路板的状态(即使之后深度睡眠引脚更改为高电平)。
    你像我一样错过了这个问题吗?

    谢谢、
    Nghia Quy
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好,Tsvetolin Shulev,

    我仍在等待您专家的反馈。
    这是一个关键问题。
    因此、请帮助我解决此问题。

    此致、
    Nghia Quy
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好、Norman、

    在 TI 文档中、第10.10.3部分"深度睡眠序列":
    步骤5. DeepSleep 引脚被驱动为高电平并启用片上振荡器。

    请帮我回答一些问题。
    什么是片上振荡器? 我是否需要配置寄存器以启用片上振荡器?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好  

    您将看到 TRM 和数据表中提到的片上振荡器作为内部振荡器或晶体振荡器。 无需寄存器即可启用此功能。

    您可以将 PLLCTRL 寄存器位 CLKMODE 设置为1、但总体而言、这不会对深度睡眠功能产生任何影响(对功耗的影响很小)  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    回到手头的问题... 在 DeepSleep 引脚处理方面、很难对您的代码和/或定制板可能出现的问题进行代码审计。

    也许您可以尝试查看是否使用 RTC 报警,允许您从深度睡眠中可靠地恢复相同的代码。
    为了保持这种简单-您应该尝试使用
    1) 1)在器件上电默认状态下测试此情况、其中 PLL 被旁路等
    2) 2)将所有内容保留在内部记忆中(我相信您现在是根据 Norman 的建议这样做的)
    3) 3)从 DeepSleep 唤醒、但不重新配置 PLL。

    --
    这里是一些旧的代码片段、我认为这应该足够好、以便进入深度睡眠模式并通过 RTC 警报从其恢复... 这可能会有所帮助

    --
    #if defined (_TMS470__)
    #define TARGET_ISA 'A' //ARM926EJ
    #Elif defined (_TMS3206X)
    #define TARGET_ISA 'D'(定义目标_ISA //C64x
    #endif

    #define PDCCMD_REG *(UINT32易失性*) 0x01810000

    /*PLL0控制器控制寄存器*/
    #define PLL0_BASE_ADDR0x01C11000
    #define PLL0_PLLCTL(PLL0_base_ADDR + 0x100)/* PLL 控制寄存器*/
    #define PLL0_OCSEL(PLL0_BASE_ADDR + 0x104)/* OBSCLK 选择寄存器*/
    #define PLL0_SECCTL(PLL0_BASE_ADDR + 0x108)/* PLL 次级控制寄存器*/
    #define PLL0_PLLM(PLL0_BASE_ADDR + 0x110)/* PLL 乘法器控制寄存器*/
    #define PLL0_PREDIV(PLL0_BASE_ADDR + 0x114)/* PLL 预分频器控制寄存器*/
    #define PLL0_PLLDIV1(PLL0_BASE_ADDR + 0x118)/* PLL 控制器 Div1寄存器*/
    #define PLL0_PLLDIV2(PLL0_BASE_ADDR + 0x11C)/* PLL 控制器 Div2寄存器*/
    #define PLL0_PLLDIV3(PLL0_BASE_ADDR + 0x120)/* PLL 控制器 Div3寄存器*/
    #define PLL0_OSCDIV1(PLL0_BASE_ADDR + 0x124)/*振荡器分频器寄存器*/
    #define PLL0_POSTDIV(PLL0_BASE_ADDR + 0x128)/* PLL 后分频寄存器*/
    #define PLL0_BPDIV(PLL0_BASE_ADDR + 0x12C)/*旁路分频器寄存器*/
    #define PLL0_WAKEUP(PLL0_BASE_ADDR + 0x130)/*唤醒寄存器*/
    #define PLL0_PLLCMD(PLL0_BASE_ADDR + 0x138)/* PLL 控制器命令寄存器*/
    #define PLL0_PLLSTAT(PLL0_BASE_ADDR + 0x13C)/* PLL 控制器状态寄存器*/
    #define PLL0_ALNCTL(PLL0_BASE_ADDR + 0x140)/* PLL 控制器时钟对齐控制寄存器*/
    #define PLL0_DCHANGE(PLL0_BASE_ADDR + 0x144)/* PLLDiv 比率更改状态寄存器*/
    #define PLL0_CKEN(PLL0_BASE_ADDR + 0x148)/*时钟使能控制寄存器*/
    #define PLL0_CKSTAT(PLL0_BASE_ADDR + 0x14C)/*时钟状态寄存器*/
    #define PLL0_SYSTAT(PLL0_BASE_ADDR + 0x150)/* SYSCLK 状态寄存器*/
    #define PLL0_PLLDIV4(PLL0_BASE_ADDR + 0x160)/* PLL 控制器 Div4寄存器*/
    #define PLL0_PLLDIV5(PLL0_BASE_ADDR + 0x164)/* PLL 控制器 Div5寄存器*/
    #define PLL0_PLLDIV6(PLL0_BASE_ADDR + 0x168)/* PLL 控制器 Div6寄存器*/
    #define PLL0_PLLDIV7(PLL0_BASE_ADDR + 0x16C)/* PLL 控制器 Div7寄存器*/
    #define PLL0_PLLDIV8(PLL0_BASE_ADDR + 0x170)/* PLL 控制器 Div8寄存器*/
    #define PLL0_PLLDIV9(PLL0_BASE_ADDR + 0x174)/* PLL 控制器 Div8寄存器*/

    /*PLL1控制器控制寄存器*/
    #define PLL1_BASE_ADDR0x01E1A000
    #define PLL1_PLLCTL(PLL1_BASE_ADDR + 0x100)/* PLL 控制寄存器*/
    #define PLL1_OCSEL(PLL1_BASE_ADDR + 0x104)/* OBSCLK 选择寄存器*/
    #define PLL1_SECCTL(PLL1_BASE_ADDR + 0x108)/* PLL 次级控制寄存器*/
    #define PLL1_PLLM(PLL1_BASE_ADDR + 0x110)/* PLL 乘法器控制寄存器*/
    #define PLL1_PREDIV(PLL1_BASE_ADDR + 0x114)/* PLL 预分频器控制寄存器*/
    #define PLL1_PLLDIV1(PLL1_BASE_ADDR + 0x118)/* PLL 控制器 Div1寄存器*/
    #define PLL1_PLLDIV2(PLL1_BASE_ADDR + 0x11C)/* PLL 控制器 Div2寄存器*/
    #define PLL1_PLLDIV3(PLL1_BASE_ADDR + 0x120)/* PLL 控制器 Div3寄存器*/
    #define PLL1_OSCDIV1(PLL1_BASE_ADDR + 0x124)/*振荡器分频器寄存器*/
    #define PLL1_POSTDIV(PLL1_BASE_ADDR + 0x128)/* PLL 后分频器寄存器*/
    #define PLL1_BPDIV(PLL1_BASE_ADDR + 0x12C)/*旁路分频器寄存器*/
    #define PLL1_WAKEUP(PLL1_BASE_ADDR + 0x130)/*唤醒寄存器*/
    #define PLL1_PLLCMD(PLL1_BASE_ADDR + 0x138)/* PLL 控制器命令寄存器*/
    #define PLL1_PLLSTAT(PLL1_BASE_ADDR + 0x13C)/* PLL 控制器状态寄存器*/
    #define PLL1_ALNCTL(PLL1_BASE_ADDR + 0x140)/* PLL 控制器时钟对齐控制寄存器*/
    #define PLL1_DCHANGE(PLL1_BASE_ADDR + 0x144)/* PLLDiv 比率更改状态寄存器*/
    #define PLL1_CKEN(PLL1_BASE_ADDR + 0x148)/*时钟使能控制寄存器*/
    #define PLL1_CKSTAT(PLL1_BASE_ADDR + 0x14C)/*时钟状态寄存器*/
    #define PLL1_SYSTAT(PLL1_BASE_ADDR + 0x150)/* SYSCLK 状态寄存器*/
    #define PLL1_PLLDIV4(PLL1_BASE_ADDR + 0x160)/* PLL 控制器 Div4寄存器*/
    #define PLL1_PLLDIV5(PLL1_BASE_ADDR + 0x164)/* PLL 控制器 Div5寄存器*/
    #define PLL1_PLLDIV6(PLL1_BASE_ADDR + 0x168)/* PLL 控制器 Div6寄存器*/
    #define PLL1_PLLDIV7(PLL1_BASE_ADDR + 0x16C)/* PLL 控制器 Div7寄存器*/
    #define PLL1_PLLDIV8(PLL1_BASE_ADDR + 0x170)/* PLL 控制器 Div8寄存器*/
    #define PLL1_PLLDIV9(PLL1_BASE_ADDR + 0x174)/* PLL 控制器 Div8寄存器*/

    /*SYSCFG0寄存器*/
    #define SYSCFG0_BASE_ADDR 0x01C14000
    #define SYSCFG0_KICK0 (SYSCFG0_BASE_ADDR + 0x38)/*KICK0寄存器*/
    #define SYSCFG0_KICK1 (SYSCFG0_BASE_ADDR + 0x3C)/* KICK1寄存器*/
    #define SYSCFG0_PINMUX0 (SYSCFG0_BASE_ADDR + 0x120)/* PINMUX0寄存器*/

    /*SYSCFG1寄存器*/
    #define SYSCFG1_BASE_ADDR 0x01E2C000
    #define SYSCFG1_DDRSLEW (SYSCFG1_BASE_ADDR + 0x04)
    #define SYSCFG1_DEEPSLEEP (SYSCFG1_BASE_ADDR + 0x08)
    #define SYSCFG1_PUPDEN (SYSCFG1_BASE_ADDR + 0x0C)
    #define SYSCFG1_PUPDSEL (SYSCFG1_BASE_ADDR + 0x10)
    #define SYSCFG1_RXACTIVE (SYSCFG1_BASE_ADDR + 0x14)

    /*RTC 寄存器*/
    #define RTC_BASE_ADDR 0x01C23000
    #define RTC_second(RTC_BASE_ADDR + 0x00)
    #define RTC_MINUTE(RTC_BASE_ADDR + 0x04)
    #define RTC_Hour(RTC_BASE_ADDR + 0x08)
    #define RTC_DAY(RTC_BASE_ADDR + 0x0C)
    #define RTC_MONTH(RTC_BASE_ADDR + 0x10)
    #define RTC_year(RTC_BASE_ADDR + 0x14)
    #define RTC_DOTW(RTC_BASE_ADDR + 0x18)
    #define RTC_ALMSEC(RTC_BASE_ADDR + 0x20)
    #define RTC_CTRL(RTC_BASE_ADDR + 0x40)
    #define RTC_STATUS(RTC_BASE_ADDR + 0x44)
    #define RTC_INTR(RTC_BASE_ADDR + 0x48)
    #define RTC_OSC(RTC_BASE_ADDR + 0x54)
    #define RTC_KICK0R(RTC_BASE_ADDR + 0x6C)
    #define RTC_KICK1R(RTC_BASE_ADDR + 0x70)

    /*定时器寄存器*/
    #define TMR_BASE_ADDR 0x01C20000
    #define TMR_TIM12(TMR_BASE_ADDR + 0x10)
    #define TMR_PRD12(TMR_BASE_ADDR + 0x18)
    #define TMR_TCR(TMR_BASE_ADDR + 0x20)
    #define TMR_TGCR(TMR_BASE_ADDR + 0x24)

    /*额外变量*/
    #define RTC_RESET_TIME2288

    unsigned int main()

    unsigned int 计数器;

    /****配置深度睡眠****/
    //1. DDR2/mDDR 应采用时钟门控
    //-无需配置。 默认时钟门控

    //2. 应禁用 SATA PHY
    //-无需配置。 默认禁用

    //3. 应禁用 USB2.0 PHY
    //-无需配置。 默认禁用

    //4. 应禁用 USB1.1 PHY
    //-无需配置。 默认禁用

    //5. PLL 应置于旁路模式(清除 PLLCTL 寄存器中的 PLLEN 位)
    //-无需配置。 旁路模式中的默认值

    //6. PLL 应掉电(设置 PLLCTL 寄存器中的 PLLPWRDN 位)
    //-无需配置。 默认断电

    //7. 将所需的唤醒时间配置为 RTC 中的警报
    *(unsigned int*) TMR_TIM12= 0x00000000;
    *(unsigned int*) TMR_PRD12= 0xFFFFFFFF;
    *(unsigned int*) TMR_TGCR=(*(unsigned int*) TMR_TGCR &~0x000C)| 0x0004;//双路、非链路模式
    *(unsigned int*) TMR_TGCR=(*(unsigned int*) TMR_TGCR &~0x0001)| 0x0001;//未处于复位状态
    *(unsigned int*) TMR_TCR=(*(unsigned int*) TMR_TCR &~0x00C0)| 0x0080;//连续启用

    *(unsigned int*) RTC_KICK0R = 0x83E70B13;//解锁 RTC 寄存器
    *(unsigned int*) RTC_KICK1R = 0x95A4F1E0;

    *(unsigned int*) RTC_OSC=(*(unsigned int*) RTC_OSC &~0x0020)| 0x0020;//软件复位
    计数器=*(无符号 int*) TMR_TIM12 + RTC_RESET_TIME;
    while (*(unsigned int*) TMR_TIM12 <计数器){}

    *(unsigned int*) RTC_ALMSEC =*(unsigned int*) RTC_ALMSEC | 0x0015;//设置警报(15秒)
    *(unsigned int*) RTC_INTR=*(unsigned int*) RTC_INTR | 0x0008;//启用警报

    *(unsigned int*) RTC_CTRL=*(unsigned int*) RTC_CTRL | 0x0081;//启用分离电源并启动 RTC

    //while ((*(unsigned int*) RTC_STATUS & 0x0040)=0){}//测试警报的额外代码

    //8. 将 PINMUX0_31_28配置为 RTC_ALARM 的输出。
    *(unsigned int*) SYSCFG0_KICK0 = 0x83E70B13;
    *(unsigned int*) SYSCFG0_KICK1 = 0x95A4F1E0;
    *(unsigned int*) SYSCFG0_PINMUX0 =*(unsigned int*) SYSCFG0_PINMUX0 &~0xF0000000;
    *(unsigned int*) SYSCFG0_PINMUX0 =*(unsigned int*) SYSCFG0_PINMUX0 | 0x20000000;

    //9. 在 SLEEPCOUNT 中配置所需的延迟
    *(unsigned int*) SYSCFG1_DeepSleep =*(unsigned int*) SYSCFG1_DeepSleep &~0xFFFF;//将 sleepcount 设置为0

    //10. 设置 DeepSleep 中的 SLEEPENABLE 位。 自动清除 SLEEPCOMPLETE 位。
    *(unsigned int*) SYSCFG1_DeepSleep =*(unsigned int*) SYSCFG1_DeepSleep | 0x8000000;//启用 DeepSleep

    //11. 开始轮询 SLEEPCOMPLETE、直至其设置为1 (器件唤醒后置1)
    while ((*(unsigned int*) SYSCFG1_DeepSleep & 0x40000000)==0){}//等待设备从 DeepSleep 模式中退出

    //12. 清除 DeepSleep 中的 SLEEPENABLE 位
    *(unsigned int*) SYSCFG1_DeepSleep =*(unsigned int*) SYSCFG1_DeepSleep &~0x8000000;//禁用 DeepSleep

    asm (" idle");

    //永远不应该到达这里
    返回(1);

    ----
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此外、还有一些关于 SysBIOS 等的问题
    在 SYSBIOS 下,我们仍然有 PWRM 模块,它显示了一些睡眠模式的情况,作为发行的一部分,PMI/PSC 库中将有其他代码,您可以将这些代码用作参考。

    processors.wiki.ti.com/.../Power_Module_for_C6748_and_OMAP-L138
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    自从我在 C6748 LCDK 上体验深度睡眠功能以来、已经有大约5年了。 我模糊地记得 JTAG 确实会停止运行、CCS 对此非常讨厌。 我必须重置电路板并重新启动 CCS 才能恢复。 稍后,我发现可以使用“Run->Free Run”保持连接。 这意味着没有单步执行代码。 我依靠 UART 和 GPIO 来告诉我睡眠的进度。

    您是否尝试注释 SLEEPCOMPLETE 循环以检查唤醒代码是否正常?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    @Norman:谢谢您的回答、我尝试对 SLEEPCOMPLETE 循环进行注释、唤醒过程很好。

    @Mukul:感谢您的反馈、我将尝试测试您的示例代码、但 RTC 现在在我的当前硬件中不可用、因此我需要花一点时间来修改我的电路板。

    今天、我尝试测试示例代码以检查 DeepSleep 函数。

    我的硬件包括:

    • 连接到 DeepSleep 引脚(GP0[8])的按钮、默认为高电平。
    • 引脚 GP6[14]是用于调试的输出引脚

    我的软件过程是:

    • 我按下按钮以启用深度睡眠模式、然后释放以进行唤醒、并在 GP6[14]中持续施加脉冲
    • 如果程序从深度睡眠模式唤醒、它将在 GP6[14]引脚中具有一个方波脉冲。

    结果是:

    1. 大多数情况下、程序未从深度睡眠模式唤醒
    2. 有时、如果我快速按下然后释放按钮、程序将唤醒并在 GP6[14]中具有脉冲
    3. 但是、我在示波器上观察到、在深度睡眠引脚电平从低电平变为高电平(黄色线)之前、GP6[14](蓝色线)中有一个脉冲。 这意味着在 DeepSleep 引脚从低电平变为高电平之前、程序会被唤醒。 根据理论,这是不可能的。

    有人可以帮助我了解这些结果吗?

    我为您的调试附加了.cmd 和源文件。

    e2e.ti.com/.../DeepsleepTest.c

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    一些注释、假设 DeepSlepTest.c 是完整的测试代码:

    1) 1)您可以将 DeepSleep 引脚的引脚复用器移出环路。

    2) 2)代码 DeepSlepTest.c 没有任何 PLL 关闭和重新启动。 我相信你必须至少这样做。 DeepSleep 信号将门控时钟、PLL 将丢失其参考时钟。 从我在论坛上看到的情况来看、处理器不像抖动 PLL、往往会锁定。 这可能是当处理器进入 DeepSleep 时发生的情况。 在这里、注释掉 SLEEPCOMPLETE 循环是 PLL 关断和重启的启动测试、无需进入深度睡眠模式。 DDR 停止/启动以及任何其他 PSC 停止/启动代码也是如此。

    3) 3) DeepSleep 信号失效前的明显唤醒可能是由于您的开关抖动所致。 按下按钮后、它会立即取消置位。 您可能需要添加某种去抖电阻/电容器。 我是固件、无法推荐值或原理图。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    最后、我可以在 OMAP 中执行深度睡眠模式。
    您说得对、在我的代码 DEepSlepTest.c 中、我必须添加 PLL 关断并重新启动。

    非常感谢 Norman 和 Mukul Bhatnagar 为您提供的帮助、

    此致、
    Quy Nguyen
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您更新该主题。 很高兴听到您正在正常运行。
    感谢 Norman 为此提供的支持、以便为您提供正确的调试路径。