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.

TM4C129ENCZAD: Unable to clear General Purpose Timers to zero.

Part Number: TM4C129ENCZAD

Tool/software:

Hello,

I am using the General Purpose Timers to count edges and record the total flow from a flow meter. 

I need to clear the timer value and get it to start from 0 again whenever the flow starts and I need to record the number of edges. However, the zeroing part is not working. Below is the function code for the timer reset that I created.:

void
TimerReset(uint32_t ui32Base, uint32_t ui32Timer)
{
if((ui32Timer & TIMER_A) == TIMER_A)
{
HWREG(ui32Base + TIMER_O_TAV) &= 0x00000000;
}
if((ui32Timer & TIMER_B) == TIMER_B)
{
HWREG(ui32Base + TIMER_O_TBV) &= 0x00000000;
}
}

Below is the timer set up code for reference:

SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);
TimerConfigure(TIMER2_BASE,
(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP));
TimerControlEvent(TIMER2_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
TimerControlEvent(TIMER2_BASE, TIMER_B, TIMER_EVENT_NEG_EDGE);
TimerPrescaleSet(TIMER2_BASE, TIMER_BOTH, 0xFF);
TimerLoadSet(TIMER2_BASE, TIMER_BOTH, 0xFFFF);
TimerEnable(TIMER2_BASE, TIMER_BOTH);

I also tried disabling and enabling the timer when zeroing and that didn't work either. 

Any help regarding this would be appreciated.

  • HI,

       I'm looking into the problem right now.

  • Hi,

      I cannot replicate your problem. I try to write 0x1234, 0x5678 and 0xABCD to the TAV register and I can see the TAR register updated with the same values. See below. 

    Below is the modified code I use from the TivaWare example. If I keep writing different values in a loop then I can also see the TAV change in the register window.

    int
    main(void)
    {
        //
        // Run from the PLL at 120 MHz.
        // Note: SYSCTL_CFG_VCO_240 is a new setting provided in TivaWare 2.2.x and
        // later to better reflect the actual VCO speed due to SYSCTL#22.
        //
        g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_PLL |
                                                 SYSCTL_CFG_VCO_240), 120000000);
    
        //
        // Enable the peripherals used by this example.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    
        //
        // Configure the GPIO to be CCP pins for the Timer peripheral.
        //
        MAP_GPIOPinConfigure(GPIO_PL4_T0CCP0);
        MAP_GPIOPinConfigure(GPIO_PL5_T0CCP1);
    
        //
        // Configure the GPIO for the Timer peripheral.
        //
        MAP_GPIOPinTypeTimer(GPIO_PORTL_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    
        //
        // Initialize the UART and write initial status.
        //
        ConfigureUART();
        UARTprintf("Edge Capture Example for measuring the high period of an"
                   "input signal.\n");
        UARTprintf("Input a square wave onto pins PL4 and PL5 of the "
                   "EK-TM4C1294XL.\n");
    
        //
        // Initialize Timers A yo run as periodic up-count edge capture
        // timers.  This will split the 32-bit timer into two 16-bit timers.
        //
        MAP_TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR |
                TIMER_CFG_A_CAP_COUNT_UP ));
    
        //
        // To use the timer in Edge Time mode, it must be preloaded with initial
        // values.  If the prescaler is used, then it must be preloaded as well.
        // Since we want to use all 24-bits for both timers it will be loaded with
        // the maximum of 0xFFFF for the 16-bit wide split timers, and 0xFF to add
        // the additional 8-bits to the split timers with the prescaler.
        //
        MAP_TimerLoadSet(TIMER0_BASE, TIMER_BOTH, 0xFFFF);
        MAP_TimerPrescaleSet(TIMER0_BASE, TIMER_BOTH, 0xFF);
    
        //
        // Configure Timer A to trigger on a Positive Edge
        //
        MAP_TimerControlEvent(TIMER0_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
    
        //
        // Clear the interrupt status flag.  This is done to make sure the
        // interrupt flag is cleared before we enable it.
        //
        MAP_TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT );
    
        //
        // Enable the Timer A interrupts for Capture Events.
        //
        MAP_TimerIntEnable(TIMER0_BASE, TIMER_CAPA_EVENT );
    
        //
        // Enable the interrupts for Timer A  on the processor (NVIC).
        //
        MAP_IntEnable(INT_TIMER0A);
    
        //
        // Enable processor interrupts.
        //
        MAP_IntMasterEnable();
    
        HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x00001234;
        HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x00005678;
        HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x0000abcd;
    
    
        //
        // Enable both Timer A to begin the application.
        //
        MAP_TimerEnable(TIMER0_BASE, TIMER_A);
    
        while(1)
        {
            HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x00001234;
            SysCtlDelay(10000);
            HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x00005678;
            SysCtlDelay(10000);
            HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x0000ABCD;
            SysCtlDelay(10000);
    
        }
    
    }

  • Thats surprising. Let me try this on my end.

  • So I tried this code:


    and below is the log output, which clearly seems to indicate the zeroing never worked:

    I don't know what I am doing wrong here. 

  • I also tried this :


    I don't see the TAV and TBV going to 0 either even though I am setting it to 0.

  • Have you tried my code as is? When I single step through my code I could clearly see the TAR updated with the value from TAV. Why don't you do the same? Can you compare your code to my code? I'm not sure if you run into a race condition where you are writing a new value to TAV at the same time the counter is incrementing to the next value. The incremented value may have overwritten the value you wrote. For example, the current TAV is 1234 and next increment value will be 1235. If you write a zero, it may be overwritten with 1235 in the next cycle. This is just a thought. Why don't you try to disable the timer before writing 0 to TAV? 

  • I tried disabling before writing 0 to TAV and that didnt work either. Your code is very similar to mine, except you are using Timer0 and I am using Timer2 and you are updating the value to random values rather than 0, so I don't see anything particularly different to try. The race condition part yes but I guess the TAV is a free running timer that should always increment while the micro is running so if it is overwriting any value I write, that basically means the functionality for resetting the timer is not available but I doubt that is the case. I can try stepping through registers using the debugger but my guess is what I will see is the counter registers not being set to 0. 

  • HI,

      Again, have you tried my code as is. I just modified the code to constantly write 0 to TAV and I can see TAR equal to 0 in the register window. 

    I even try manually writing ABCD directly in the register window to the TAV register and I will see TAR change to ABCD as well. Why don't you just try my code first, don't modify anything and what do you see?

  • Thank you Charles for helping me out. I really appreciate you putting in the effort to help solve this problem. Let me try this and get back to you.