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.

[参考译文] TM4C123AH6PM:深度睡眠偶尔无法唤醒- GPIO

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1040239/tm4c123ah6pm-deep-sleep-fails-to-wake-up-occasionally---gpio

器件型号:TM4C123AH6PM
主题中讨论的其他器件:TM4C123

您好!

我们有一个项目、其中具有 TM4C123的电路板一直处于通电状态。 为了避免耗尽电池电量、策略是将其降至深度睡眠模式(它不会真正执行任何操作、只需在特定 GPIO 中通过脉冲唤醒它)。 它不是休眠、因为唤醒脉冲未路由到方便的休眠 GPIO、因此深度睡眠是我们可以达到的最佳状态。  当系统从休眠状态中唤醒时、它只是复位、以便我们拥有完全新鲜的状态。

它运行得很好、几乎总是... 然而、即使脉冲信号在那里是确认的、电路板偶尔也不会被唤醒。

我们确实查看了一些有关勘误表 HIB#01的帖子、并尝试从这些帖子中添加一些代码、但老实说、我并不完全理解建议的解决方案、足够的代码、我甚至不确定原因是所述的勘误问题。

/*
 * Puts the system in DeepSleep mode
 * This function will only exit when an interrupt caused by EXP_GPIO_PIN is triggered
 */
void TaskSystemDeepSleep(void)
{
    /* Now enable the interrupt for the wake up pin */
    GPIOIntRegister(EXP_GPIO_BASE, TaskDeepSleepISR);
    GPIOIntTypeSet(EXP_GPIO_BASE, EXP_GPIO_PIN, GPIO_RISING_EDGE);
    IntEnable(EXP_GPIO_INT);
    GPIOIntClear(EXP_GPIO_BASE, 0xFF);
    GPIOIntEnable(EXP_GPIO_BASE, EXP_GPIO_PIN);

    /* Disabled Peripherals */
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_ADC0);
	    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_ADC1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_CAN0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_CAN1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_COMP0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_EMAC0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_EPHY0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_EPI0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOB);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOC);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOD);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOE);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOF);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOG);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOH);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOJ);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_HIBERNATE);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_CCM0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_EEPROM0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_FAN0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_FAN1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOK);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOL);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOM);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPION);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOP);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOQ);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOR);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOS);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOT);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C2);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C3);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C4);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C5);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C6);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C7);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C8);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C9);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_LCD0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_ONEWIRE0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_PWM0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_PWM1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_QEI0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_QEI1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_SSI0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_SSI1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_SSI2);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_SSI3);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER2);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER3);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER4);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER5);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER6);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER7);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART2);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART3);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART4);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART5);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART6);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART7);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UDMA);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_USB0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_WDOG0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_WDOG1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_WTIMER0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_WTIMER1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_WTIMER2);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_WTIMER3);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_WTIMER4);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_WTIMER5);

    /* Enabled Peripherals */
    SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOA);		// Should not be needed but just in case...
    SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_GPIOA);

    /*
     * There is a HW bug regarding deep sleep. See these posts:
     * e2e.ti.com/.../tm4c123ge6pm-tm4c123gxl-deep-sleep-mode-issue
     * e2e.ti.com/.../964156
     */

    /* DeepSleep configurations */
    SysCtlPeripheralClockGating(true);
    /* Function below is for TM4C123 devices */
    SysCtlDeepSleepClockSet(SYSCTL_DSLP_DIV_1 | SYSCTL_DSLP_OSC_INT30 | SYSCTL_DSLP_PIOSC_PD);
    /* Function below is for TM4C129 devices */
    // SysCtlDeepSleepClockConfigSet(1, (SYSCTL_LDO_SLEEP|SYSCTL_TEMP_LOW_POWER|SYSCTL_FLASH_LOW_POWER|SYSCTL_SRAM_LOW_POWER));
    SysCtlDeepSleepPowerSet(SYSCTL_LDO_SLEEP|SYSCTL_TEMP_LOW_POWER|SYSCTL_FLASH_LOW_POWER|SYSCTL_SRAM_LOW_POWER);
    SysCtlLDODeepSleepSet(SYSCTL_LDO_0_90V);        // Select LDO to Scale to 0.9V in Deep Sleep

    while (!canWakeUp)
    {
        HWREG(HIB_CTL) |= HIB_CTL_CLK32EN | HIB_CTL_OSCDRV;
        SysCtlDelay(SYSTEM_CLOCK_HZ/2);	// Wait for 1500 ms
        HibernateRTCSet (0);
    	HibernateRTCTrimSet (0x7FFF);
        SysCtlDeepSleep();
    }
    /* Code will never come here unless the interrupt was caused by EXP_GPIO_PIN */
	
	HWREG(NVIC_APINT) = (NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ);
}

以上 是配置和启动深度睡眠的函数。

/*
 * Specific ISR for deep sleep mode, makes sure that only the EXP_GPIO pin wakes the board up
 */
