• Not Answered

TM4C1294NCPDT: RTC Clock Counter Mode Application

Part Number: TM4C1294NCPDT

I am trying to use RTC in counter mode using hibernation module but not sending processor into hibernating mode.

I am trying to create a sub second interrupt using RTC Match registers - precisely 10 HZ interrupt about 10 times within one second. I use a different GPIO pin to enable interrupt every one second. And within this one second I need precise ten 10 HZ interrupts. I am using the RTC subseconds register and Match Register for the same.

The code snippets to enable RTC and HIB:

// Configure Hibernate module clock.
//
HibernateEnableExpClk(ui32SysClock);


// Enable RTC mode.
//
HibernateRTCEnable();

//
// Configure the hibernate module counter to 24-hour calendar mode.
//
// HibernateCounterMode(HIBERNATE_COUNTER_24HR);
// Configure the hibernate module counter to RTC counter mode.
HibernateCounterMode(HIBERNATE_COUNTER_RTC);

############To get inetrrupt every ones econd we use the GPIO######################################################################################

// LaunchPad BoosterPack 1 Header for taking 1 PPS pulse configure pins
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_3); // Init PF3 as input

GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);

// Interrupt setup
GPIOIntDisable(GPIO_PORTF_BASE, GPIO_PIN_3); // Disable interrupt for PF4 (in case it was enabled)
GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_3); // Clear pending interrupts for PF4
// Register our handler function for port F pin 3
GPIOIntRegisterPin(GPIO_PORTF_BASE, GPIO_INT_PIN_3,IntGPIOf_Pin3);
GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_RISING_EDGE);

//
// Register the interrupt handler function for GPIO F pin 3
//
IntRegister(INT_GPIOF_TM4C129 , IntGPIOf_Pin3);

####################################################################################################

ENABLE HIBERNATE MATCH INTERRUPT

// Enable Hibernate Match Interrupt
HibernateRTCSet(0); // set RTC counter second to zero
// Clear pending interrupt from Hibernate Module
HibernateIntClear(HIBERNATE_INT_RTC_MATCH_0);
// Disable interrupts for Hibernate module
HibernateIntDisable(HIBERNATE_INT_RTC_MATCH_0);

HibernateIntRegister(Count10Hz_ISR); // register handler for this interrupt
// Register the interrupt handler function for RTC Match 0
//
IntRegister(INT_HIBERNATE_TM4C129 , Count10Hz_ISR);
//
// Enable the interrupt for RTC Match 0 in the processor vector table
//
// IntEnable(INT_HIBERNATE_TM4C129); // moved to just before main loop
// Enable processor interrupts.


// Reset RTC counter seconds
HibernateRTCMatchSet(0,0);

##########################################################################################################################################################

iSECOND ISR through GPIO 

void
IntGPIOf_Pin3(void)
{

// set PPS flag = true for processing in main loop

HWREG(UART0_BASE + 0) = '$'; // 400nS delay, 550nS jitter @ 115200 baud // UART send
// // Turn on the bit


pps_flag = TRUE;
hibRegister_subseconds = HibernateRTCSSGet(); // HWREG(HIB_RTCSS);get subseconds alone here in ISR

// set both RTC counters to zero seconds and sub seconds

HibernateRTCSet(0);

GPIOIntClear(GPIO_PORTF_BASE, GPIO_INT_PIN_3);

}

#############################################################################################################

SUB SECOND ISR ENABLED BY HIB MATCH ISR

//*****************************************************************************
//
// This is the handler for 10 HZ interrupt within each 1 pps interval.
// Use RTC Match value to generate interrupt 10 times within 1 sec
//
//*****************************************************************************
void Count10Hz_ISR(void) {
HWREG(UART0_BASE + 0) = '|'; // ###########
// Turn on the bit

//MAIN LOOP FLAG
RTC_Flag = TRUE;

HWREG(HIB_IC) |= HIBERNATE_INT_RTC_MATCH_0;

} // end ISR

##############################################################################################

MAIN LOOP

