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.

Tiva timer0 split pair periodic

Other Parts Discussed in Thread: STRIKE

I am trying to configure 2 simple periodic timer but the more I read and the more I try different configuration, the more I get confused.

I tried 2 timers, 0 and 1 but get time intervals that do not correspond to the timer load values. I now have tried the WTIMER0 configuration  haphazardly because the documentation is scattered over a few chapters in DRIVER_LIB. Here is the code:

SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);
     
SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0);
     // Configure the  32-bit periodic timers
    TimerConfigure(WTIMER0_BASE, TIMER_CFG_SPLIT_PAIR  | TIMER_CFG_A_PERIODIC  | TIMER_CFG_B_PERIODIC);
    //PWMPeriod2 = SysCtlClockGet() / 100;
    PWMPeriod2=160000;
    // Setup the interrupts for the timer timeout.
    IntEnable(INT_WTIMER0A);
    TimerIntEnable(WTIMER0_BASE, TIMER_TIMA_TIMEOUT);
    TimerIntRegister(WTIMER0_BASE, TIMER_A,TimerA_IntHandler);
    TimerIntRegister(WTIMER0_BASE, TIMER_B,TimerB_IntHandler);
    IntEnable(INT_WTIMER0B);
    TimerIntEnable(WTIMER0_BASE, TIMER_TIMB_TIMEOUT);
    TimerEnable(WTIMER0_BASE, TIMER_A);
    TimerEnable(WTIMER0_BASE, TIMER_B);
    TimerLoadSet(WTIMER0_BASE, TIMER_B, 8000000);   // 0.5 SEC 
    TimerLoadSet(WTIMER0_BASE, TIMER_A, 160000);

Time A interrupts at 1.305 seconds What am I missing? Is there a pre-scaler? Do I have to set the clock source?

thanks