void TaskDeepSleepISR(void)
{
    uint32_t intFlags;
    intFlags = GPIOIntStatus(EXP_GPIO_BASE, false);     // false means we are concerned about unmasked interrupts
    GPIOIntClear(EXP_GPIO_BASE, intFlags);

    if (intFlags & EXP_GPIO_PIN)
    {
        canWakeUp = true;
    }
}

然后、我们有相关的 ISR。 想法是让 GPIO 触发中断、将系统唤醒到 ISR 中、检查原因是否为预期引脚、并设置 canWakeUp、这将重置主控代码。

有什么关于如何调试和解决此问题的想法吗?

谢谢

布鲁诺

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

    您好、Bruno、

     很高兴再次听到您的声音! 已经有一段时间了。  

     我已经阅读了你的帖子以及你提到的其他两篇帖子、这些帖子都是 Chester 回答的。 但是、目前我没有关于您的问题的答案。 我也不明白为什么 HIB#1的权变措施 会对深度睡眠产生任何影响、因为您甚至不像我所理解的那样使用 RTC。 您仅使用深度睡眠模式。  

     当您说它在大部分时间都能正常工作时、您能否用百分比来详细说明它何时无法唤醒?

     其他唤醒脉冲是否会唤醒器件?

     此问题是否在您拥有的所有电路板上都可重复出现?

     我不知道原因是否是您下面配置中的某些设置所致。 我想您正在尝试使用可实现最低深度睡眠电流消耗的设置。 在实验中、我想知道您是否更改了其中的一些设置、它是否会产生任何影响?

    SysCtlDeepSlepClockSet (SYSCTL_DSLP_DIV_1 | SYSCTL_DSLP_OSC_INT30 | SYSCTL_DSLP_PIOSC_PD);
    下面的/*函数用于 TM4C129器件*/
    // SysCtlDeepSlepClockConfigSet (1、(SYSCTL_LDO_SLEEP|SYSCTL_TEMP_LOW_POWER|SYSCTL_FLASH_LOW_POWER|SYSCTL_FLASH_LOW_POWER|SYSCTL_SRAM_LOW_POWER);
    SysCtlDeepSleep PowerSet (SYSCTL_LDO_SLEEP|SYSCTL_TEMP_LOW_POWER|SYSCTL_FLASH_LOW_POWER|SYSCTL_SRAM_LOW_POWER);
    SysCtlLDODeepSlepSet (SYSCTL_LDO_0_90V);

       

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

    嘿 Charles、感谢您的评论和快速回复!

    是的、生活有点太忙了、除了紧急情况、我甚至不能梦想享受一些论坛时间!

    无论如何、请遵循您的建议:

    -我删除了所有与休眠相关的内容(实际上,我发布的代码会崩溃,除非首先启用休眠模块)。

    -将 LDO 电压从0.90增加到1.00V。

    这似乎解决了这个问题。

    至于您的其他问题、其他唤醒脉冲不会唤醒器件(当系统的其余部分开启时、信号实际上是一个2Hz 连续方波)。 我们尚未在其他电路板中进行测试。 经过6-8次尝试后、它将失败...

    无论如何、我可以说您的建议是解决问题的关键-再次感谢。

    谢谢

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

    太早了,无法庆祝
    几个小时后、它再次无法唤醒...  :(

    这是一个密封外壳、无法轻松访问重置按钮、从而增加了人身伤害。

    我将进一步提高 LDO、看看它是否会产生任何影响。

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

    您好、Bruno、

     当您将 LDO 电压升高到1.0V 并运行几个小时时、它会告诉我0.9V 时的电源太低或太小、晶体管无法正常工作。 我希望您可以根据数据表将 LDO 升至高于1.08V。  

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

    我很确定我刚刚在另一台计算机上回复了、但消息不在这里...
    无论如何、我已将 LDO 提升至1.2V 的最大设置(在此阶段、我们对低功耗并不关心)
    测试了大约40次、结果完美。 但是、在电路板深度睡眠几个小时后、它 仍然无法唤醒...

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

    您好、Bruno、

     是否有更多更新?

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

    您好、Charles、

    最后一次尝试是将 LDO 设置为1.2V、这是我围绕这些参数找到的最高宏。 这仍然没有解决这个问题(今天早上它不会唤醒-但我也只能唤醒...)

    我刚刚读过 LDO 调整:Tivaware 用户指南说该器件有一个内部 LDO ... 默认设置为2.5V。 我很困惑、为什么 SysCtlLDODeepSlepSet 参数大约为1V、但仍未查看。

    此外、我还想启用和实现一个中断例程来处理 SysClt 事件、例如 LDO 故障、振荡器故障等、如果该线路上出现问题、可能会尝试完全复位... 但我还没有亲自动手、今天稍后将尝试寻找时间。

    我们非常感谢您提出的任何建议和意见。  ;)