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.

TM4C129ENCPDT: configuring single 32 bit capture timer.

Part Number: TM4C129ENCPDT

How does one configure a Timer to have 32 bit capture resolution on TM4C129ENCPDT? Tivaware manual is confusing me about how to make TIMER0A and TIMER0B become a single 32 bit capture. I am not sure I am using the "TIMER_BOTH" correctly. I tried without "TIMER_CFG_SPLIT_PAIR" in the "TimerConfigure" but then the interrupt is never called.

I am trying to measure time between pulses which are 10mS apart. So, having 32 bits or 4294967296 cycles (4.3 billion) and running off the main clock at 120MHz should give me enough to measure 10mS. 

Here is code configuring TIMER0:

***************************

ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
ROM_SysCtlPeripheralEnable( SYSCTL_PERIPH_TIMER0 );
ROM_GPIOPinConfigure( GPIO_PA0_T0CCP0 );
ROM_GPIOPinTypeTimer( GPIO_PORTA_BASE , GPIO_PIN_0) ;

ROM_IntMasterEnable();
ROM_TimerConfigure( TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME | TIMER_CFG_B_CAP_TIME );

ROM_TimerControlEvent( TIMER0_BASE, TIMER_BOTH, TIMER_EVENT_POS_EDGE );

ROM_TimerLoadSet( TIMER0_BASE, TIMER_A, 0xFFFF);
ROM_TimerLoadSet( TIMER0_BASE, TIMER_BOTH, 0xFFFF);
ROM_TimerIntClear( TIMER0_BASE, TIMER_CAPA_EVENT );
ROM_TimerIntClear( TIMER0_BASE, TIMER_CAPB_EVENT );
ROM_TimerIntEnable( TIMER0_BASE, TIMER_A );
ROM_TimerIntEnable( TIMER0_BASE, TIMER_B );
ROM_IntEnable( INT_TIMER0A_TM4C129 );
ROM_IntEnable( INT_TIMER0A );
ROM_TimerEnable( TIMER0_BASE, TIMER_A);
ROM_TimerEnable( TIMER0_BASE, TIMER_B);

************************************

and the handler:

*************************************

void TIMER0A_Handler(void){ 
ROM_TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT );
capture_duration = ROM_TimerValueGet(TIMER0_BASE, TIMER_A );

ROM_TimerLoadSet( TIMER0_BASE, TIMER_BOTH, 0xFFFF);
}

***************************************

The value in "capture_duration" is not transferring from one of the timer registers. But that doesn't surprise me because I don't think things are set-up correctly.

***I have confirmed (unless I am very confused)***

1- The capture interrupt routine is correctly getting called.

2- The timer registers are changing.

3- I do have a 10mS period toggling input on PA0 (pin 33).

If it's relevant I am using Keil Microvision 5.24.1. and a J-Link.

I read several excellent prior posts including:

"https://e2e.ti.com/support/microcontrollers/stellaris_arm/f/471/t/358696"

   and

"e2e.ti.com/.../331045"

Thanks,