Claude

  • Hi Claude,

    The info can be a bit tricky to get familiar with, but it's pretty much all there, datasheet+tiware libraries guides+source codes. 

    Before I analyze the rest of the code I'm gonna ask you something.
    The Timers always have the system clock fed into them. What do you think is your processor speed set to?

  • The clock is set to 16Mhz:
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);

    Systick period set is 160000 giving a 1.28msec Systick measured with a scope on a toggled bit.
  • The clock is not set to 16MHz, it is set to 200MHz which won't work. Change SYSCTL_USE_PLL to SYSCTL_USE_OSC.

    Randy

  • I added a SysCtlClockGet() function to see the clock frequency the result is 12.5Mhz, so I tried to settings:
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ); gives 16Mhz and
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ); gives 12.5Mhz, the internal PIOSC.
    This explains Systick timing. But 16Mhz or 12.5Mhz still gives timing in the seconds range for TimerA .
  • Bravo to both Randy & Luis for their awareness & diligence.

    This "unclear" parameter "SYSCTL_SYSDIV_x" has plagued many - for quite some time. Quite recently - right here - I proposed that the parameter be renamed, to better convey its "real application/meaning. "SYSCTL_SYSDIV_PLL_x." (this as the real/desired divide impacts the PLL primarily - such (perhaps) should be noted!) Or not - and we can rely upon "experience store" or vendor's "inside knowledge."
  • Hi,

    Exactly why I asked what you thought the clock was, to see if you realized your error.

    ClaudeArpin said:
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ); gives 12.5Mhz, the internal PIOSC.


    Not at all. The internal PIOSC is 16Mhz also. 12.5Mhz is the default configuration when using the PLL and not setting a division.


    You are using the PLL in your setting. The PLL generates a 400Mhz clock which later is divided by 2 making it 200Mhz.
    The parameter SYSCTL_SYSDIV_1 sets the division after the PLL. Hence 200Mhz/1 gives you 200Mhz, an overclock. 
    It seems the function didn't allow the clock to be set, and left it at the default 12.5Mhz, because as far as I know the only hardware fail safe would set the system clock to the PIOSC (and could cause reset). Anyhow I think it's simply and error, anything can happen when you overclock the processor.
    Check more in 5.2.5 Clock Control on your datasheet.

    Could your handler, or better yet, your complete test code?




  • Out of the fire into the frying pan. I had changed to clock source from the crystal
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ)
    to the PLL because of the ADC issue #8 in the errata. I will have to find a solution for this but I still have my issue with timer0 TimerA and the above setting. Is there anything else that could be affecting the timer?

    thanks
    Claude
  • Hi Claude,

    Could you post your complete test code?
  • Are you sure you set the PLL and dividers correctly?
    If you truly want 16MHz, you must use SYSCTL_SYSDIV_12_5.
    Unless you are concerned about power consumption, why not run this puppy at 80MHz using SYSCTL_SYSDIV_2_5 ?
  • Randy, in this case he seems to be using directly the oscillator instead of the PLL so it doesn't mater what that parameter is.
    I agree, why 16Mhz? Well I guess it works for tests.
  • Claude said:

    I had changed to clock source from the crystal
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ)
    to the PLL because of the ADC issue #8 in the errata.

    This still requires a valid SYSDIV value.

    Randy
  • I apologize, bad setup. I was measuring with the PLL, with the crystal, the timer works as advertised.
    I need the crystal for accuracy so I have to check if I can use another clock source for the ADC.

    thanks
  • Well, that error is that you can't directly use the PIOSC as a source as the system clock (since by default the ADC has the PIOSC and the error states that the ADC and system clock can't have both the MOSC and PIOSC).

    What do you mean by valid? SYSCTL_SYSDIV_1 is valid and still the same stands. The clock is directly from the Main oscilator so it doesn't matter if it's SYSCTL_SYSDIV_1 instead of SYSCTL_SYSDIV_12_5.
  • You can use the PLL and still satisfy the ADC errata.
    The PLL is just as accurate as the crystal.

    Randy
  • Luis,
    The clock is not direcly from the main oscillator if you use the PLL. That what was stated "I changed the clock source .... to the PLL.
  • oh, it seemed to me that the poster said he started using that line of code. I misread.
    Sorry about that Randy
  • Yes, when I look at the data sheet diagram fig 5-5 it is clear PIOSC can to the ADC while MOSC is the system clock. The tricky part is how to enable all this. In DRIVER_LIB ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL,1) will set the PIOSC as the ADC clock but how can I enable both the MOSC as the system clock and the PIOSC?
  • Hi Claude,

    The function SysCtlClockSet() is what configures the system clock so you can use it to either use the main oscilator or the PIOSC. Then you can also chose to use one of them directly or to feed them into the PLL for which you will also need to set the correct division (PLL gives 200Mhz so for a 80Mhz part, 2.5 is the smallest division you can make).

    I don't quite understand what you mean "and the PIOSC" in "how can I enable both the MOSC as the system clock and the PIOSC?" Could you clarify? You seem to be saying you want 2 different sources at the same time for the system clock.
  • Looking at fig 5-5 Main Clock Tree in the datasheet, there is a direct line from the PIOSC to the ADC clock selector. I was asking if it is possible to have 2 clocks, the PIOSC for the ADC and the MOSC for the system clock. The errata ADC#8 seems to suggest this is possible:
    "Configure the MOSC as the system clock source and the PIOSC as the ADC clock source."
    If not, then the solution would be to use the MOSC and the PLL with a divisor of 10 giving me 20MHz which is appropriate for my application.
    The command would be: SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);
    what do you think?
    thanks
    Claude
  • Yes, indeed it is possible for the ADC to use the PIOSC and the System clock the MOSC.

    The ADC as a independent config than the System clock like you saw. What the ADC enforces is that it needs a 16Mhz clock. By default it uses the PLL divided by 25 (a different divider from the system clock divider and with a fixed value) and it doesn't depend in any way with the system clock, the system clock has his own config but he system clock needs to be at 16Mhz or higher when using the ADC.

    The best option I'll tell you, if the precision is good enough for you, is use the PLL to feed the system clock. If you use the PLL you would have no problems at all. The ADC uses the PLL by default so you would never even face this problem when setting up the clock.

    But I have still have yet to understand. This began with the timer, why as it escalated to ADC related issues. It should not cause problems at all besides the ADC not sampling.
    You began testing and you were overclocking the system. That causes unpredictable behavior. How and what are you testing right now? Is it still the timer? What is your test code now? What should it be doing and what is it doing wrong?
  • Luis you hit the nail on the head, clocking issues can affect multiple pieces of code. I had another post about the ADC hanging and was directed to the errata ADC#8. I was using the MOSC for both the ADC and system
    "SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ)".
    So I changed to the PLL
    "SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);",
    not understanding how the PLL works.
    I my book you drive a PLL from a low frequency and put the divider in the feedback loop to increase the output frequency, so I assumed, incorrectly, that USE_PLL plus SYSDIV_1 plus "XTAL_16MHZ" would yield a 16Mhz output.

    "SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);", fixed the ADC problem, no more hanging. I then completed my ADC testing.

    The next step was the timer and I found inconsistent results. So I started this post about the Timers and you pointed out I was overlocking. I then did measurements of the timer output(using bit toggling and a scope) alternating between "SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);" and "SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ)".
    After a few iterations I finally was able to confirm PLL is overlocking and the timer is accurate with
    "SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ)".
    Out of the frying pan and into the fire: the solution to my ADC problem turns out to be worst by creating an overlocking issue.
    Basically this is a clocking issue that affects the ADC, the timer and the Systick.
    I an reluctant to use the PLL for the main clock because I have an RTC function, that must be accurate to 30 minutes per year, running off one of the timers. ( I should of implemented the 32Khz crystal but I did not).
    How can I have the best of both worlds, MOSC for the system and PIOSC for the ADC?

    all the best
    Claude
  • Sorry Claude, you have to understand that I don't remember any other post you made about the ADC. I got confused because you suddenly you come speaking about the ADC when first it was about timer problems (zzzzz electronics exam fried my brain)

    So you want the ADC to have the PIOSC and the system clock to have the MOSC. Does it have to be the MOSC or do you simply want to have the clock at 16Mhz? Now, according to the errata:
    Simplest way, use the PLL with a 12,5 division.

    If you really want the MOSC for the system clock simply set the system clock like:
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ)
    and the ADC clock with:
    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC, ADC_CLOCK_RATE_FULL);

    Now the harder one, PIOSC for both System clock and ADC, it seems possible but is the more complicated to set, it seems you need a bit of configs out of the Tivaware libraries.


    If you could confirm that this will work smoothly it would be appreciated.
  • Claude,

    I think you are under the impression that the PLL is not accurate enough for your RTC.  This is not true, the PLL is phase locked to the crystal so its accuracy is the same as the crystal.

    If you enable the PLL as the system clock, the ADC will use the PLL divided by 25 by default and the ADC errata will be satisfied. You will still have an accurate source for the timers.

    I'm not trying to beat you up on this, but I still don't understand the reason for running the system clock at 16 MHz. This affects the execution speed of your code.

    Randy

  • Randy,
    you can beat me up all you want, I don't bruise easily.
    I think your solution is the simplest, since the PLL is locked to the crystal. The simpler the better.
    I can set the system clock to 20 Mhz:
    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ); // 20 Mhz
    and that should work.
    I run the system at the lowest possible speed to save current, my system is battery powered.
    thanks for the help.
  • Sounds like you have everything under control. Enjoy your project.

    Randy
  • Randy - may I commend your efforts?

    Thank you - great presence here - you, Luis, Robert, Roberto (in deep cover), Chester & few others make this forum (to my belief) "best in class."

    Amit is (of course) other-worldly in his knowledge of this MCU family - but sometimes "outsiders" strike new paths - free of the (seeming) necessary, vendor-only constraints... Great to have you aboard!
  • Yes, and fast! You don't wait days for a response. Thanks to all
  • Well I have to thank Randy because it seemed I was with half my brain working in some answers.

    Good luck with your project Claude :D
  • ClaudeArpin said:
    You don't wait days for a response

    Sometimes true - fails when, (Suggestions to Vendor) "Guidelines for Posters" (to best enable the clear/complete (i.e. necessary) description of issues) and/or "Elimination or Correction of "sub-optimal" decisions (i.e. famed/plaguing 0Ω resistors on LPads),  Default of PF0/PD7 to (unwanted by most all) NMI, & "scattersite" locating of normal/customary MCU centric data.    (could be, "most anywhere" - and moves, often!)

    Best in class does not preclude ... "Could be better!"    (w/slight NIH tweaks...)    Herd of turtles (hi-beams flashing) pass this vendor in such "fixes."  

  • Thanks for the kind words.
    In my opinion, that's what E2E is all about. "Engineer to Engineer", a place for folks to meet and exchange ideas. I never thought of this forum as a place to get instant help from TI representatives or a soap box to complain about their products. No doubt, modern hardware, including the ARM platforms are very complex and it takes a bit of digging and learning to sort out all of the details. And there will always be bugs and errata to deal with. This can be especially daunting to a new comer.

    My $.02
    Randy
  • You're quite welcome - again thanks.

    May I (briefly) address, "complain about products?"   I was past taught by lawyer/investors never to "complain/protest" - unless or until - I had a (clearly superior) alternative.    And - for some while now - I've posted such suggestions (in great detail) right here.  Most always they're, "Duly noted" - yet the "fix" (always) seems to elude/over-challenge.    (NIH rises as high suspect - here)

    Of course (bugs & errata), "come w/the terrain."    My comments don't speak toward those (necessary) evils - they speak (properly I believe) to things which (many) agree stem from poor and/or misguided decisions - which cause great client-user pain/suffering - yet are allowed to remain - uncorrected - for years!
     
    We may, "remain quiet/compliant" or we may present (reasoned) alternatives - that's what I believe E2E to be more, "properly" about... Success here - stems not just from tech. - but from carefully considered (and flexible) command decisions - gleaned from (much) user feedback & experience!

  • One simple improvement would be to have people like me post the completed code so others can just go to the end of the post to see the solution. Event better a system by which tested code snippets could be saved in a repository for easy access.

    So again thanks to all and here is my code:

     SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ); // 20 Mhz    
    // PLL used for the system clock and the ADC  
    //=================  timer 0 config  2 x 32 timers =================
         SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0);
         // Configure the  32-bit periodic timers
        TimerConfigure(WTIMER0_BASE, TIMER_CFG_SPLIT_PAIR  | TIMER_CFG_A_PERIODIC  | TIMER_CFG_B_PERIODIC);
        
        // Setup the interrupts for the timer timeout.
        IntEnable(INT_WTIMER0A);
        TimerIntEnable(WTIMER0_BASE, TIMER_TIMA_TIMEOUT);
        TimerIntRegister(WTIMER0_BASE, TIMER_A,TimerA_IntHandler);
        TimerIntRegister(WTIMER0_BASE, TIMER_B,TimerB_IntHandler);
        IntEnable(INT_WTIMER0B);
        TimerIntEnable(WTIMER0_BASE, TIMER_TIMB_TIMEOUT);
        TimerEnable(WTIMER0_BASE, TIMER_A);
        TimerEnable(WTIMER0_BASE, TIMER_B);
        TimerLoadSet(WTIMER0_BASE, TIMER_B, 10000000);   // 0.5 SEC 
        TimerLoadSet(WTIMER0_BASE, TIMER_A, 200000);
         
    //*****************************************************

    All the best

  • OK, I can't resist one more interesting tidbit.
    If you run a wide timer in 64 bit mode, driven from an 80 MHz. clock, it will take 7,306 years, 238 days, 6 hours, and 42 minutes to overflow.
    I haven't actually tried it yet.

    Randy
  • The Wide timers are probably more useful in split mode since you get 32bit timers with capture and PWM modes :)
    Couldn't imagine a application that required a timer to run so much time straight, without being able to save the overflow, with so small unitary time (1/80Mhz), imagine also the error accumulated even with a good crystal.
  • Randy Ott said:
    it will take 7,306 years, 238 days, 6 hours, and 42 minutes to overflow.

    That's while running downhill - is it not?

    And to Luis - does this vendor's "Wide Timer" - when in PWM mode - (then) enable 32 bit PWM resolution?    (I recall 16 bit as the (usual) Timer-PWM limit)

  • Hi cb1,

    The timer does indeed allow for 32bit PWM resolution. At least it allows for 32bit numbers. Now if it's actually capable of giving that output I don't know. I haven't tested.

    Once to control a servo I used a wide timer instead of a timer+prescaler. At 80Mhz, to give the 50hz signal to a analog servo the load value would need to be about 1538461, hence why I used the wide timer (didn't feel like using a prescaler).
  • Luis Afonso said:
    The timer does indeed allow for 32bit PWM resolution

    And friend Luis - you are right - once again.    Here - from the TM4C123 data manual:   (note that the non-wide timers - even though 32 bit capable (in one-shot. periodic or RTC modes) - are confined to just 16 bits when ordered into PWM mode.    That's what I recalled - and why I asked...)    Thanks.

  • Digging a little deeper reveals that the non-wide timer running in 16-bit PWM mode also has 8 more bits of extension available yielding 24-bit resolution.

    This requires loading the timer match as well as the prescale match registers to control the PWM.  This can be tricky if the PWM needs to be updated on the fly as writes to these registers is not easy to do atomically.

    (The same holds true for the 32-bit wide timer PWMs)

    Randy