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.

EK-TM4C123GXL: RTC

I am on new turf here so forgive me if my question is a bit generalized.

It is desired to have a 64 bit variable to keep system time where each count represents 1 microsecond. I see that the timers have an RTC config. Unfortunately the board was designed without the 32.768KHz oscillator. Is there light at the end of the tunnel or will I need to use a count down timer that interrupts every microsecond and maintain a rollover counter? Looks like SysTick may be the place to start but I still need to consider 64 bit access. If it will make a much better solution I can lobby for the 2nd crystal for the next board spin.

Also I assume that uint64 access are not atomic and mutexs will be required, correct?

I apologize for the fact that I am not asking concise questions but a bit of general guidance would be appreciated. So far in my short experience with this MCU I have enjoyed it and want to make this work.

John

  • Hi John,

    Need to make some distinctions here with the capabilities you are needing. The dedicated RTC peripheral with hibernation mode is only 32-bit.

    However, you can configure a General Purpose Timer in wide mode to get a 64-bit timer and there is an RTC feature involved. The trick here is you need to be sure to have the crystal on a proper Timer CCP input:

    To use the RTC mode, the timer must have a 32.768-KHz input signal on an even CCP input.

    If the system time is desired then some form of RTC is the way to go. But you could use SysTick in the interim. Usually SysTick is more used to established a 1ms tick for RTOS processing. I haven't used it to track system time before.

    Also I assume that uint64 access are not atomic and mutexs will be required, correct?

    Yeah this is a 32-bit processor. For wide timer, two registers are used.

    Best Regards,

    Ralph Jacobi

  • Hi Ralph, 

    Thanks, and yes I should have been more clear about what I need. There are things I need:

    1) A 1 microsecond interrupt to trigger my scheduler.

    2) A place and efficient method to keep a count of microseconds since power up. I thought about using a pair of timers in RTC mode but Section 11.3.2.2 states: The input clock on a CCP0 input is required to be 32.768 KHz in RTC mode. The clock signal is then divided down to a 1-Hz rate and is passed along to the input of the counter. I need microsecond resolution so I have continued with the systick route. The code below works but I am trying to determine if there is a better way using the non-ARM timers or maybe a combination of SysTick and a timer.

    #include <stdbool.h>
    #include <stdint.h>
    #include <driverlib/systick.h>
    #include <driverlib/sysctl.h>
    #include "driverlib/gpio.h"
    #include "driverlib/rom_map.h"
    #include "inc/hw_memmap.h"
    
    
    #define LEDS (GPIO_PIN_1 | GPIO_PIN_2 |GPIO_PIN_3)
    #define SYSTEM_TICKS_PER_SECOND 1000000UL
    
    static uint64_t ticks;
    
    static void timeISR();
    uint64_t    getTicks();
    
    
    
    static void
    timeISR()
    {
        ticks++;
        GPIOPinWrite(GPIO_PORTF_BASE, LEDS, GPIO_PIN_2); //Blue
        GPIOPinWrite(GPIO_PORTF_BASE, LEDS, 0);
    }
    
    
    uint64_t
    getTicks()
    {
        volatile uint64_t pete;
        volatile uint64_t repeat;
        int i = 0;
        volatile static int max = 0;
    
        //Deal with ISR updates during non-atomic read
        pete   = ticks;
        repeat = ticks;
    
        while ( pete != repeat )
        {
          pete   = repeat;
          repeat = ticks;
          i++;
        }
        if (i > max)
            max = i;
        return pete;
    }
    
    
    int
    main(void)
    {
        volatile uint64_t t = 0;
    
        MAP_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, LEDS);
    
        SysTickPeriodSet(SysCtlClockGet() / SYSTEM_TICKS_PER_SECOND);
        SysTickIntRegister(timeISR);
        SysTickEnable();
        SysTickIntEnable();
    
        while (1)
        {
           t = getTicks();
        }
    }