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.

How does systick work - Tiva C Launchpad

Forgive me for the N00b questions.

However trying to get my head around this:

uint32_t time;

void SysTick_IntHandler(void)
    {
       time++;
    }

int main(){

    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL| SYSCTL_OSC_INT);
    uint32_t clock=SysCtlClockGet();
    SysTickIntRegister(SysTick_IntHandler);

SysTickPeriodSet(SysCtlClockGet());
    IntMasterEnable();
    SysTickIntEnable();
    SysTickEnable();
    SysCtlDelay(SysCtlClockGet()/3); //approx 1 sec
    SysTickDisable();

}

When running this code I don't get a count of 1 in time..

I get around 6.

Would this be because systick runs off pll?

If I run it with SYSCTL_USE_OSC I get a count of 1. However the chip then runs at around 5Mhz.

I guess I'm trying to get a constant count of 1sec for timer apps but I would like to run the processor a bit quicker than 5Mhz.  Any ideas?

I have thoroughly read the datasheets and gone through all of the example code that I can find but I can't seem to get my head around some of this. 

Thanks in advance.

Warwick

  • Hi Warwick,

        Try to set, your system clock at 16 MHz same with the example at "\\examples\peripherals\systick", and see if you still get the same results. 

    //
        // Set the clocking to run directly from the external crystal/oscillator.
        // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
        // crystal on your board.
        //
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    -kel

  • Hi Markel,

    Yes this does work.  But it is kind of the same issue in a way at least.  Once again I'm left wondering how systick works.  It seems as though if I say SysCTL_USE_OSC it works in a predicable fasion.  However I would have liked to run the clock at a faster speed and just interrupt every second or half second to process some instructions.  

    My understanding is that I need to use pll to run it at a faster rate..  

    However the way the driverlib reads it says as follows:

    "The SysTick counter runs on either the system clock or the precision internal oscillator (PIOSC)
    divided by 4."

    So that would suggest that I should be able to change it so that I can run the system clock at 40Mhz / 80Mhz but run systick off the PIOSC.

    I can't seem to see anyway to change it though..

    Any thoughts?

    Thanks

    Warwick

  • Hi Warwick,

         I have not much experience using the PIOSC. I read something at the Tivaware Peripherals Library User Guide 1.0. See below.

        Chapter 21. System Control: "The PIOSC is not available on all Tiva devices"

         I have not confirmed this myself. So, I am not entirely sure. 

         If you want to set the system clock to run at 80 Mhz, just use the PLL. Refer, to your device datasheet, Table 5-6. Examples of Possible System Clock Frequencies with DIV400=1.

    -kel     

  • Hmm Ok..

    I think we have a little bit of a misunderstanding.

    What I'm trying to do:

    1. Run at 80Mhz

    2. Set an interrupt at every 1 second, reasonably reliable.  Doesn't have to be perfectly accurate but at least a little bit would be nice.  

    I don't seem to be able to do both things at once.

    I'm either working at 16Mhz maximum and somewhat accurate or I'm working at 80Mhz and can't seem to get a 1 second interrupt.  I.e. I have no value to work off to get 1 s and it seems to vary slightly if I use SysCtDelay(SysCtlGetClock()/3) this shoudl be 1s I sometimes get a count of 6 in the timer, sometimes it's 7.

    Does that make sense?

    I would have thought that being able to run a clock of some sort whilst processing at a much higher speed would have been a basic function.  But then I haven't been playing around with this stuff for very long so far.

    Thanks

    Warwick

  • Hi Warwick,

         It is sleep time where I am. So, I am a little bit off. Sorry, if there are any misunderstandings.

         If I have more time tomorrow, I will try to do a little systick test with one of my TI kits. As I have said in my earlier post, that "The PIOSC is not available on all Tiva devices", I will skip any advice regarding PIOSC.

         You have run the systick with a 1 second systick interrupt using these SysCtlClockSet code below.

         SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    What you want is to set the system clock at 80 Mhz. Try this code line below, to set the system clock at 80 Mhz.

         SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    As far as I know, you will still get a 1 second systick interrupt if you change your system clock to 80 Mhz with this SystickPeriodSet() code below. I will re-verify this, if I have time.

         SysTickPeriodSet(SysCtlClockGet());

    Also, use the systick example at "\\examples\peripherals\systick" as base for your test. From your shared code at the top of this post, you are missing the while loop at the end of main().

    -kel

  • Hehe it was sleep time where I was as well so I know the feeling..

    I have just rerun the testing using the exact code out of the examples/Systick.c

    What I get is as follows:

    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    System Clock is set at 16Mhz and I get 1 tick per second.

    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    System Clock is now set to 5.3Mhz and I get 1 tick per second.   Not sure how I get that..

    But that's the value of SysCtlClockGet()..

     

    Thanks for all of your help.

  • So I think I've maybe found the answer.

    P 136 of the datasheet for the chip shows me how to run systick off PIOSC/4.

    As Follows:

       

    SysTickEnable();

    //Set to PIOSC/4

    HWREG(NVIC_ST_CTRL)^= NVIC_ST_CTRL_CLK_SRC;

    I notice that I have to do this after I set Systick Enable as systickenable sets the CLK_SRC bit to 1 which I don't want.

    This seems to now count at exactly 1 second intervals or very close to it at least.

    Bit of a backward way of doing it thought I would have thought.

     

     

  • Hi Warwick,

    A couple of additional notes on this. You may have already figured these out, but I thought they might be helpful for others with similar issues.

    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL| SYSCTL_OSC_INT);
    SysTickPeriodSet(SysCtlClockGet());

    One reason that this statement might not produce 1-second interrupts is because SysTick doesn't have enough bits. The 24-bit SysTick timer can only count to about 16,000,000 (decimal), which means that the longest period you could generate with these clock settings is in the neighborhood of 5 interrupts per second. This also explains why this strategy does work for system clock speeds of 16 MHz and below. Using PIOSC (16MHz) or PIOSC/4 (4MHz) as the source for SysTick as you are doing here solves this problem.

    As another note, the function call "SysCtlDelay(SysCtlClockGet()/3)" is a little less reliable at higher clock frequencies. The problem mainly exists because Flash access takes more than one clock cycle at 80 MHz, so the constant 3-instruction loop can take longer than 3 cycles to complete. The additional delay is mitigated by a pre-fetch buffer, so you should get relatively close to 3 cycles per loop, but the performance may not be exactly the same on every loop.

    For a more reliable solution, you might want to try the ROM version "ROM_SysCtlDelay()", which will not have any access-time penalties at the higher system clock frequencies.

    Regards,

    Christian

  • Markel Robregado said:
    Chapter 21. System Control: "The PIOSC is not available on all Tiva devices"

     This has been confirmed by TI StellarisAngela to be a document error from another post, and have raised a bug against it. See post below.

        Setting ADC clock for deep sleep mode

    -kel

  • That is interesting.

    Systick definitely works at 16Mhz when I set the CLK_SRC bit to 0..

    It also reads in the datasheet as thought it does definitely have a PIOSC.

    For example 1.3.4.2 on page 57 of the datasheet reads:

    24.9.2 PIOSC Specifications

    Table 24-15. PIOSC Clock Characteristics

    Parameter Parameter Name Min Nom Max Unit

    Internal 16-MHz precision oscillator frequency variance - - ±3% -

    (factory calibrated at 25 °C C and 3.3 V) across the

    specified voltage and temperature range F

    So I'm unsure where this comes from, maybe for a different tiva c processor to the one installed onto the tiva c Launchpad?

    Thanks

     

    Warwikc

  • Christian Jolivet said:

    Hi Warwick,

    A couple of additional notes on this. You may have already figured these out, but I thought they might be helpful for others with similar issues.

    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL| SYSCTL_OSC_INT);
    SysTickPeriodSet(SysCtlClockGet());

    One reason that this statement might not produce 1-second interrupts is because SysTick doesn't have enough bits. The 24-bit SysTick timer can only count to about 16,000,000 (decimal), which means that the longest period you could generate with these clock settings is in the neighborhood of 5 interrupts per second. This also explains why this strategy does work for system clock speeds of 16 MHz and below. Using PIOSC (16MHz) or PIOSC/4 (4MHz) as the source for SysTick as you are doing here solves this problem.

    As another note, the function call "SysCtlDelay(SysCtlClockGet()/3)" is a little less reliable at higher clock frequencies. The problem mainly exists because Flash access takes more than one clock cycle at 80 MHz, so the constant 3-instruction loop can take longer than 3 cycles to complete. The additional delay is mitigated by a pre-fetch buffer, so you should get relatively close to 3 cycles per loop, but the performance may not be exactly the same on every loop.

    For a more reliable solution, you might want to try the ROM version "ROM_SysCtlDelay()", which will not have any access-time penalties at the higher system clock frequencies.

    Regards,

    Christian

    Hi Christian,

    I did actually end up working out the 16 000 000 part of this equation.  I realised this mistake last night when I read through the datasheet and suddenly realised that it was a 24bit register.  Which explained why it was ticking a lot quicker than once per second.  Since once or twice per second would be heaps for the interrupt to run I didn't want to bog the processor down too much.

    I also realised ended up replacing the SysCTLDelay with just the number of seconds as I noticed that I was sometimes getting vastly different times for the same delay.  As in Delay for what should have been 30 seconds and sometimes it would be 39 seconds and sometimes 31.  However I will try the Rom Call.  I had previously thought that the rom calls took longer for simple functions from something else that I read.

     

    Thanks for all of your help.

     

    Warwick