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.

TM4C1233D5PM: RTC time sporadically lost

Part Number: TM4C1233D5PM

Hi

I use the hibernation module to maintain the RTC while the device is not powered externally. This is the only feature of the hibernation module in use.

The hibernation module clock and battery are wired as illustrated in the Figure below (PE is ground).

In firmware, I first initialise the hibernation module using the code below:

void HIB_init( void )
{
    /* Check if hibernation module is already running (and that it is set to high drive strength) */
    if( ( !getHibEnb() ) || ( !getHighDriveStrength() ) )
    {
        /* If not running, enable the clock */
        ROM_HibernateEnableExpClk(  ROM_SysCtlClockGet() );

        /* Wait t_HIBOSC_START to let the clock stabilize */
        ROM_SysCtlDelay(500000);
/* Wait for write ready */ waitHibWrite(); /* Configure clock */ ROM_HibernateClockConfig( HIBERNATE_OSC_HIGHDRIVE ); } /* Set module initialised flag */ hibInitialised = true; }
static bool getHibEnb( void )
{
    bool enb = false;
    if ( HWREG( HIB_CTL ) & HIB_CTL_CLK32EN )
    {
        enb = true;
    }
    return enb;
}
static bool getHighDriveStrength( void )
{
    bool highStrength = false;
    if ( HWREG( HIB_CTL ) & HIB_CTL_OSCDRV )
    {
        highStrength = true;
    }
    return highStrength;
}

 

Then I enable the RTC using the code below:

bool HIB_RTCEnable( void )
{
    bool resultFlag = false;

    /* Is module initialised ?*/
    if( hibInitialised == true )
    {
        /* Is RTC already initialised ? */
        if( !getRTCEnb() )
        {
            /* Wait for write ready */
            waitHibWrite();

            /* Enable the RTC */
            ROM_HibernateRTCEnable();

            /* Wait for write ready */
            waitHibWrite();

            /* Set the trim to the norminal value, 0x7FFF */
            ROM_HibernateRTCTrimSet( 0x7FFFU );

            /* Wait for write ready */
            waitHibWrite();

            /* First time the RTC is enabled, the time is set to 01/01/2000 */
            ROM_HibernateRTCSet( RTC_TIME_INIT_VALUE );
        }
        resultFlag = true;
    }
    return resultFlag;
}
static bool getRTCEnb( void )
{
    bool enb = false;
    if ( HWREG( HIB_CTL ) & HIB_CTL_RTCEN )
    {
        enb = true;
    }
    return enb;
}
static void waitHibWrite( void )
{
    /* Wait for the hibernation module to complete a asynchronous write */
      while( !( HWREG( HIB_CTL ) & HIB_CTL_WRC ) ){};
}

I intend to only initialise the hibernation module and the RTC if they are not already running.

My problem is that given a 100 boards with this setup, some boards sporadically loses the maintained RTC value.

I have considered to following possible root causes:

  1. The hardware is not able to maintain the RTC while the device is off
  2. The initialisation procedure incorrectly determines that the hibernation module or the RTC is not running, and (re-)runs the initialisation sequence (which resets the RTC)

The devices with lost RTC all runs on fairly new coin cell batteries (1-2 months).

My hope is that the root cause is related to #2 above, as this can be changed in firmware and does not need a hardware fix. 

As you can see from the code, I attempt to detect if the hibernation module is running using the getHibEnb and getHighDriveStrength functions. Similarly, I use the getRTCEnb to detect if the RTC is running. If one of these functions returns false, the modules will be re-initialised, resetting the time.

I hope the above is clear and really appreciate any help that you can provide on this.

Thanks, 

Christian