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.

TM4C123GH6PM: TM4C123 Hibernation Module - Hibernate high after power is cut

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

Hello,

I have a custom circuit, with a wake up button, and hibernate pin controlling the power supply.

This is how I setup my hibernate module:

// Hibernate enable
SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
HibernateEnableExpClk(SysCtlClockGet());
HibernateGPIORetentionDisable();
MAP_SysCtlDelay(1333333UL); // 50ms
HibernateWakeSet(HIBERNATE_WAKE_PIN);

And when needed, I use

HibernateRequest();

Which will put the device in hibernate mode, turn of the power supply, and wake up when wake button is pushed.

I observed that if the main power supply is disconnected, without putting the device in hibernate mode, the hibernate pin stays high, which will drain the battery, in a month or so.

Is there a way to work around this problem?

Best Regards,

C.A.

  • The datasheet contains:

    The call to HibernateEnableExpClk(SysCtlClockGet()); will set the CLK32EN bit.

    The call to HibernateWakeSet(HIBERNATE_WAKE_PIN); will set the PINWEN bit.

    Therefore, I expect the device to enter hibernation if VDD is arbitrarily removed.

    I have a custom circuit, with a wake up button, and hibernate pin controlling the power supply.

    Can you show the schematic for the how the hibernate pin controls the power supply, and how the main power supply is disconnected?

  • Hello Chester,

    I have carefully measured again and again, and unfortunately, hibernate pin stays high after arbitary power removal.

    Here are the relevant parts of the circuit:

    And here is how I connect my battery:

    And the hibernate pin is used to switch on/off a high side mosfet switch like shown below:

    Here is one thing I noticed, datasheet states that when power is reapplied, the circuit will wake up from hibernate or execute a cold-boot, but however, when the hibernate pin is used to switch on/off external power supply, there is no way for mcu to know when and if external power is reconnected right?

    Could there be also other reasons, that when power is removed arbitrarily, that will stop the mcu going to hibernate mode? I have a number of timer interrupts, and systick is enabled.

    I have been using and testing this circuit for a long time, and I thought I did everything correct, but this issue points to a mistake.

    Best Regards,

    Can Altineller

  • Hi Can,

    I observed that if the main power supply is disconnected, without putting the device in hibernate mode, the hibernate pin stays high,

    In the datasheet, it didn't say that the nHIB will go low when you arbitrarily remove the main power. I think nHIB is more controlled by the HibernateRequest() that will set the HIBREQ bit resulting in nHIB go low. 

    Here is one thing I noticed, datasheet states that when power is reapplied, the circuit will wake up from hibernate or execute a cold-boot,

    This is only true if PINWEN and RTCEN are bloth clear. You have set the wakeup source to HIBERNATE_WAKE_PIN.

    If the CLK32EN bit is set but the PINWEN, and RTCEN bits are all clear, the microcontroller still goes
    into hibernation if power is removed; however, when VDD is reapplied, the MCU executes a cold
    POR and the Hibernation module is reset.

    Could there be also other reasons, that when power is removed arbitrarily, that will stop the mcu going to hibernate mode? I have a number of timer interrupts, and systick is enabled.

    What is the current on the Vbat before you arbitrarily remove power and after you remove power? 

    Are you checking and configuring for battery threshold where hibernation mode will not be entered when the battery goes below the programmed threshold?

     For experiment, if you disable the systick and timer interrupt before you arbitrarily remove power, will it make a difference? I'm also curious if systick/timer interrupts are preventing from entering hibernate mode. 

  • Hello Charles,

    To rule out any interference by the use of systick, timer interrupts, and the usb-cdc i am using in my circuit, I made a simple program that illustrates the situation. It still behaves the same way, so neither systick, nor timer interrupts are responsible.

    I also measured the battery current like you suggested. When power is on it measures 0.0microAmps, and when power is removed it measures 78.2microAmps.

    Also, maybe it is going to VCC3ON state? I thought HibernateGPIORetentionDisable() would take care of that.

    I am not doing battery checking and configuring for battery threshold. It is all defaults.

    Best Regards,

    Can

    Below is my sample program:

    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
        while(1);
    }
    #endif
    
    
    int main(void) {
    
        SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOC)) {}
        GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_7);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
        HibernateEnableExpClk(SysCtlClockGet());
        HibernateGPIORetentionDisable();
        SysCtlDelay(64000000);
    
        HibernateRTCSet(0);
        HibernateRTCEnable();
    
        HibernateWakeSet(HIBERNATE_WAKE_PIN);
    
        //HibernateRequest();
    
        volatile uint32_t ui32Loop;
        while(1) {
            GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_PIN_7);
            for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++) {}
            GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, 0x0);
            for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++) {}
        }
    }

  • Hi Can,

      There is a hibernate module example in the latest TivaWare release. You can find the full project in C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c123gxl\hibernate. Below is a snippet of the main(). As you can see in the code and as per driverlib user's guide, the HibernateRTCEnable must be called before the HibernateRTCSet. You have the opposite order but I'm not sure if that is the reason for your problem. In addition, there is a waiting for the 32.768kHz crystal to stabilize that is missing in your code. I will suggest you try the example first and see if it makes a difference. 

    //*****************************************************************************
    //
    // This example demonstrates how to use the RTC mode of the Hibernation module.
    //
    //*****************************************************************************
    int
    main(void)
    {
        uint32_t ui32Status;
    
        //
        // Set the clocking to run directly from the external crystal/oscillator.
        //
        MAP_SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
                           SYSCTL_OSC_MAIN);
    
        //
        // Enable the hibernate module.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
    
        //
        // Read and clear any status bits that might have been set since
        // last clearing them.
        //
        if(MAP_HibernateIsActive())
        {
            //
            // Read the status bits to see what caused the wake.
            //
            ui32Status = MAP_HibernateIntStatus(0);
            MAP_HibernateIntClear(ui32Status);
        }
    
        //
        // Set up the serial console to use for displaying messages.
        //
        ConfigureUART();
        UARTprintf("Hibernation with RTC Wake Example.\n");
    
        //
        // Enable the GPIO peripheral for the on-board LED.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    
        //
        // Configure the GPIOs for the RGB LED.
        //
        MAP_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3 | GPIO_PIN_2 |
                                                   GPIO_PIN_1);
    
        //
        // Enable the Hibernation module for operation.
        //
        MAP_HibernateEnableExpClk(0);
    
        //
        // Wait for 32.768kHz clock to stabilize.
        //
        while(!(HWREG(HIB_RIS) & HIB_RIS_WC));
    
        //
        // Configure the drive strength for the crystal.
        //
        MAP_HibernateClockConfig(HIBERNATE_OSC_LOWDRIVE);
    
        //
        // Enable the Hibernate module RTC mode.
        //
        MAP_HibernateRTCEnable();
    
        //
        // Load initial RTC value.
        //
        MAP_HibernateRTCSet(0);
    
        //
        // Set initial match value to trigger RTC after 5 seconds.
        //
        MAP_HibernateRTCMatchSet(0, 5);
    
        //
        // Enable RTC match interrupt.
        //
        MAP_HibernateIntEnable(HIBERNATE_INT_RTC_MATCH_0);
    
        //
        // Re-intializes the Trim which gets modified due to a known issue of
        // Hibernate register initialization from HIB#01 errata.
        //
        MAP_HibernateRTCTrimSet(0x7FFF);
    
        //
        // Configure MCU interrupts.
        //
        MAP_IntEnable(INT_HIBERNATE_TM4C123);
    
        //
        // Enable MCU interrupts.
        //
        MAP_IntMasterEnable();
    
        //
        // Turn on the Blue LED.
        //
        MAP_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);
    
        //
        // Enter Hibernation Mode.
        //
        UARTprintf("Entering Hiberation, waking in 5 seconds.\n");
        MAP_HibernateRequest();
    
        while(1)
        {
            //
            // Do nothing, Hibernate interrupt routine will handle the rest.
            //
        }
    }
    

  • Hello Charles,

    I have adopted the code above into my test program, and still get the same behavior. However, I have been reading hibernate.c from the driverlib, and I found that there is a HIBERNATE_INT_VDDFAIL flag. So hibernate module can be programmed with an interrupt, in case of vdd fail. Can this be instrumented to get the desired behavior, or is it already in effect with defaults?

    I also would like to disable all functions that has to do with low battery, i.e. if the bios battery is low, it should just go to hibernate and not wake up.

    The voltage measured at the hibernate pin is almost half of what the battery voltage is. I measure 2.9V from battery terminals, and about 1.4 from the hibernate pin.

    To disable vabort, I wrote:

    HWREG(HIB_CTL) &= ~HIB_CTL_VABORT;
    while(!(HWREG(HIB_CTL) & HIB_CTL_WRC)) {}

    But, I am not sure if this would just flip the vabort bit, or set it with 0.

    Best Regards,

    C.

  • Hi Can,

    I have adopted the code above into my test program, and still get the same behavior. However, I have been reading hibernate.c from the driverlib, and I found that there is a HIBERNATE_INT_VDDFAIL flag. So hibernate module can be programmed with an interrupt, in case of vdd fail. Can this be instrumented to get the desired behavior, or is it already in effect with defaults?

    Unfortunately, that is a feature only available on TM4C129, not TM4C123.

    The voltage measured at the hibernate pin is almost half of what the battery voltage is. I measure 2.9V from battery terminals, and about 1.4 from the hibernate pin

    I want to make sure we are on the same page. The hibernate pin you are referring to is the nHIB pin, correct?

    Can you try on the launchPad and do you see the same?

    To disable vabort, I wrote:

    HWREG(HIB_CTL) &= ~HIB_CTL_VABORT;
    while(!(HWREG(HIB_CTL) & HIB_CTL_WRC)) {}

    But, I am not sure if this would just flip the vabort bit, or set it with 0.

    By default, it will not abort. So you don't really need to do this step. Also you can use the HibernateLowBatSet to either detect or abort on a specified threshold voltage.

    15.2.2.24 HibernateLowBatSet
    Configures the low-battery detection.
    Prototype:
    void
    HibernateLowBatSet(uint32_t ui32LowBatFlags)
    Parameters:
    ui32LowBatFlags specifies behavior of low-battery detection.
    Description:
    This function enables the low-battery detection and whether hibernation is allowed if a low
    battery is detected. If low-battery detection is enabled, then a low-battery condition is indicated
    in the raw interrupt status register, which can be enabled to trigger an interrupt. Optionally,
    hibernation can be aborted if a low battery condition is detected.
    The ui32LowBatFlags parameter is one of the following values:
    HIBERNATE_LOW_BAT_DETECT - detect a low-battery condition
    HIBERNATE_LOW_BAT_ABORT - detect a low-battery condition and abort hibernation if
    low-battery is detected

    The other setting in the ui32LowBatFlags allows the caller to set one of the following voltage
    level trigger values :
    HIBERNATE_LOW_BAT_1_9V - voltage low level is 1.9 V
    HIBERNATE_LOW_BAT_2_1V - voltage low level is 2.1 V
    HIBERNATE_LOW_BAT_2_3V - voltage low level is 2.3 V
    HIBERNATE_LOW_BAT_2_5V - voltage low level is 2.5 V
    Example: Abort hibernate if the voltage level is below 2.1 V.
    HibernateLowBatSet(HIBERNATE_LOW_BAT_ABORT | HIBERNATE_LOW_BAT_2_1V);

    Below is another EVM board for TM4C123 that we no longer carry. While I don't know the reason to your problem, I hope the schematic in this board can provide some reference. 

    dk_tm4c123 user guide spmu357b.pdf

  • Hello Charles,

    > I want to make sure we are on the same page. The hibernate pin you are referring to is the nHIB pin, correct?

    I upload the same code to the ek-tm4c123gxl, and then measured the hibernate pin, to find out it is 3.3V same as the supply voltage. I am using a mosfet switch in my circuit, which the hibernate pin switches the main power over a mun2211 transistor. Like below:

    Since this transistor has built in bias resistors and hibernate pin connected to base, it has a ground path of 20kOhms. Once I removed this part, I have found the nHIB pin, stays at same voltage as VDD when supply is on, and same voltage as VBAT when suppy is off.

    I also measured the current consumption, with and without rtc enabled, and found that it is consistent with the pdf on hibernate module.

    When I connect the battery, it draws 0.5uA. When I connect the (externally supplied) 3V3, it draws 0uA, when I remove the power arbitarily, it draws 1.1uA. (I dont know why it does not equal to 0.5uA, but I think that wuold not hurt much)

    So upon arbitary power removal, the device definitively goes to hibernate mode, (also judging from spending 1.1uA, it is not vdd3on mode neither, because it would spend 5uA) - but with the nHIB pin high. Is this the normal behavior?

    How can I use this nHIB pin, without interfering with it? In the schematics of the DK-TM123, there is a reverse connected diode on the hibernate pin, but I am not sure I understand how this works. Are there any tactics/best practices to work with the nHIB pin.

    Best Regards,

    Can

  • Hi Can,

    Once I removed this part, I have found the nHIB pin, stays at same voltage as VDD when supply is on, and same voltage as VBAT when suppy is off.

    I also measured the current consumption, with and without rtc enabled, and found that it is consistent with the pdf on hibernate module.

    When I connect the battery, it draws 0.5uA. When I connect the (externally supplied) 3V3, it draws 0uA, when I remove the power arbitarily, it draws 1.1uA. (I dont know why it does not equal to 0.5uA, but I think that wuold not hurt much)

    Are you saying that if  you were to connect the nHIB to your mosfet switch then the current drawn on the battery will be much higher than 1.1uA and thus draining the battery in one month? And you suspect the much higher current was due to a seemingly floating nHIB at 1.4V. I really don't understand your mosfet circuit enough to comment what caused to it to be 1.4V. As you said, when the mosfet switch is removed, the nHIB remains at 3.3V. As I mentioned in my earlier reply, the datasheet didn't really specifically say the nHIB will go low when you arbitrarily remove main power. I still think the state of nHIB is a direct result of calling HibernateRequest() only which means it is a software based. The MCU doesn't know when the main power is arbitrarily removed to automatically set the HIBREQ bit. 

    How can I use this nHIB pin, without interfering with it? In the schematics of the DK-TM123, there is a reverse connected diode on the hibernate pin, but I am not sure I understand how this works. Are there any tactics/best practices to work with the nHIB pin.

    On the DK board, I'm not so sure what the reverse diode is for either. I'm guessing that it is for the special Vbat monitoring circuit on board to force the board to USB power when the battery is low or full discharged. 

      The DK-TM4C123G has additional circuitry that allows the development board to be turned on when a battery is not present or when the battery voltage is too low. A Texas Instruments TPS3803-01 Voltage Detector (U12) monitors VBAT and produces a VBAT_GOOD signal when the battery voltage is above 2.1 V. Using standard logic gates and the state of VBAT and VDD, the HIB signal can be forced high when VBAT is not valid and the microcontroller is not already powered. With this circuit, a USB-powered board can turn itself on when the back-up battery is either missing or fully discharged. See Appendix A: Schematics for more details. This additional circuitry may not be needed in all applications. For example, when using the Hibernate module in VDD3ON mode, power is cut to the microcontroller internally which eliminates the need to turn off an external supply using HIB. By default the DK-TM4C123G is not configured to use VDD3ON mode; HIB is connected to the load switch, WAKE is pulled up to VBAT, and VBAT is connected to the battery. VDD3ON mode can be used if the board is reconfigured as follows (2): Disconnect HIB from the load swich by removing the HIB DISC jumper (JP3). Next, ensure that WAKE is pulled HIGH either by leaving the battery connected or by removing the battery and connecting VBAT to VDD.

    As far as best practice I will have to refer to the example hibernate circuit diagrams shown in the datasheet. I do not see how the battery is connected to the Vbat pin in your schematic. Please refer to the datasheet and also the errata. 

  • The MCU doesn't know when the main power is arbitrarily removed to automatically set the HIBREQ bit. 

    Thank you Charles Tsai. This answers my question.

    I still have a question about the nHIB pin, which I will ask as a related question.