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.

CCS/TM4C123GH6PM: hibernate (HIBERNATE_INT_RTC_MATCH_0) sometimes can not wake-up

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL

Tool/software: Code Composer Studio

Hello,

We use EK-TM4C123GXL for test hibernate function, reference code form SW-TM4C-DRL-UG-2.1.0.12573 USER’S GUIDE page 318 and  qs-rgb project file.

We tested  HibernateRTCMatchSet wake-up time of 60 sec , 15 sec or 600 sec, Can not wake-up at different times,  but when we set a wake-up every 60 seconds,

can not wake up in 644 +60  seconds.. Reference is as follows: Please help us reslove this issue.

:

Thanks

by HC. Huang

  • Hi,

     I'm not clear with your description. I understand you have problem with waking up from hibernate mode. I don't know how to interpret your terminal window. What is (644 / 600)? What does 644 indicate and what does 600 indicate? You said 'but when we set a wake-up every 60 seconds, can not wake up in 644 +60  seconds.' What does this mean?

      I will suggest you download the latest TivaWare which is version 2.1.4.178 and try to see if it makes a difference on the behavior. 

  • Hi Charles,
    The "644" is free rum counter value read from RTC module , 600 is a invaild data, The RTC starts at 0 when TM4C is reset.
    We set every 18 seconds into deep sleep mode, 60 seconds after the wake up . First tiem into deep sleep mode will be RTC 18 and wake up from HIBERNATE_INT_RTC_MATCH_0 "RTC (18+60) ", Next times into deep sleep will be RTC 96 and wake up from RTC 156
    .......Then attached image RTC 644 is into deep sleep mode of time , so accuracy wake up time is a RTC 708 but it is not wake up.

    modify code as following for you reference.

    void AppHibernateEnter(void)
    {
    uint32_t ui32RtcMatch;
    //
    // Alert UART command line users that we are going to hibernate
    //
    SysTickDisable();
    SysTickIntDisable();

    HibernateRTCEnable();
    ROM_SysCtlPeripheralClockGating(true);
    HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC);

    //
    // Store state information to battery backed memory
    // since sizeof returns number of bytes we convert to words and force
    // a rounding up to next whole word.
    //
    HibernateDataSet((uint32_t*)&g_sAppState, sizeof(tAppState)/4+1);

    ui32RtcMatch = HibernateRTCGet() + 60;
    HibernateRTCMatchSet(0, ui32RtcMatch); // HC
    if (ui32RtcMatch != HibernateRTCMatchGet(0))
    UARTprintf("Match counter error...\n");
    //HC HibernateRTCMatchSet(0, 60);
    HibernateIntEnable(HIBERNATE_INT_RTC_MATCH_0);
    HibernateIntClear(HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_LOW_BAT | HIBERNATE_INT_RTC_MATCH_0);

    // Disable the LED for 100 milliseconds to let user know we are
    // ready for hibernate and will hibernate on relase of buttons
    //
    RGBDisable();
    SysCtlDelay(SysCtlClockGet()/3/10);
    RGBEnable();

    SysCtlDelay(100);

    //
    // Disable the LED for power savings and go to hibernate mode
    //
    RGBDisable();
    SysTickDisable();
    SysTickIntDisable();

    HibernateIntRegister(HibernateHandler);

    SysCtlDeepSleep();

    UARTprintf("RTC MATCH INT...\n");

    UARTprintf("Wake Up from Deep sleep...\n");

    //
    // Initialize the SysTick interrupt to process colors and buttons.
    //
    SysTickPeriodSet(SysCtlClockGet() / APP_SYSTICKS_PER_SEC); // 50 ms
    SysTickEnable();
    SysTickIntEnable();
    IntMasterEnable();

    HibernateDataGet((uint32_t*) &g_sAppState, sizeof(tAppState) / 4 + 1);

    UARTprintf("RTC Count: (%u / 600)\n\r", HibernateRTCGet());

    RGBEnable();

    ui32HibModeEntryCount = 0;
    g_sAppState.ui32Mode = APP_MODE_NORMAL;
    }


    void HibernateHandler(void)
    {
    uint32_t ui32Status;
    //
    // Get the interrupt status and clear any pending interrupts.
    //
    ui32Status = HibernateIntStatus(1);
    HibernateIntClear(ui32Status);

    //
    // Process the RTC match 0 interrupt.
    //
    if(ui32Status & HIBERNATE_INT_RTC_MATCH_0)
    {
    //UARTprintf("RTC MATCH INT...\n");
    }
    }
  • Hi Hong Chun,
    Thanks for the clarification. Now I understand how you enter and wake from hibernate mode. Where is the code that goes into deepsleep after 18s? In your code you call SysCtlDeepSleep() but I don't see prior to the call a timer of 18s is introduced. Perhaps I'm missing something. Can you please clarify? Otherwise, I don't really spot anything obvious that is incorrect. Perhaps one thing you can also try is to comment out all the UARTprintf() inside the AppHibernateEnter(). It is not that anything wrong with the UARTprintf() but I just wanted to know if there is any effect with them. In the past I came to know that having them in an ISR can sometimes affect the ISR exit time. Even though it may not be the case for you but please give a try.
  • Hi Charles,

    Main loop control of the 18s Please refer to the following, on the UARTprintf () after the release of hibernate.

    //*****************************************************************************
    //
    // Main function performs init and manages system.
    //
    // Called automatically after the system and compiler pre-init sequences.
    // Performs system init calls, restores state from hibernate if needed and
    // then manages the application context duties of the system.
    //
    //*****************************************************************************
    int
    main(void)
    {
    uint32_t ui32Status;
    uint32_t ui32ResetCause;
    int32_t i32CommandStatus;


    //
    // Enable stacking for interrupt handlers. This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPUEnable();
    ROM_FPUStackingEnable();

    //
    // Set the system clock to run at 40Mhz off PLL with external crystal as
    // reference.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
    SYSCTL_OSC_MAIN);

    //
    // Enable the hibernate module
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);

    //
    // Enable and Initialize the UART.
    //
    ConfigureUART();

    UARTprintf("Welcome to the Tiva C Series TM4C123G LaunchPad!\n");
    UARTprintf("Type 'help' for a list of commands\n");
    UARTprintf("> ");

    //
    // Determine why system reset occurred and respond accordingly.
    //
    /*HC
    ui32ResetCause = SysCtlResetCauseGet();
    SysCtlResetCauseClear(ui32ResetCause);
    if(ui32ResetCause == SYSCTL_CAUSE_POR)
    {
    if(HibernateIsActive())
    {
    //
    // Read the status bits to see what caused the wake.
    //
    ui32Status = HibernateIntStatus(0);
    HibernateIntClear(ui32Status);

    //
    // Wake was due to the push button.
    //
    if(ui32Status & HIBERNATE_INT_PIN_WAKE)
    {
    UARTprintf("Hibernate Wake Pin Wake Event\n");
    UARTprintf("> ");

    //
    // Recover the application state variables from battery backed
    // hibernate memory. Set ui32Mode to normal.
    //
    HibernateDataGet((uint32_t*) &g_sAppState,
    sizeof(tAppState) / 4 + 1);
    g_sAppState.ui32Mode = APP_MODE_NORMAL;
    }

    //
    // Wake was due to RTC match
    //
    else if(ui32Status & HIBERNATE_INT_RTC_MATCH_0)
    {
    UARTprintf("Hibernate RTC Wake Event\n");
    UARTprintf("> ");
    //
    // Recover the application state variables from battery backed
    // hibernate memory. Set ui32Mode to briefly flash the RGB.
    //
    HibernateDataGet((uint32_t*) &g_sAppState,
    sizeof(tAppState) / 4 + 1);
    g_sAppState.ui32Mode = APP_MODE_HIB_FLASH;
    }
    }

    else
    {
    //
    // Reset was do to a cold first time power up.
    //
    UARTprintf("Power on reset. Hibernate not active.\n");
    UARTprintf("> ");

    g_sAppState.ui32Mode = APP_MODE_NORMAL;
    g_sAppState.fColorWheelPos = 0;
    g_sAppState.fIntensity = APP_INTENSITY_DEFAULT;
    g_sAppState.ui32Buttons = 0;
    }
    }
    else
    {
    //
    // External Pin reset or other reset event occured.
    //
    UARTprintf("External or other reset\n");
    UARTprintf("> ");

    //
    // Treat this as a cold power up reset without restore from hibernate.
    //
    g_sAppState.ui32Mode = APP_MODE_NORMAL;
    g_sAppState.fColorWheelPos = APP_PI;
    g_sAppState.fIntensity = APP_INTENSITY_DEFAULT;
    g_sAppState.ui32Buttons = 0;

    //
    // colors get a default initialization later when we call AppRainbow.
    //
    }
    */
    UARTprintf("External or other reset\n");
    UARTprintf("> ");

    g_sAppState.ui32Mode = APP_MODE_NORMAL;
    g_sAppState.fColorWheelPos = APP_PI;
    g_sAppState.fIntensity = APP_INTENSITY_DEFAULT;
    g_sAppState.ui32Buttons = 0;

    //
    // Initialize clocking for the Hibernate module
    //
    HibernateEnableExpClk(SysCtlClockGet());
    HibernateRTCSet(0); // HC
    HibernateRTCEnable(); // HC

    //
    // Initialize the RGB LED. AppRainbow typically only called from interrupt
    // context. Safe to call here to force initial color update because
    // interrupts are not yet enabled.
    //
    RGBInit(0);
    RGBIntensitySet(g_sAppState.fIntensity);
    AppRainbow(1);
    RGBEnable();

    //
    // Initialize the buttons
    //
    ButtonsInit();

    //
    // Now Program for Deep Sleep Mode: Auto Clock Gating
    //
    SysCtlPeripheralClockGating(true);

    //
    // Program which peripherals are to be gated and which have to remain
    // enabled in deep sleep
    //
    SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_GPIOF);
    SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_HIBERNATE);
    /*
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_ADC1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOB);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOC);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_GPIOE);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_I2C0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART3);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_UART5);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER0);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER1);
    SysCtlPeripheralDeepSleepDisable(SYSCTL_PERIPH_TIMER2);
    */
    //
    // Select Deep Sleep Clock Source as LFIOSC div by 1
    //SYSCTL_DSLP_OSC_INT30
    //ROM_SysCtlDeepSleepClockSet(SYSCTL_DSLP_DIV_1 | SYSCTL_DSLP_OSC_EXT32|SYSCTL_DSLP_PIOSC_PD); // Set deep sleep
    ROM_SysCtlDeepSleepClockSet(SYSCTL_DSLP_DIV_1 | SYSCTL_DSLP_OSC_EXT32|SYSCTL_DSLP_MOSC_PD); // Set deep sleep

    /*
    SysCtlDeepSleepClockConfigSet( 64,
    ( SYSCTL_DSLP_OSC_INT30 | SYSCTL_DSLP_PIOSC_PD |
    SYSCTL_DSLP_MOSC_PD ) );
    */

    //
    // Select power Mode to put Flash and SRAM in low Power mode
    // Select LDO in Sleep Mode and TS to be powered down
    //
    SysCtlDeepSleepPowerSet(SYSCTL_LDO_SLEEP|SYSCTL_TEMP_LOW_POWER|SYSCTL_FLASH_LOW_POWER|SYSCTL_SRAM_LOW_POWER);

    //
    // Select LDO to Scale to 0.9V in Deep Sleep
    //
    SysCtlLDODeepSleepSet(SYSCTL_LDO_0_90V);


    //
    // Initialize the SysTick interrupt to process colors and buttons.
    //
    SysTickPeriodSet(SysCtlClockGet() / APP_SYSTICKS_PER_SEC);
    SysTickEnable();
    SysTickIntEnable();
    IntMasterEnable();

    //
    // spin forever and wait for carriage returns or state changes.
    //
    while(1)
    {

    UARTprintf("\n>");


    //
    // Peek to see if a full command is ready for processing
    //
    while(UARTPeek('\r') == -1)
    {
    //
    // millisecond delay. A SysCtlSleep() here would also be OK.
    //
    SysCtlDelay(SysCtlClockGet() / (1000 / 3));

    if (g_bPoll)
    {
    g_bPoll = false;

    if (g_sAppState.ui32Mode != APP_MODE_HIB)
    {
    ui32HibModeEntryCount = ui32HibModeEntryCount + 1;
    if (ui32HibModeEntryCount == 580)
    {
    UARTprintf("Entering Deep Sleep...\n");
    UARTprintf("RTC Count: (%u / 600)\n\r", HibernateRTCGet());
    }
    if (ui32HibModeEntryCount >= 600) // 30 seconds
    {
    ui32HibModeEntryCount = 0;
    g_sAppState.ui32Mode = APP_MODE_HIB;
    }
    }
    }

    //
    // Check for change of mode and enter hibernate if requested.
    // all other mode changes handled in interrupt context.
    //
    if(g_sAppState.ui32Mode == APP_MODE_HIB)
    {
    AppHibernateEnter();
    }
    }

    //
    // a '\r' was detected get the line of text from the user.
    //
    UARTgets(g_cInput,sizeof(g_cInput));

    //
    // Pass the line from the user to the command processor.
    // It will be parsed and valid commands executed.
    //
    i32CommandStatus = CmdLineProcess(g_cInput);

    //
    // Handle the case of bad command.
    //
    if(i32CommandStatus == CMDLINE_BAD_CMD)
    {
    UARTprintf("Bad command!\n");
    }

    //
    // Handle the case of too many arguments.
    //
    else if(i32CommandStatus == CMDLINE_TOO_MANY_ARGS)
    {
    UARTprintf("Too many arguments for command processor!\n");
    }
    }
    }
  • Dear Charles

    Is there any update on this issue?
    Thanks for your support.
  • Hi Jefferey,

      Can you first check if the HIBn pin  is asserted low properly to enter hibernation?

      Do you have another board that you can test if you observe the same behavior?

      I wonder if the below errata is causing the problem. Please take a look and implement the workaround as suggested and try if it makes a difference.