while(1)
{
// spit out $ in an infinite loop
if (pps_flag == TRUE){
// reset pps flag
pps_flag = FALSE;


MatchDollarCounter = 0; // ###############



HWREG(HIB_RTCSS) &= 0x0000FFFF; // retaining lower 16 bits as is

while(!(HWREG(HIB_CTL) & HIB_CTL_WRC)); // ###### needed before next write
// measured ~90uS
HWREG(HIB_RTCSS) |= 0x0CCD0000; // ##### disassembled code shows that this does a read-modify-write over 4 instructions, which introduces a timing error ######
while(!(HWREG(HIB_CTL) & HIB_CTL_WRC)); // ###### needed before next write

HibernateIntEnable(HIBERNATE_INT_RTC_MATCH_0); // interrupt source for RTC interrupt} // end if pps flag


else if (RTC_Flag == TRUE) { // #############
// UARTFlushTx(FALSE); // Flush UART Transmit Buffer #############
// Turn off the bit

// GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_1, GPIO_PIN_1);

GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 1);
MatchDollarCounter++; // ##########

// hibernateRTCMatchValue = (HibernateRTCMatchGet(0) + 0x1000) << 16; // add 100 msec more each time. So zero is start of time ###############
hibernateRTCMatchValue = (0xCCD + 0xCCD*MatchDollarCounter) << 16; // add 100 msec more each time. So zero is start of time ###############

HWREG(HIB_RTCSS) &= 0x0000FFFF; // retaining lower 16 bits as is #################
while(!(HWREG(HIB_CTL) & HIB_CTL_WRC)); // ###### needed before next write (~90uS)
HWREG(HIB_RTCSS) |= hibernateRTCMatchValue; // ##### disassembled code shows that this does a read-modify-write over several instructions, which introduces a timing error ######
while(!(HWREG(HIB_CTL) & HIB_CTL_WRC)); // ###### needed before next write (~90uS)
// HibernateRTCSSMatchSet(0,hibernateRTCMatchValue); // ######## This will alter the Subsample Seconds, which we don't want to do! ########
RTC_Flag = FALSE;

if (MatchDollarCounter == 3)
HibernateIntDisable(HIBERNATE_INT_RTC_MATCH_0);

GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
}


} // end while 1

#####################################################################################################################

PROBLEM: We can generate only 3 pulses and they are not evenly spaced at 10 HZ. They keelp increasing in time: The first interrupt is at 1/10 sec, the second at 132 microsecond and third at about 250 usec and we do not get fourth one.

I would appreciate reply on this as as much as help from TI as possible.

I am attaching original code file which was adapted from Tivaware example :

Example code for Hybernation Module is found in Tivaware\examples\boards\ek-tm4c1294xl\hibernate\hibernate.c

Thank you

Pavitrahibernate.c

6 Replies

  • Hi,
    Is your 1s interrupt periodic or based on a random GPIO input?

    regards,

    Charles

    Please click the Verify Answer button on this post if it answers your question.

  • In reply to Charles Tsai:

    Interrupt is periodic but triggered by GPIO Port F pin 3 which is programmed to raise interrupts every 1 second.

    Regards
    Pavitra
  • In reply to Pavitra Ramanujam:

    Hi,
    Can you please check if you are using HIB LFIOSC as the clock source for the Hibernate module? Please note that the onchip HIB low frequency oscillator (HIB LFIOSC) has a wide frequency variation. It is not recommended to use the HIB LFIOSC as an RTC clock source.

    regards,

    Charles

    Please click the Verify Answer button on this post if it answers your question.

  • In reply to Charles Tsai:

    Hi,

    A 32.768 KHz crystal is used for RTC.

    We are using EK-TM4C1294XL Launchpad which has an onboard 32.768 KHz crystal.

    Thanks
    Pavitra
  • In reply to Pavitra Ramanujam:

    Hi,
    Can you do an experiment? Can you try to to generate sub-section match interrupt at 5Hz instead of 10Hz? You are not really using hibernate module to save power but rather to generate the sub-section match interrupt by adding the next sub-section match value, right? The hibernate module runs off of the 32kz OSC and to access the hibernate module registers it takes some cycles at 32kz frequency. From the time the sub-section match value is first cleared to the time a new (next) sub-section match register is written, the sub-section counter has already elapsed. If the sub-section counter value has already counted over next match value before the next value is fully written then the match may be missed. This is just one direction I'm looking into. Not necessary the root cause yet. Another thing you can try is to reset the RTC counter for each 0.1s and always set the sub-section match to 0.1s.

    regards,

    Charles

    Please click the Verify Answer button on this post if it answers your question.

  • In reply to Charles Tsai:

    Hello

    I am aware that a small amount of sub-second time is lost because the SS match value is in the same register as the SS clock value. Therefore, I have to do a read-modify-write with masking to preserve the SS time (almost). But that error can be corrected for.

    “For the current experiment, the Tiva is doing little else, so 100ms should be plenty of time to set up for the next interval. And the oscilloscope confirms that by use of test point flags. The times I am seeing are: 100mS from the GPS 1PPS edge to the first SS interrupt, another 132mS to the next, and another 268mS to third (total of 500mS at that point); no more until the next second when the pattern repeats. Each time, the GPS edge clears the counters, and the SS match is incremented by 0xCCD at each interrupt.

    “Yes, the RTC counter instead at each 100mS time, or empirically generated match could be derived to make it work. But I’d like to understand what’s going on first. I’m using the RTC to potentially take advantage of the timing trim capability after the basics are worked out, and because it seemed at first like the RTC would be a natural for this sort of problem

    Thank you