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.

Hibernation problem TM4C129XNCZAD

Other Parts Discussed in Thread: TM4C129DNCPDT, LMFLASHPROGRAMMER

It's me again. I'm now working on Lab 6 of the Tiva C Workshop series. I got through Lab 5 (ADC) without any problems, which was great. Now I'm stuck again. I really can't figure out what the problem is this time -- I've read and re-read all the API function info in the Peripheral Driver Library User's Guide to see if I was causing problems like in Lab 4, i.e. some functions are different with the TM4C129X series as opposed to TM4C123G. However, in this case, that doesn't seem to be the case. 

Here's my code so far. Note that I've commented out the rom.h and TARGET_IS_SNOWFLAKE_RA0 because I wanted to make sure that wasn't the problem. I just learned how to call the API from ROM in the last lab, and I wanted to try and apply that right away to this lab (though it's not a part of the lab instructions) just as a learning experience. But I commented that out and removed all the ROM_ prefixes just in case. In the HibernateEnableExpClock() function call, I remembered that in my other thread I was told that the Snowflake devices do not support SysCtlClockGet() function, so I simply entered the 40MHz as a constant. BTW -- is there any where to get the clock value through an API call or otherwise? It seems really strange that they removed that API call for the 129X devices but then didn't supply an alternative.

#include <stdint.h>
#include <stdbool.h>
#include "utils/ustdlib.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/debug.h"
#include "driverlib/hibernate.h"
#include "driverlib/gpio.h"
//#define TARGET_IS_SNOWFLAKE_RA0
//#include "driverlib/rom.h"

int main(void)
{
	SysCtlClockFreqSet(SYSCTL_OSC_INT|SYSCTL_USE_PLL|SYSCTL_CFG_VCO_480, 40000000); // set system clock to 40MHz

	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ); // enable Port Q GPIO
	GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE, GPIO_PIN_7); // set PQ7 to output
	GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7, 0x80); // turn LED on

	SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); // enable hibernation
	HibernateEnableExpClk(40000000); // set clock to system clock
	HibernateGPIORetentionEnable();
	//HibernateClockConfig(HIBERNATE_OSC_LFIOSC); // set LFI as clock source in hibernation
	SysCtlDelay(64000000); // delay long enough to see the LED
	HibernateWakeSet(HIBERNATE_WAKE_PIN); // set wake condition to wake pin
	GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7, 0x00); // turn LED off before going to sleep

	HibernateRequest();

	while(1)
	{

	}
}

The HibernateClockConfig() is also not part of the lab, but I experimented with adding it in to see if if helped.
Essentially, here's what's supposed to happen -- when the micro powers up, it turns on an LED, then enables the hibernation module, and as soon as the HibernateRequest() happens, it turns the LED off. It then is supposed to stay in hibernation until the /WAKE pin goes low. This board (unlike the 123G Launchpad) does not have a button connected to the /WAKE pin, so I simply took the header pins onto a breadboard, and used a 1k pull-up resistor to keep /WAKE  high. Then, when the button is pressed, it goes low and should in theory wake the micro.

What's happening though, is after the delay, there's a brief flicker in the LED, then it comes back on fully, and the debugger loses communication with the board. The flicker keeps happening every four seconds or so (the length of the delay function). Occasionally, the LED will turn off and the chip will go into hibernate mode. Pushing the button 'wakes' the chip but then instead of going back into hibernation after four seconds it does the same infinite loop as I just described, with the LED flickering every four seconds, and the board losing contact with the debugger.

