LPC55 systick clock divider

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC55 systick clock divider

Jump to solution
778 Views
kbetts
Contributor III

I am configuring the systick of an LPC5526 with the intention of having it fire once per second. The core clock is running at 150MHz so the systick cannot run from this directly. This is because the systick counter has a maximum of 2^24 and (2^24) / 150 MHz ~= 0.112 seconds, which isn't a long enough period.

To reduce the frequency at which the systick counts, I am setting a value in the SYSCON->SYSTICKCLKDIV0 register. A value of 149 causes a clock division of 150, reducing the systick clock to 1MHz. (2^24) / 1 MHz ~= 16.778 seconds, which is easily long enough to allow firing once per second:

U8 systick_init(const U32 u32SystickFrequencyInHertz) // u32SystickFrequencyInHertz = 1
{
   CLOCK_AttachClk(kSYSTICK_DIV0_to_SYSTICK0);

   const U32 u32CoreFrequency = CLOCK_GetCoreSysClkFreq(); // Returns 150000000
   U32 u32Divisor             = u32CoreFrequency / 1000000; // Gives 150

   if (C_U8_MAX < u32Divisor)
   {
      u32Divisor = C_U8_MAX;
   }
   else if (0 < u32Divisor)
   {
      u32Divisor -= 1; // Gives 149
   }

   SYSCON->SYSTICKCLKDIV0 = u32Divisor & 0xFF; // Still gives 149

   const U32 u32SystickClockFrequency = CLOCK_GetSystickClkFreq(0); // Returns 1000000
   const U32 u32DelayTicks            = u32SystickClockFrequency / u32SystickFrequencyInHertz; // Gives 1000000
   const U32 u32SetupResult           = SysTick_Config(u32DelayTicks); // Returns 0, ie completed successfully

   return 0 == u32SetupResult; // Returns 1, ie completed successfully
}

 

Initially this seems to work well, and CLOCK_GetSystickClkFreq returns the correct frequency of 1 MHz. However, using the systick to toggle a GPIO pin and examining that signal on an oscilloscope shows that the systick interrupt runs every 6.667 milliseconds. Decreasing the value set in the register to 74 (so decreasing the divisor to 75) increases the value reported by CLOCK_GetSystickClkFreq to 2 MHz but also increases the period between systick interrupts to 13.333 milliseconds.

This seems to imply that the higher the systick clock frequency, the longer the time between systick interrupts? What's going on here? How do I get the systick interrupt to fire once per second?

Labels (1)
0 Kudos
1 Solution
746 Views
scottm
Senior Contributor II

Are you sure systick is the timer you want to be using? I only ever see it used for fairly fast things like RTOS ticks.

The LPC5526 has a multi-rate timer (MRT) that's designed for generating periodic interrupts. It's the peripheral I use on my LPC55S69 projects when they need a once-per-second interrupt.

The #1 reason I stay away from systick is that it's an ARM feature, and not an NXP peripheral. NXP is really bad about documenting anything on ARM's side of things - they tend to tell you just to read the ARM documentation and don't give any specifics on where to look or exactly how they've chosen to configure the features in their devices.

If the MRT will get the job done, I'd use that. You've also got 5 standard 32-bit CTIMERs available on that part.

Scott

View solution in original post

0 Kudos
3 Replies
747 Views
scottm
Senior Contributor II

Are you sure systick is the timer you want to be using? I only ever see it used for fairly fast things like RTOS ticks.

The LPC5526 has a multi-rate timer (MRT) that's designed for generating periodic interrupts. It's the peripheral I use on my LPC55S69 projects when they need a once-per-second interrupt.

The #1 reason I stay away from systick is that it's an ARM feature, and not an NXP peripheral. NXP is really bad about documenting anything on ARM's side of things - they tend to tell you just to read the ARM documentation and don't give any specifics on where to look or exactly how they've chosen to configure the features in their devices.

If the MRT will get the job done, I'd use that. You've also got 5 standard 32-bit CTIMERs available on that part.

Scott

0 Kudos
735 Views
kbetts
Contributor III

I have now reimplemented using a CTIMER, I was just hoping to avoid it as I've now used all 5. I'll take a look at the multi rate timer too

0 Kudos
718 Views
scottm
Senior Contributor II

Yeah, the MRT is focused on just periodic interrupts and doesn't have the PWM features and external connections of the CTIMER, so if an interrupt is all I need, the MRT is the first place I'll go so I can keep from tying up CTIMERs.

0 Kudos