Jeff

  • Hi Jeff,

      You can only form a 24-bit timer for input capture only, not 32-bit. Please refer to the below datasheet excerpt on the timer in time capture mode.

    In Edge-Time mode, the timer is configured as a 24-bit up- or down-counter including the optional
    prescaler with the upper timer value stored in the GPTMTnPR register and the lower bits in the
    GPTMTnILR register. In this mode, the timer is initialized to the value loaded in the GPTMTnILR
    and GPTMTnPR registers when counting down and 0x0 when counting up. The timer is capable of
    capturing three types of events: rising edge, falling edge, or both. The timer is placed into Edge-Time
    mode by setting the TnCMR bit in the GPTMTnMR register, and the type of event that the timer
    captures is determined by the TnEVENT fields of the GPTMCTL register.

    Let's say you want to use the TIMERA to create your 24-bit timer in input time capture mode you will need to use.

    ROM_TimerConfigure( TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME ); 

    The 24-bit timer is formed by the 8-bit prescale counter and the 16-bit preload counter. This means that if you want to use in 24-bit mode you will need to configure both the prescale and the internval load registers using below two API.

    TimerPrescaleSet()
    TimerLoadSet()
  • Great Charles! In case it's useful to someone else, here is the working (but not rigorously tested yet) code for a 24 bit capture.

    *****************************************************************

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_SysCtlPeripheralEnable( SYSCTL_PERIPH_TIMER0 );
    ROM_GPIOPinConfigure( GPIO_PA0_T0CCP0 );
    ROM_GPIOPinTypeTimer( GPIO_PORTA_BASE , GPIO_PIN_0) ;

    ROM_IntMasterEnable();
    ROM_TimerConfigure( TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME );
    ROM_TimerClockSourceSet( TIMER0_BASE, TIMER_CLOCK_PIOSC );
    ROM_TimerPrescaleSet( TIMER0_BASE, TIMER_A, 0xFF);
    ROM_TimerControlEvent( TIMER0_BASE, TIMER_BOTH, TIMER_EVENT_POS_EDGE );
    ROM_TimerLoadSet( TIMER0_BASE, TIMER_A, 0xFFFF);
    ROM_TimerIntClear( TIMER0_BASE, TIMER_CAPA_EVENT );
    ROM_TimerIntEnable( TIMER0_BASE, TIMER_A );
    ROM_IntEnable( INT_TIMER0A_TM4C129 );
    ROM_IntEnable( INT_TIMER0A );
    ROM_TimerEnable( TIMER0_BASE, TIMER_A);

    ******************************************************************************

    void TIMER0A_Handler(void){
    ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT | TIMER_CAPA_EVENT );
    capture_duration = 0xFFFF - ROM_TimerValueGet(TIMER0_BASE, TIMER_A );

    ROM_TimerLoadSet( TIMER0_BASE, TIMER_A, 0xFFFF);
    ROM_TimerPrescaleSet( TIMER0_BASE, TIMER_A, 0xFF);
    }

  • Glad your problem solved and thanks for sharing your working code with the community.
  • Good for you. Glad that you persisted - reached your goal.

    As a "quick/dirty" check - I calc'ed that @ 24 bits - your "Timer Max" was just under 140mS. Might you test & confirm?
    In comparison - @ 32 bits (stained napkin) reveals ~35S as, "Timer Max."
    And for completeness - @16 bits ~540µS was "Timer Max." (all assumed 120MHz System Clock)

  • Hi cb1,
    The poster is looking to measure 10ms inputs. In additional he is using PIOSC as the clock source for the TMR.
  • Jeffrey Kittredge said:
    ... having 32 bits or 4294967296 cycles (4.3 billion) and running off the main clock at 120MHz

    Your honor - may the defense present exhibit "A" - logged into evidence - and presented in the (very) top posting?

    In addition - where "serious measurements" are sought/required - we were taught that (only) an xtal or xtal-osc were suitable.       (the "precision" w/in PIOSC may prove an illusion - is that not so?)

    And - if the Timer clock is reduced to (just) 16MHz - the granularity increases by 7.5!     (120/16)      

  • cb1- in the code of second post I decided to switch to PIOSC after realizing that direct hardware supported 32 bits was not possible. I should have indicated as such.

     I share your concern about the accuracy/ drift of the PIOSC. I believe for my application +/- 5% should be fine. I am not even sure what it rates to. I am going to try with PIOSC, and if it won't suffice; then figure out how to use a crystal. FWIW, it's not apparent to me how to do "captures" using an external clock. I haven't put much effort into it though. As they say, necessity is the mother of invention. I looked at both the datasheet block diagram and tivaware clocksourceset() which make it look like only MainClock and PIOSC can be used. But, I think I am missing something because I assume captures can use a precision external crystals as the clock input and still capture another hardware input event.

  • Thank you for a most detailed & effort-laden response.     Outstanding.

    I may have several insights which prove useful.    (maybe)

    The external xtal/xtal-osc - employed in conjunction w/MCU's PLL - enables a System Clock of up to 120MHz.      I believe that the System Clock - or its (halved value) - is then presented as input to the Timer(s).       Note the verbage, "the possible clock sources are the "System Clock" or the "precision" (marketing's over-inflated opinion!) internal oscillator" have (both) escaped entry into this drawing!      Why - we may  ask - is that?

    Never/ever would I (or experienced/reasonable others) characterize vendor's "internal R-C oscillator" as "precision!"         Especially while "avoiding" such award to the (clearly, KNOWN/Proven superior) external xtal/xtal-osc.       (which truly qualifies as "precision" - which the internal "attempt" meets (only & maybe) in marketing's eye.)

    The loss of granularity - in addition - (a 120/16 factor) will impact ALL of your timer usage - thus should demand (some) attention.       Perhaps "red-lining" all (improper/over-promoted) occurrences of "precision" just preceding "internal oscillator."         (R-C oscillator - even "if" Improved - does not confer "precision" - not close!)

  • So getting better precision for the timer/ capture module would come by virtue of deriving MainClock from a precision crystal? And then dividing MainClock as the timersource? Not by having a separate precision crystal which is only used for timer/ capture?

    I have no real (cost/ space) problems putting a crystal down to source mainclock from.
  • I'm not aware of this class MCU providing a "unique xtal input" - reserved solely for the Timer(s).

    Feeding the MCU's oscillator input pins w/a properly chosen, closely placed/driven, name brand xtal, w/proper support components - usually provides requisite accuracy and (repeatability - thus precision.)      Which is NOT achieved via the enfeebled internal device (again not close!) - despite its "over-promotion."      (which magnifies the sin - is that not so?)