Am I missing something obvious here? Again, all help is truly appreciated! Thanks in advance.

  • Hi Aurelius,

    The use of SysCtlClockFreqSet gives more flexibility in terms of system clock setting. On TM4C123 the system clock had definite values of 80, 66, 53, etc. In case of TM4C129 be selecting the correct VCO and system clock frequency the API will try to set the dividers to get the system clock as close as possible to the desired system frequency.

    To the problem of Hibernate, the issue is that you have called the HibernateGPIORetentionEnable, which will set the IO in retention mode. However on wake up it will not clear the IO retention and thus the IO used for LED will not have any effect, You have to call the HibernateGPIORetentionDisable so that IO can be controlled by the GPIO module

    Regards

    Amit Ashara

  • Okay. Where should the HibernateGPIORetentionDisable() be called?

    Also, would omitting that cause the behaviour I'm seeing? The only way to restore communication to the board after the bug I'm experiencing is to use the LM Flash Programmer and erase the whole chip.

    It's almost like it's either getting stuck in an infinite loop, or it's getting stuck in hibernation. Or maybe going in and out of hibernation infinitely. Either way, the debugger gives a bunch of errors and then stops trying to communicate.

    Thanks again Amit! Your advice is always appreciated!

  • Hi Aurelius

    No. The JTAG IO's are not retained so they can still access the device, after the device exits hibernate and before it goes into the next hibernate. The time window is approximately 1.6 seconds for the debugger to connect (based on the code you have shown)

    Also since you are using VDD3ON Mode of Hibernate please do make sure that the 3.3V supply is not cut out when in Hibernate. This is just a check-mark for you to use when debugging Hibernate.

    As for the GPIO retention disable, I would suggest the code to be like this. Of course there are better ways of doing the code for most simplest of exercises, this should be good

        SysCtlClockFreqSet(SYSCTL_OSC_INT|SYSCTL_USE_PLL|SYSCTL_CFG_VCO_480, 40000000); // set system clock to 40MHz
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ); // enable Port Q GPIO
        GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE, GPIO_PIN_7); // set PQ7 to output
        GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7, 0x80); // turn LED on
        SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); // enable hibernation
        HibernateEnableExpClk(40000000); // set clock to system clock
        HibernateGPIORetentionDisable();

        SysCtlDelay(64000000); // delay long enough to see the LED

        HibernateWakeSet(HIBERNATE_WAKE_PIN); // set wake condition to wake pin
        GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7, 0x00); // turn LED off before going to sleep
        HibernateGPIORetentionEnable();
        HibernateRequest();

    Regards

    Amit Ashara

  • Thanks for the suggestion. I implemented the changes as you specified, but the second the chip goes into Hibernation I get 

    CORTEX_M4_0: Error: Debug Port error occurred.

    and then when I wake it I get

    CORTEX_M4_0: Error: Debug Port error occurred.
    CORTEX_M4_0: Unable to determine target status after 20 attempts
    CORTEX_M4_0: Failed to remove the debug state from the target before disconnecting. There may still be breakpoint op-codes embedded in program memory. It is recommended that you reset the emulator before you connect and reload your program before you continue debugging

    It doesn't matter if I change the wake mode to RTC and wake it that way. Is it possible that there's a different way to enter hibernation for Snowflake devices?

    Thanks again for your help! I really want to figure this one out as hibernation will be critical for many of my projects.

  • Hi Aurelius,

    Hibernate is the lowest power mode for TIVA devices where everything except the Hibernate Block will be shut down. This includes the mechanism for any debugger to access the System. Hence, you would always see debugger disconnecting when the device goes to Hibernate.

    Regards

    Amit Ashara

  • That makes sense. But still, when the chip wakes up, it seems to glitch and the LED just flickers every 4 seconds instead of returning to hibernation. Something is definitely not working properly.

  • Hi Aurelius,

    The issue was that after the Pin Wakeup the HIBRIS get's set which has to be cleared by the application. There is a data sheet Note in the HIBRIS description for bit-3

    So I made the change to the code and ran it. Now it works as expected.

        SysCtlClockFreqSet(SYSCTL_OSC_INT|SYSCTL_USE_PLL|SYSCTL_CFG_VCO_480, 40000000); // set system clock to 40MHz
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ); // enable Port Q GPIO
        GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE, GPIO_PIN_7); // set PQ7 to output
        GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7, 0x80); // turn LED on
        SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); // enable hibernation
        HibernateEnableExpClk(40000000); // set clock to system clock

        HibernateGPIORetentionDisable();
        HibernateIntClear(HIBERNATE_INT_PIN_WAKE);

        //HibernateClockConfig(HIBERNATE_OSC_LFIOSC); // set LFI as clock source in hibernation
        SysCtlDelay(64000000); // delay long enough to see the LED
        HibernateWakeSet(HIBERNATE_WAKE_PIN); // set wake condition to wake pin
        GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7, 0x00); // turn LED off before going to sleep
        HibernateGPIORetentionEnable();

        HibernateRequest();

    Regards

    Amit Ashara

  • wow, thanks again Amit!

    Once again you've come to the rescue. Thanks so much!

  • Hi Amit,

    I'm working on TM4C129DNCPDT. I wanted to test hibernate mode. I did the settings similar to above , except LED configuration, as follows

    SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); // enable hibernation
    HibernateEnableExpClk(120000000);
    HibernateGPIORetentionDisable();
    HibernateIntClear(HIBERNATE_INT_PIN_WAKE);
    HibernateWakeSet(HIBERNATE_WAKE_PIN); // set wake condition to wake pin
    HibernateGPIORetentionEnable();
    HibernateRequest();

    I debugged the code using JTAG(XDS200) , after programming the micro  JTAG is not getting connected. I think micro is working but it directly goes into hibernate mode. Can you please help regarding this?

    Thanks,

    Abhay

  • Hello Abhay,

    Yes, it will go into hibernate mode.

    You will have to erase the flash using the LMFlashProgrammer which would require the Stellaris ICDI from a a Launch Pad. There are posts where I have shown the connections to be made to get the LaunchPad working as a debugger with a custom board and then using LMFLashProgrammer.

    Alternatively, you can set the wake pin of Hibernate to low to bring the processor out of hibernate and try to connect in the same time.

    If none of the above works, then remove the 32K crystal from your board. That will cause Hibernate Clock Configuration to get stuck in a loop, after which you can connect to the device.

    Regards

    Amit

  • Hello again Amit,

    I think I face the same problem with hibernate and following this discussion. How can the HibernateGPIORetentionDisable() comes after GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7, 0x80) ? The pins in this case are under the retention enable and can't controled by the GPIO because the retention disable comes late !

    GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7, 0x80); // turn LED on /////how can this work before the RetentionDisable ?
        SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); // enable hibernation
        HibernateEnableExpClk(40000000); // set clock to system clock

        HibernateGPIORetentionDisable();    ///////

    I am asking because I am using a code on TM4C123 and it is working fine without using HibernateGPIORetentionDisable command except for several times in 3 months. But for the last days I found that the code can't go to hibernate several times and the watchdog is restarting it continuously till the battery dies ! Nothing modified except I have changed the kind of switching transistor attached to the port.

    If I need to add HibernateGPIORetentionDisable, can you tell me where to locate it and if I need to change the location of HibernateGPIORetentionEnable ?

    ////////My code////////

    GPIO_PORTC_DIR_R |= 0x40;  //enable PC6 for output

    GPIO_PORTC_AFSEL_R &= ~0x40;      // not alternative

      GPIO_PORTC_AMSEL_R &= ~0x40;      // no analog

    GPIO_PORTC_DEN_R  |= 0x40; //enable digital i/o PC6

    GPIO_PORTC_DATA_R |=0x40;  //sending 1 to PC6  //switch on transistor

    SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);

    HibernateEnableExpClk(SysCtlClockGet());

    HibernateGPIORetentionEnable();

    HibernateRTCSet(0);

    HibernateRTCEnable();

    HibernateRTCMatchSet(0,3600*2);

    HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC);

    //

    //code

    UART1_CTL_R &= ~UART_CTL_UARTEN;      // disable UART

    GPIO_PORTC_DIR_R |= 0xF0;  //enable PC4-7 for output

    GPIO_PORTC_AFSEL_R &= ~0xF0;      // not alternative

      GPIO_PORTC_AMSEL_R &= ~0xF0;      // no analog

    GPIO_PORTC_DEN_R  |= 0xF0; //enable digital i/o PC4-7

    GPIO_PORTC_DATA_R &=0x00;  //sending  zeros (0000 1111) //switch off transistor at PC6

    HibernateRequest();

    Regards,

    Ahmed

  • Hello Ahmed

    Did you check if the TM4C123 device you are using supports Hibernate GPIO Retention?

    Regards
    Amit
  • Hello Amit,

    Thanks alot, you are right, TM4C123 is not supporting the Hibernate GPIO Retention. I am just wondering now how the code didnot flag an error while using it ?

    Regards,

    Ahmed

  • Hello Ahmed,

    The GPIO are retained automatically and there is no manual control over it in VDD3ON mode of Hibernate in TM4C123 devices.

    Regards
    Amit