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.

Hibernate RTC sub seconds problem



I'm using the LM4F232 board and a modified version of the hibernate example along with TivaWare. My goal is to use the hibernate RTC to create very accurate interrupts off the sub seconds match. In the hibernate ISR I toggle an LED to indicate that it's working correctly and also so that I can measure the accuracy using a scope. It works correctly until 55 to 80 seconds in when the RTC value manages to surpass my match value and thus the ISR value doesn't fire anymore. I'm hoping this is something I'm doing wrong and not a bug with the chip.

Code:

#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/hibernate.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/rom.h"
#include "driverlib/uart.h"
#include "utils/ustdlib.h"
#include "inc/hw_hibernate.h"
#include "driverlib/pin_map.h"

static volatile uint32_t period;
static volatile uint32_t sMatch,
						 ssMatch;
static volatile bool led;

void HibernateHandler( void )
{
	HibernateIntClear( HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_LOW_BAT | HIBERNATE_INT_RTC_MATCH_0 );
	ssMatch = (ssMatch + period) % 32768;
	if( ssMatch == 0 )
		//++sMatch;
		HibernateRTCMatchSet( 0, HibernateRTCGet( ) + 1 );
	HibernateRTCSSMatchSet( 0, ssMatch );

	if( led )
		GPIOPinWrite( GPIO_PORTG_BASE, GPIO_PIN_2, GPIO_PIN_2 );
	else
		GPIOPinWrite( GPIO_PORTG_BASE, GPIO_PIN_2, 0 );
	led = !led;

}

int main(void)
{
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_INT | SYSCTL_XTAL_16MHZ);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
    HibernateEnableExpClk(SysCtlClockGet( ));
    GPIOPinTypeGPIOOutput( GPIO_PORTG_BASE, GPIO_PIN_2 );

    uint32_t Fs = 2;
    period = 32768 / Fs;
    sMatch = 5;
    ssMatch = 0;
    led = true;

    HibernateClockConfig(HIBERNATE_OSC_LOWDRIVE);
    HibernateRTCEnable();

    HibernateRTCSet(0);

    HibernateRTCMatchSet(0, sMatch);
    HibernateRTCSSMatchSet(0, ssMatch);

    HibernateIntEnable(HIBERNATE_INT_RTC_MATCH_0);
    HibernateIntClear(HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_LOW_BAT | HIBERNATE_INT_RTC_MATCH_0);
    HibernateIntRegister(HibernateHandler);


    while( 1 )
    {

    }

}

  • I wanted to provide an update on the problem. I'm using the OLED on the LM4F232 evaluation board to display a running ticker of the current RTC match value and also the current RTC value. Predicted behavior is that the match value is always a second ahead of the RTC, ensuring that the match interrupts keep firing. However, as soon as the RTC hits the value of 65 it immediately skips to 66 thus the match interrupt never fires. I've seen this on both the OLED and also in the debugger watching the HIB_RTCC register. I've attached the whole project in the hopes someone can verify the problem since it uses an LM4F232 eval board with no modifications. I would greatly appreciate some help from TI tech support as this would be quite easy to recreate.

    0523.hibernate.zip

    I removed all the interrupts and setting of match registers so the device is acting purely like an RTC. The same behavior where the RTC periodically will skip through a count occurs. This happens from 1 to 2, 65 to 66, 129 to 130, etc.

  • Hi Nathan,

    This behavior is expected.  Please review the RTC Trim section of the Hibernation Module chapter of the data sheet.

    Regards,

    Sue

  • I was trying to find code for the RTC and used the code above, however Sue's comment although correct did not help a lot... 

    The problem is that the default of the TRIM is suppose to be 0x7FFF however on my board it was set to 0x2040 which caused the interrupts to stop. The fix was to change the code above to set the Trim value to 0x7FFF.

    HibernateClockConfig(HIBERNATE_OSC_LOWDRIVE);
    SysCtlDelay( SysCtlClockGet() * 3 );

    HibernateRTCTrimSet(0x7FFF);


    HibernateRTCEnable();

    Thanks

    Trampas